package incheon.ags.cms.admin.web;

import incheon.ags.cms.admin.service.CleaningAdminService;
import incheon.ags.cms.admin.vo.RouteVO;
import incheon.ags.cms.admin.vo.VehicleVO;
import incheon.com.cmm.ResponseCode;
import incheon.com.cmm.api.DefaultApiResponse;
import incheon.com.security.vo.LoginVO;
import lombok.RequiredArgsConstructor;
import org.egovframe.rte.psl.dataaccess.util.EgovMap;
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/v1/cms/admin")
@RequiredArgsConstructor
public class CleaningAdminApiController {

    private final CleaningAdminService cleaningAdminService;
    private static final Logger LOGGER = LoggerFactory.getLogger(CleaningAdminApiController.class);

    /**
     * 청소차량 + 노선 목록 조회
     *
     * @param vhclId 차량아이디
     * @return 차량 + 노선 정보
     * @throws Exception
     */
    @GetMapping("/selectVehicleWithRouteList")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<Map<String, Object>>> selectVehicleWithRouteList(@RequestParam int vhclId) throws Exception {

        Map<String, Object> response = new HashMap<>();

        // 청소차량 + 노선 목록 조회
        VehicleVO vehicleVo = cleaningAdminService.selectVehicleWithRouteList(vhclId);

        response.put("success", true);
        response.put("message", "청소차량 및 노선 목록 조회가 완료되었습니다.");
        response.put("count", 1);
        response.put("result", vehicleVo);
        LOGGER.info(response.get("message").toString());
        return ResponseEntity.ok(DefaultApiResponse.success(response));
    }

    /**
     * 청소차량 목록 조회
     *
     * @param vehicleVO 차량 정보
     * @return 차량 목록
     * @throws Exception
     */
    @PostMapping("/selectVehicleList")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<Map<String, Object>>> selectVehicleList(@RequestBody VehicleVO vehicleVO) throws Exception {

        Map<String, Object> response = new HashMap<>();

        PaginationInfo paginationInfo = new PaginationInfo();
        paginationInfo.setCurrentPageNo(vehicleVO.getPageIndex());
        paginationInfo.setRecordCountPerPage(vehicleVO.getRecordCountPerPage());
        paginationInfo.setPageSize(vehicleVO.getPageSize());

        vehicleVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
        vehicleVO.setLastIndex(paginationInfo.getLastRecordIndex());

        // 청소차량 목록 건수
        int totalCount = cleaningAdminService.selectVehicleTotalCount(vehicleVO);
        paginationInfo.setTotalRecordCount(totalCount);

        // 청소차량 목록 조회
        List<EgovMap> vehicleList = cleaningAdminService.selectVehicleList(vehicleVO);

        response.put("success", true);
        response.put("message", "청소차량 목록 조회가 완료되었습니다.");
        response.put("totalCount", totalCount);
        response.put("paginationInfo", paginationInfo);
        response.put("results", vehicleList);
        LOGGER.info(response.get("message").toString());
        return ResponseEntity.ok(DefaultApiResponse.success(response));
    }

    /**
     * 청소차량 노선 목록 조회
     *
     * @param routeVO 노선 정보
     * @return 노선 목록
     * @throws Exception
     */
    @PostMapping("/selectRouteList")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<Map<String, Object>>> selectRouteList(@RequestBody RouteVO routeVO) throws Exception {

        Map<String, Object> response = new HashMap<>();

        PaginationInfo paginationInfo = new PaginationInfo();
        paginationInfo.setCurrentPageNo(routeVO.getPageIndex());
        paginationInfo.setRecordCountPerPage(routeVO.getRecordCountPerPage());
        paginationInfo.setPageSize(routeVO.getPageSize());

        routeVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
        routeVO.setLastIndex(paginationInfo.getLastRecordIndex());

        // 노선 목록 건수
        int totalCount = cleaningAdminService.selectRouteTotalCount(routeVO);
        paginationInfo.setTotalRecordCount(totalCount);

        // 노선 목록 조회
        List<EgovMap> vehicleList = cleaningAdminService.selectRouteList(routeVO);

        response.put("success", true);
        response.put("message", "청소차량 노선 목록 조회가 완료되었습니다.");
        response.put("totalCount", totalCount);
        response.put("paginationInfo", paginationInfo);
        response.put("results", vehicleList);
        LOGGER.info(response.get("message").toString());
        return ResponseEntity.ok(DefaultApiResponse.success(response));
    }

    /**
     * 청소차량 관제규칙 조회
     * @return
     * @throws Exception
     */
    @GetMapping("/selectControlRuleList")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<Map<String, Object>>> selectControlRuleList() throws Exception {

        Map<String, Object> response = new HashMap<>();

        // 청소차량 관제규칙 조회
        List<EgovMap> controlRuleList = cleaningAdminService.selectControlRuleList();

        response.put("success", true);
        response.put("message", "청소차량 관제규칙 조회가 완료되었습니다.");
        response.put("count", controlRuleList.size());
        response.put("results", controlRuleList);
        LOGGER.info(response.get("message").toString());
        return ResponseEntity.ok(DefaultApiResponse.success(response));
    }

    /**
     * 청소차량 공통코드 조회
     * @return
     * @throws Exception
     */
    @GetMapping("/selectCommonCodes")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<Map<String, Object>>> selectCommonCodes() throws Exception {

        Map<String, Object> response = new HashMap<>();

        // 청소차량 공통코드 조회
        EgovMap commonCodeMap = new EgovMap();
        commonCodeMap.put("cleaningType", cleaningAdminService.selectCmsCmmnListByGroupCd("CLEANING_TYPE"));
        commonCodeMap.put("violationType", cleaningAdminService.selectCmsCmmnListByGroupCd("VIOLATION_TYPE"));

        response.put("success", true);
        response.put("message", "청소차량 공통코드 조회가 완료되었습니다.");
        response.put("count", commonCodeMap.size());
        response.put("results", commonCodeMap);
        LOGGER.info(response.get("message").toString());
        return ResponseEntity.ok(DefaultApiResponse.success(response));
    }

    /**
     * 청소차량 등록
     * @param vehicleVO
     * @return
     * @throws Exception
     */
    @PostMapping("/insertVehicle")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<Map<String, Object>>> insertVehicle(
            @RequestBody VehicleVO vehicleVO, Authentication authentication) throws Exception {

        Map<String, Object> response = new HashMap<>();

        try {
            LoginVO loginVO = (LoginVO) authentication.getPrincipal();
            String loginUserId = loginVO.getUserId();
            vehicleVO.setFrstRegId(loginUserId);
            vehicleVO.setLastMdfcnId(loginUserId);

            // 청소차량 등록
            int insertCount = cleaningAdminService.insertVehicle(vehicleVO);

            response.put("success", true);
            response.put("message", "청소차량 등록이 완료되었습니다.");
            response.put("count", insertCount);
            LOGGER.info(response.get("message").toString());
        } catch (IllegalArgumentException e) {
            LOGGER.error(e.getMessage());
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(DefaultApiResponse.error(ResponseCode.INPUT_ERROR.getCode(), e.getMessage(), e.toString()));
        } catch (IllegalStateException e) {
            LOGGER.error(e.getMessage());

            HttpStatus statusCode = e.getMessage().contains("이미 등록된")
                    ? HttpStatus.CONFLICT
                    : HttpStatus.INTERNAL_SERVER_ERROR;

            return ResponseEntity.status(statusCode).body(DefaultApiResponse.error(ResponseCode.INPUT_ERROR.getCode(), e.getMessage(), e.toString()));
        }

        return ResponseEntity.ok(DefaultApiResponse.success(response));
    }

    /**
     * 청소차량 수정
     * @param vehicleVO
     * @return
     * @throws Exception
     */
    @PutMapping("/updateVehicle")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<Map<String, Object>>> updateVehicle(
            @RequestBody VehicleVO vehicleVO, Authentication authentication) throws Exception {

        Map<String, Object> response = new HashMap<>();

        try {
            LoginVO loginVO = (LoginVO) authentication.getPrincipal();
            String loginUserId = loginVO.getUserId();
            vehicleVO.setFrstRegId(loginUserId);
            vehicleVO.setLastMdfcnId(loginUserId);

            // 청소차량 수정
            int updateCount = cleaningAdminService.updateVehicle(vehicleVO);

            response.put("success", true);
            response.put("message", "청소차량 정보 수정이 완료되었습니다.");
            response.put("count", updateCount);
            LOGGER.info(response.get("message").toString());
        } catch (IllegalArgumentException e) {
            LOGGER.error(e.getMessage());
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(DefaultApiResponse.error(ResponseCode.INPUT_ERROR.getCode(), e.getMessage(), e.toString()));
        } catch (IllegalStateException e) {
            LOGGER.error(e.getMessage());

            HttpStatus statusCode = e.getMessage().contains("이미 등록된")
                    ? HttpStatus.CONFLICT
                    : HttpStatus.INTERNAL_SERVER_ERROR;

            return ResponseEntity.status(statusCode).body(DefaultApiResponse.error(ResponseCode.INPUT_ERROR.getCode(), e.getMessage(), e.toString()));
        }

        return ResponseEntity.ok(DefaultApiResponse.success(response));
    }

    /**
     * 청소차량 삭제
     * @param vhclIds
     * @return
     * @throws Exception
     */
    @DeleteMapping("/deleteVehicle")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<Map<String, Object>>> deleteVehicle(
            @RequestParam List<Integer> vhclIds, Authentication authentication) throws Exception {

        Map<String, Object> response = new HashMap<>();

        LoginVO loginVO = (LoginVO) authentication.getPrincipal();
        String loginUserId = loginVO.getUserId();

        Map<String, Object> paramMap = new EgovMap();
        paramMap.put("vhclIdList", vhclIds);
        paramMap.put("lastMdfcnId", loginUserId);

        // 청소차량 soft delete
        int deleteCount = cleaningAdminService.disableVehicles(paramMap);

        response.put("success", true);
        response.put("message", "청소차량 삭제가 완료되었습니다.");
        response.put("count", deleteCount);
        LOGGER.info(response.get("message").toString());
        return ResponseEntity.ok(DefaultApiResponse.success(response));
    }

    /**
     * 청소차량 노선 등록
     * @param routeVO
     * @return
     * @throws Exception
     */
    @PostMapping("/insertRoute")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<Map<String, Object>>> insertRoute(
            @RequestBody RouteVO routeVO, Authentication authentication) throws Exception {

        Map<String, Object> response = new HashMap<>();

        try {
            LoginVO loginVO = (LoginVO) authentication.getPrincipal();
            String loginUserId = loginVO.getUserId();
            routeVO.setFrstRegId(loginUserId);
            routeVO.setLastMdfcnId(loginUserId);

            // 노선 등록
            int insertCount = cleaningAdminService.insertRoute(routeVO);

            response.put("success", true);
            response.put("message", "청소차량 노선 등록이 완료되었습니다.");
            response.put("count", insertCount);
            LOGGER.info(response.get("message").toString());
        } catch (IllegalArgumentException e) {
            LOGGER.error(e.getMessage());
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(DefaultApiResponse.error(ResponseCode.INPUT_ERROR.getCode(), e.getMessage(), e.toString()));
        } catch (IllegalStateException e) {
            LOGGER.error(e.getMessage());
            return ResponseEntity.status(HttpStatus.CONFLICT).body(DefaultApiResponse.error(ResponseCode.INPUT_ERROR.getCode(), e.getMessage(), e.toString()));
        }

        return ResponseEntity.ok(DefaultApiResponse.success(response));
    }

    /**
     * 청소차량 노선 수정
     * @param routeVO
     * @return
     * @throws Exception
     */
    @PutMapping("/updateRoute")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<Map<String, Object>>> updateRoute(
            @RequestBody RouteVO routeVO, Authentication authentication) throws Exception {

        Map<String, Object> response = new HashMap<>();

        try {
            LoginVO loginVO = (LoginVO) authentication.getPrincipal();
            String loginUserId = loginVO.getUserId();
            routeVO.setLastMdfcnId(loginUserId);

            // 청소차량 수정
            int updateCount = cleaningAdminService.updateRoute(routeVO);

            response.put("success", true);
            response.put("message", "청소차량 노선 정보 수정이 완료되었습니다.");
            response.put("count", updateCount);
            LOGGER.info(response.get("message").toString());
        } catch (IllegalArgumentException e) {
            LOGGER.error(e.getMessage());
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(DefaultApiResponse.error(ResponseCode.INPUT_ERROR.getCode(), e.getMessage(), e.toString()));
        } catch (IllegalStateException e) {
            LOGGER.error(e.getMessage());
            return ResponseEntity.status(HttpStatus.CONFLICT).body(DefaultApiResponse.error(ResponseCode.INPUT_ERROR.getCode(), e.getMessage(), e.toString()));
        }

        return ResponseEntity.ok(DefaultApiResponse.success(response));
    }

    /**
     * 청소차량 노선 삭제 전 차량 매핑정보 확인
     * @param rteIds
     * @return
     * @throws Exception
     */
    @GetMapping("/checkRouteMapping")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<Map<String, Object>>> checkRouteMapping(
            @RequestParam List<Integer> rteIds) throws Exception {

        Map<String, Object> response = new HashMap<>();

        // 차량에 매핑되어있는 노선 리스트
        List<EgovMap> mappingList = cleaningAdminService.checkRouteMapping(rteIds);

        response.put("success", true);
        response.put("message", "차량 노선 매핑정보 조회가 완료되었습니다.");
        response.put("results", mappingList);
        LOGGER.info(response.get("message").toString());
        return ResponseEntity.ok(DefaultApiResponse.success(response));
    }

    /**
     * 청소차량 노선 삭제
     * @param rteIds
     * @return
     * @throws Exception
     */
    @DeleteMapping("/deleteRoute")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<Map<String, Object>>> deleteRoute(
            @RequestParam List<Integer> rteIds, Authentication authentication) throws Exception {

        Map<String, Object> response = new HashMap<>();

        LoginVO loginVO = (LoginVO) authentication.getPrincipal();
        String loginUserId = loginVO.getUserId();

        Map<String, Object> paramMap = new EgovMap();
        paramMap.put("rteIdList", rteIds);
        paramMap.put("lastMdfcnId", loginUserId);

        // 노선 soft delete
        int deleteCount = cleaningAdminService.disableRoutes(paramMap);

        response.put("success", true);
        response.put("message", "청소차량 노선 삭제가 완료되었습니다.");
        response.put("count", deleteCount);
        LOGGER.info(response.get("message").toString());
        return ResponseEntity.ok(DefaultApiResponse.success(response));
    }

    /**
     * 관제규칙 신규 등록
     * @param rules
     * @return
     * @throws Exception
     */
    @PostMapping("/insertControlRules")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<Map<String, Object>>> insertControlRules(
            @RequestBody List<Map<String, Object>> rules, Authentication authentication) throws Exception {

        Map<String, Object> response = new HashMap<>();

        try {
            LoginVO loginVO = (LoginVO) authentication.getPrincipal();
            String loginUserId = loginVO.getUserId();
            rules.forEach(r -> {
                r.put("frstRegId", loginUserId);
                r.put("lastMdfcnId", loginUserId);
            });

            // 관제규칙 등록
            int insertCount = cleaningAdminService.insertControlRules(rules);

            response.put("success", true);
            response.put("message", "관제규칙 등록이 완료되었습니다.");
            response.put("count", insertCount);
            LOGGER.info(response.get("message").toString());
        } catch (IllegalArgumentException e) {
            LOGGER.error(e.getMessage());
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(DefaultApiResponse.error(ResponseCode.INPUT_ERROR.getCode(), e.getMessage(), e.toString()));
        }

        return ResponseEntity.ok(DefaultApiResponse.success(response));
    }

}
