package com.nisum.myteam.controller;

import com.nisum.myteam.exception.handler.MyTeamException;
import com.nisum.myteam.exception.handler.ResponseDetails;
import com.nisum.myteam.model.dao.Employee;
import com.nisum.myteam.model.dao.EmployeeVisa;
import com.nisum.myteam.model.dao.Resource;
import com.nisum.myteam.model.vo.EmployeeDashboardVO;
import com.nisum.myteam.repository.EmployeeVisaRepo;
import com.nisum.myteam.service.IEmployeeService;
import com.nisum.myteam.service.IProjectService;
import com.nisum.myteam.service.IResourceService;
import com.nisum.myteam.utils.MyTeamUtils;
import org.apache.commons.lang3.StringUtils;
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.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping
public class ResourceController {

    @Autowired
    private IEmployeeService employeeService;

    @Autowired
    private IProjectService projectService;

    @Autowired
    private EmployeeVisaRepo employeeVisaRepo;

    @Autowired
    private IResourceService resourceService;


    @RequestMapping(value = "/resources", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> createResource(@RequestBody Resource resourceReq,
                                               @RequestParam(value = "loginEmpId", required = true) String loginEmpId, HttpServletRequest request) throws MyTeamException {
        if (StringUtils.isNotBlank(loginEmpId)) {
            resourceReq.setActive(true);
            resourceReq.setAuditFields(loginEmpId, MyTeamUtils.CREATE);
            Resource resourcePersisted = resourceService.addResource(resourceReq, loginEmpId);

            ResponseDetails createResponseDetails = new ResponseDetails(new Date(), 601, "Resource has been created",
                    "Resource description", null, request.getContextPath(), "details", resourcePersisted);
            return new ResponseEntity<ResponseDetails>(createResponseDetails, HttpStatus.OK);
        }

        ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Please provide the valid Employee Id",
                "Employee Id is not valid", null, request.getRequestURI(), "Resource details", resourceReq);
        return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);

    }

    @RequestMapping(value = "/resources", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> updateResource(@RequestBody Resource resourceReq,
                                            @RequestParam(value = "loginEmpId") String loginEmpId, HttpServletRequest request) throws MyTeamException {

        if (StringUtils.isNotBlank(loginEmpId)) {
            resourceReq.setAuditFields(loginEmpId, MyTeamUtils.UPDATE);
            String responseMessage = resourceService.updateResource(resourceReq, loginEmpId);
            ResponseDetails createResponseDetails = new ResponseDetails(new Date(), 601, responseMessage,
                    "Resource description", null, request.getContextPath(), "Resource details", resourceReq);
            return new ResponseEntity<ResponseDetails>(createResponseDetails, HttpStatus.OK);
        }
        ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Please provide the valid Employee Id",
                "Employee Id is not valid", null, request.getRequestURI(), "Resource details", resourceReq);
        return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);
    }

    @RequestMapping(value = "/resources", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> deleteResource(@RequestBody Resource resourceReq,
                                            @RequestParam(value = "loginEmpId", required = true) String loginEmpId, HttpServletRequest request) throws MyTeamException {
        if (StringUtils.isNotBlank(loginEmpId)) {
            Resource resourceDeleted = resourceService.deleteResource(resourceReq.getEmployeeId(), resourceReq.getProjectId(), resourceReq.getId(), loginEmpId);

            ResponseDetails createResponseDetails = new ResponseDetails(new Date(), 601, "Resource has been deleted",
                    "Resource description", null, request.getContextPath(), "Resource details", resourceDeleted);
            return new ResponseEntity<ResponseDetails>(createResponseDetails, HttpStatus.OK);
        }

        ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Please provide the valid Employee Id",
                "Employee Id is not valid", null, request.getRequestURI(), "Resource details", resourceReq);
        return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);
    }

    @RequestMapping(value = "/resources/employeeId/{employeeId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> getResourcesSortByStartDate(@PathVariable(value = "employeeId", required = true) String employeeId, HttpServletRequest request)
            throws MyTeamException {

        if (StringUtils.isNotBlank(employeeId)) {
            List<Resource> resourcesList = resourceService.getResourcesSortByStartDate(employeeId);
            ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Resources have been retrieved successfully",
                    "List of Resources for an employee", resourcesList, request.getRequestURI(), "Resource List details", null);
            return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);
        }

        ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Please provide the valid Employee Id",
                "Employee Id is not valid", null, request.getRequestURI(), "Resource details", null);
        return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);

    }

    @RequestMapping(value = "/resources/active", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> getActiveResources(@RequestParam(value = "employeeId", required = false) String employeeId, HttpServletRequest request)
            throws MyTeamException {
        if (StringUtils.isNotBlank(employeeId)) {
            List<Resource> employeesRoles = resourceService.getActiveResources(employeeId);

            ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Resources have been retrieved successfully",
                    "List of Resources who are active in the projects", employeesRoles, request.getRequestURI(), "Resource List details", null);
            return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);

        }
        ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Please provide the valid Employee Id",
                "Employee Id is not valid", null, request.getRequestURI(), "Resource details", null);
        return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);
    }


    @RequestMapping(value = "/resources/shifts/{shift}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> getResourcesForShift(@PathVariable(value = "shift", required = true) String shift, HttpServletRequest request)
            throws MyTeamException {

        if (StringUtils.isNotBlank(shift)) {
            List<Resource> resourcesList = resourceService.getResourcesForShift(shift);
            ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Resources have been retrieved successfully",
                    "List of Resources for the provided shift", resourcesList, request.getRequestURI(), "Resource List for shift", null);
            return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);
        }
        ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Please provide the valid Shift value",
                "List of Resources for the provided shift", null, request.getRequestURI(), "Resource details", null);
        return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);

    }

    @RequestMapping(value = "/resources/projects", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> getResourcesAllocatedForAllProjects(HttpServletRequest request) throws MyTeamException {

        List<Resource> resourcesList = resourceService.getResourcesForActiveProjects();
        ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Resources have been retrieved successfully",
                "List of Resources for the  projects", resourcesList, request.getRequestURI(), "Resource details", null);
        return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);

    }

    @RequestMapping(value = "/resources/project/{projectId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> getResourcesForProject(@PathVariable(value = "projectId", required = true) String projectId,
                                                    @RequestParam(value = "status", required = false, defaultValue = MyTeamUtils.ACTIVE) String status,
                                                    HttpServletRequest request)
            throws MyTeamException {

        if (StringUtils.isNotBlank(projectId)) {
            List<Resource> resourcesList = resourceService.getResourcesForProject(projectId, status);
            ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Resources have been retrieved successfully",
                    "List of Resources for a project", resourcesList, request.getRequestURI(), "Resource details", null);
            return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);

        }
        ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Please provide ProjectId",
                "List of Resources for a project", null, request.getRequestURI(), "Resource details", null);
        return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);
    }


    @RequestMapping(value = "/resources/deliverylead/{deliveryLeadId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> getTeamDetails(@PathVariable(value = "deliveryLeadId", required = true) String deliveryLeadId, HttpServletRequest request)
            throws MyTeamException {

        if (StringUtils.isNotBlank(deliveryLeadId)) {
            List<Resource> resourcesList = resourceService.getResourcesUnderDeliveryLead(deliveryLeadId);

            ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Resources have been retrieved successfully",
                    "List of Resources for a project", resourcesList, request.getRequestURI(), "Resource details", null);
        }

        ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Please provide Valid Delivery Lead Id",
                "List of Resources for DeliveryLead", null, request.getRequestURI(), "Resource details", null);
        return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);

    }


    @RequestMapping(value = "resources/unAssignedEmployees", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> getUnAssignedEmployees(HttpServletRequest request) throws MyTeamException {
        List<Employee> employeesList = projectService.getUnAssignedEmployees();

        ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Resources have been retrieved successfully",
                "List of Resources who are not assigned to project", employeesList, request.getRequestURI(), "Resource details", null);
        return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);
    }


    @RequestMapping(value = "/getEmployeesDashBoard", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> getEmployeesDashBoard(HttpServletRequest request) throws MyTeamException {
        List<EmployeeDashboardVO> employeeDashBoardList = projectService.getEmployeesDashBoard();

        ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Resources have been retrieved successfully",
                "List of Resources for dashboard", employeeDashBoardList, request.getRequestURI(), "Resource details", null);
        return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);
    }

    @RequestMapping(value = "/getEmployeesHavingVisa", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> getEmployeesHavingVisa(@RequestParam("visa") String passport,HttpServletRequest request)
            throws MyTeamException {
        List<Employee> employees = new ArrayList<>();

        if (passport != null && !"passport".equalsIgnoreCase(passport)) {

            List<EmployeeVisa> employeeVisas = employeeVisaRepo.findByVisaName(passport);

            List<String> employeeIds = null;
            if (employeeVisas != null) {
                employeeIds = employeeVisas.stream().map(EmployeeVisa::getEmployeeId).collect(Collectors.toList());
            }
            if (employeeIds != null && !employeeIds.isEmpty()) {
                List<Employee> emps = employeeService.getActiveEmployees();
                for (Employee emp : emps) {
                    if (employeeIds.contains(emp.getEmployeeId())) {
                        employees.add(emp);
                    }
                }
            }
        } else {
            if (employeeService.getActiveEmployees() != null) {
                employees = employeeService.getActiveEmployees().stream()
                        .sorted((o1, o2) -> o1.getEmployeeName().compareTo(o2.getEmployeeName()))
                        .collect(Collectors.toList());
            }

        }

        ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Resources have been retrieved successfully",
                "List of Resources who has visa", employees, request.getRequestURI(), "Resource details", null);
        return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);

    }


    @RequestMapping(value = "/addEmployeeToTeamWithCheck", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> addEmployeeToTeamWithCheck(@RequestBody Resource resourceReq,
                                                        @RequestParam(value = "loginEmpId") String loginEmpId, HttpServletRequest request) throws MyTeamException {

        if (StringUtils.isNotBlank(loginEmpId)) {
            HashMap<String, Object> responseMap = projectService.addProjectTeamMateWithCheck(resourceReq, loginEmpId);

            ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, responseMap.get("message").toString(),
                    "List of Resources for dashboard", responseMap.get("resourceObj"), request.getRequestURI(), "Resource details", null);
            return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);
        }
        ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "Please provide Valid Employee Id",
                "Verification of resource in Bench Project", null, request.getRequestURI(), "Resource details", resourceReq);
        return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);

    }

}
