package com.nisum.mytime.controller;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.nisum.mytime.exception.handler.MyTimeException;
import com.nisum.mytime.model.Account;
import com.nisum.mytime.model.AccountInfo;
import com.nisum.mytime.model.Designation;
import com.nisum.mytime.model.Domains;
import com.nisum.mytime.model.EmployeeLocationDetails;
import com.nisum.mytime.model.EmployeeRoles;
import com.nisum.mytime.model.Location;
import com.nisum.mytime.model.MasterData;
import com.nisum.mytime.model.Shift;
import com.nisum.mytime.model.Skill;
import com.nisum.mytime.service.RoleMappingService;
import com.nisum.mytime.service.UserService;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleMappingService roleMappingService;

    @RequestMapping(value = "/employee", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<EmployeeRoles> getEmployeeRole(
            @RequestParam("emailId") String emailId) throws MyTimeException {
        EmployeeRoles employeesRole = userService.getEmployeesRole(emailId);
        if (employeesRole != null) {
            if (employeesRole.getRole() != null
                    && employeesRole.getRole().equalsIgnoreCase("Admin")) {
                employeesRole.setRole("Admin");
            } else {
                String roleName = roleMappingService
                        .getEmployeeRole(employeesRole.getEmployeeId());
                if (roleName != null) {
                    employeesRole.setRole(roleName);
                }
            }
        }
        System.out.println("emailId" + emailId + "result" + employeesRole);
        return new ResponseEntity<>(employeesRole, HttpStatus.OK);
    }

    @RequestMapping(value = "/assignEmployeeRole", method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE,
            consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<EmployeeRoles> assigingEmployeeRole(
            @RequestBody EmployeeRoles employeeRoles, @RequestParam(value="empId") String  loginEmpId) throws MyTimeException {
        EmployeeRoles employeeRole = userService
                .assigingEmployeeRole(employeeRoles,loginEmpId);
        return new ResponseEntity<>(employeeRole, HttpStatus.OK);
    }

    @RequestMapping(value = "/updateEmployeeRole", method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE,
            consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<EmployeeRoles> updateEmployeeRole(
            @RequestBody EmployeeRoles employeeRoles,
            @RequestParam(value="empId") String  loginEmpId) throws MyTimeException {
        EmployeeRoles employeeRole = userService
                .updateEmployeeRole(employeeRoles,loginEmpId);
        return new ResponseEntity<>(employeeRole, HttpStatus.OK);
    }

    @RequestMapping(value = "/deleteEmployee", method = RequestMethod.DELETE,
            produces = MediaType.TEXT_PLAIN_VALUE)
    public ResponseEntity<String> deleteEmployee(
            @RequestParam("empId") String empId) throws MyTimeException {
        userService.deleteEmployee(empId);
        return new ResponseEntity<>("Success", HttpStatus.OK);
    }

    @RequestMapping(value = "/getUserRoles", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<EmployeeRoles>> getUserRoles()
            throws MyTimeException {
        List<EmployeeRoles> employeesRoles = userService.getEmployeeRoles();
        return new ResponseEntity<>(employeesRoles, HttpStatus.OK);
    }

    @RequestMapping(value = "/getEmployeeRoleData", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<EmployeeRoles> getEmployeeRoleData(
            @RequestParam("empId") String empId) throws MyTimeException {
        EmployeeRoles employeesRole = userService.getEmployeesRoleData(empId);
        return new ResponseEntity<>(employeesRole, HttpStatus.OK);
    }

    @RequestMapping(value = "/getEmployeeLocations", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<EmployeeLocationDetails>> getEmployeeLocations(
            @RequestParam("employeeId") String empId) throws MyTimeException {
        List<EmployeeLocationDetails> employeeLocationDetails = userService
                .getEmployeeLocationDetails(empId);
        return new ResponseEntity<>(employeeLocationDetails, HttpStatus.OK);
    }

    @RequestMapping(value = "/getManagers", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<EmployeeRoles>> getManagers()
            throws MyTimeException {
        List<EmployeeRoles> employeesRoles = userService.getEmployeeRoles();
        List<EmployeeRoles> managers = employeesRoles.stream()
                .filter(e -> ("Director".equalsIgnoreCase(e.getRole())
                        || "Delivery Manager".equalsIgnoreCase(e.getRole())
                        || "Manager".equalsIgnoreCase(e.getRole())
                        || "HR Manager".equalsIgnoreCase(e.getRole())
                        || "Lead".equalsIgnoreCase(e.getRole())))
                .sorted(Comparator.comparing(EmployeeRoles::getEmployeeName))
                .collect(Collectors.toList());
        return new ResponseEntity<>(managers, HttpStatus.OK);
    }

    @RequestMapping(value = "/getAllShifts", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<String>> getAllShifts() throws MyTimeException {
        List<String> shifts = userService.getAllShifts().stream()
                .filter(e -> "Y".equalsIgnoreCase(e.getActiveStatus()))
                .map(Shift::getShiftName).sorted().collect(Collectors.toList());
        return new ResponseEntity<>(shifts, HttpStatus.OK);
    }

    @RequestMapping(value = "/getAllDesignations", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<String>> getAllDesignations()
            throws MyTimeException {
        List<String> designations = userService.getAllDesignations().stream()
                .filter(e -> "Y".equalsIgnoreCase(e.getActiveStatus()))
                .map(Designation::getDesignationName).sorted()
                .collect(Collectors.toList());
        return new ResponseEntity<>(designations, HttpStatus.OK);
    }

    @RequestMapping(value = "/getSkills", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<String>> getTechnologies()
            throws MyTimeException {
        List<String> technologies = userService.getTechnologies().stream()
                .filter(e -> "Y".equalsIgnoreCase(e.getActiveStatus()))
                .map(Skill::getSkillName).sorted().collect(Collectors.toList());
        return new ResponseEntity<>(technologies, HttpStatus.OK);

    }

    @RequestMapping(value = "/getLocations", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<String>> getLocations() throws MyTimeException {
        System.out.println(
                " userService.getLocations()" + userService.getLocations());
        List<String> locations = userService.getLocations().stream()
                .filter(e -> (e.isActiveStatus() == true))
                .map(Location::getLocation).sorted()
                .collect(Collectors.toList());
        System.out.println("getLocations################ " + locations);
        return new ResponseEntity<>(locations, HttpStatus.OK);

    }

    @RequestMapping(value = "/updateProfile", method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE,
            consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<EmployeeRoles> updateProfile(
            @RequestBody EmployeeRoles employeeRoles) throws MyTimeException {
        EmployeeRoles employeeRole = userService.updateProfile(employeeRoles);
        return new ResponseEntity<>(employeeRole, HttpStatus.OK);
    }

    @RequestMapping(value = "/getAccounts", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<Account>> getAccounts() throws MyTimeException {
        List<Account> technologies = userService.getAccounts().stream()
                .filter(e -> "Y".equalsIgnoreCase(e.getStatus()))
                //.filter(a -> !("Nisum India".equalsIgnoreCase(a.getAccountName())))
                // .map(Account::getAccountName).sorted()
                .collect(Collectors.toList());
        return new ResponseEntity<>(technologies, HttpStatus.OK);
    }

    @RequestMapping(value = "/getEmployeeRoleDataForSearchCriteria",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<EmployeeRoles> getEmployeeRoleDataForSearchCriteria(
            @RequestParam("searchId") String searchId,
            @RequestParam("searchAttribute") String searchAttribute)
            throws MyTimeException {
        EmployeeRoles employeesRole = userService
                .getEmployeeRoleDataForSearchCriteria(searchId,
                        searchAttribute);
        return new ResponseEntity<>(employeesRole, HttpStatus.OK);
    }

    @RequestMapping(value = "/getEmployeeDetailsForAutocomplete",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<String>> getEmployeeDetailsForAutocomplete()
            throws MyTimeException {
        List<String> details = userService.getEmployeeDetailsForAutocomplete();
        return new ResponseEntity<>(details, HttpStatus.OK);
    }

    @RequestMapping(value = "/getMasterData", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Map<String, List<String>>> getMasterData()
            throws MyTimeException {
        Map<String, List<String>> masterDataMap = new HashMap<>();
        Map<String, List<MasterData>> result = userService.getMasterData()
                .stream().filter(e -> (e.isActiveStatus() == true))
                .collect(Collectors.groupingBy(MasterData::getMasterDataType));
        for (String key : result.keySet()) {
            List<MasterData> valueList = result.get(key);
            List<String> technologies = valueList.stream()
                    .map(MasterData::getMasterDataName).sorted()
                    .collect(Collectors.toList());
            masterDataMap.put(key, technologies);
        }
        return new ResponseEntity<>(masterDataMap, HttpStatus.OK);

    }

    @RequestMapping(value = "/getEmployeeByStatus", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<EmployeeRoles>> getEmployeeByStatus(
            @RequestParam("status") String status) {

        List<EmployeeRoles> employeesRoles = userService
                .getEmployeesByStatus(status);
        return new ResponseEntity<>(employeesRoles, HttpStatus.OK);
    }

    @RequestMapping(value = "/getDeliveryLeads", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<HashMap<String, String>>> getDeliveryLeads(
            @RequestParam("domainId") String domainId) throws MyTimeException {
        List<HashMap<String, String>> managers = userService
                .getDeliveryLeads(domainId);
        return new ResponseEntity<>(managers, HttpStatus.OK);
    }

    @RequestMapping(value = "/getAccountsInfo", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<AccountInfo>> getAccountsInfo()
            throws MyTimeException {
        List<AccountInfo> technologies = userService.getAccountsInfo().stream()
                .filter(e -> "Active".equalsIgnoreCase(e.getStatus()))
                .collect(Collectors.toList());
        return new ResponseEntity<>(technologies, HttpStatus.OK);
    }

    @RequestMapping(value = "/getDomains", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<Domains>> getDomains(
            @RequestParam("accountId") String accountId)
            throws MyTimeException {
        List<Domains> domains = userService.getDomains(accountId).stream()
                .filter(e -> "Active".equalsIgnoreCase(e.getStatus()))
                .collect(Collectors.toList());
        return new ResponseEntity<>(domains, HttpStatus.OK);
    }

}