package incheon.sgp.drm.web;

import incheon.ags.mrb.analysis.web.SpatialAnalysisController;
import incheon.cmm.g2f.layer.vo.TaskLayerSearchRequestDTO;
import incheon.cmm.g2f.layer.vo.TaskLayerVO;
import incheon.com.cmm.context.RequestContext;
import incheon.sgp.drm.service.sgpDrmService;
import incheon.sgp.drm.service.impl.sgpDrmServiceImpl;
import incheon.ags.drm.vo.DrmContentVO;
import incheon.ags.drm.vo.DrmPoiVO;
import lombok.RequiredArgsConstructor;
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.*;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.io.FileNotFoundException;
import java.nio.file.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/sgp/drm")
@RequiredArgsConstructor
public class sgpDrmController {

    private static final Logger logger = LoggerFactory.getLogger(SpatialAnalysisController.class);
    private final sgpDrmService sgpDrmService;
    @Value("${gis.server.url}")
    private String BASE_URL;

    @GetMapping("/main.do")
    public String viewMap(ModelMap model) throws Exception {
        // RST/BAS/POR와 동일하게: 로그인 여부를 JSP로 내려 프론트에서 Inner/Outer 분기 가능하도록 함
        model.addAttribute("isManager", RequestContext.getCurrentUserId() != null);
        return "sgp/drm/drmView";
    }

    @GetMapping("/getLayerList.do")
    public ResponseEntity<Map<String, Object>> getLayerList(TaskLayerSearchRequestDTO searchVO) {
        Map<String, Object> response = new HashMap<>();

        try {
            if (searchVO == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
            }

            searchVO.setLyrGroupCd("pba");
            searchVO.setLyrSclsfCd(null);
            List<TaskLayerVO> taskLayerList = sgpDrmService.getLayerList(searchVO);
            response.put("taskLayerList", taskLayerList);

            searchVO.setLyrGroupCd("lnd");
            List<TaskLayerVO> lndLayerList = sgpDrmService.getLayerList(searchVO);
            response.put("lndLayerList", lndLayerList);

            searchVO.setLyrGroupCd("drm");
            searchVO.setLyrSclsfCd("poi");
            List<TaskLayerVO> drmPoiList = sgpDrmService.getLayerList(searchVO);
            response.put("poiLayerList", drmPoiList);

            searchVO.setLyrSclsfCd("cnt");
            List<TaskLayerVO> drmCntList = sgpDrmService.getLayerList(searchVO);
            response.put("contentLayerList", drmCntList);

            return ResponseEntity.ok(response);

        } catch (DataIntegrityViolationException e) {
            logger.warn("시스템 오류가 발생했습니다: {}", "데이터 제약조건 위반", e);
            return ResponseEntity.status(HttpStatus.CONFLICT).body(response);

        } catch (NullPointerException e) {
            // 객체 참조 오류 (데이터 매핑 실패 등)
            logger.error("시스템 오류가 발생했습니다: {}", "데이터 처리 중 널 참조 발생", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();

        } catch (DataAccessException e) {
            // DB 접속 불능, SQL 문법 오류 등 데이터 계층 예외
            logger.error("시스템 오류가 발생했습니다: {}", "DB 오류 발생", e);
            return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build();

        } catch (Exception e) {
            logger.error("시스템 오류가 발생했습니다: {}", "레이어 목록 조회", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
    @GetMapping("/getAddress.do")
    public ResponseEntity<Map<String, Object>> getAddressByPoint (@RequestParam String pnu) {
        Map<String, Object> response = new HashMap<>();
        try {
            List<Map<String, Object>> result = sgpDrmService.getAddressByPoint(pnu);
            response.put("result", result);
            response.put("status", "success");
            return ResponseEntity.ok(response);

        } catch (DataIntegrityViolationException e) {
            logger.warn("시스템 오류가 발생했습니다: {}", "데이터 제약조건 위반", e);
            response.put("message", "위치 정보 조회 중 오류가 발생했습니다.");
            return ResponseEntity.status(HttpStatus.CONFLICT).body(response);

        } catch (NullPointerException e) {
            // 객체 참조 오류 (데이터 매핑 실패 등)
            logger.error("시스템 오류가 발생했습니다: {}", "데이터 처리 중 널 참조 발생", e);
            response.put("message", "위치 정보 조회 중 오류가 발생했습니다.");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();

        } catch (DataAccessException e) {
            // DB 접속 불능, SQL 문법 오류 등 데이터 계층 예외
            logger.error("시스템 오류가 발생했습니다: {}", "DB 오류 발생", e);
            response.put("message", "위치 정보 조회 중 오류가 발생했습니다.");
            return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build();

        } catch (Exception e) {
            logger.error("시스템 오류가 발생했습니다: {}", "위치 정보 조회", e);
            response.put("status", "error");
            response.put("message", "위치 정보 조회 중 오류가 발생했습니다.");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }

    /* DRM_POI */
    @GetMapping("/poiPanelPop.do")
    public String showPOIPanelPop(@RequestParam(required = false) Long poiId, ModelMap model) {
        try {
            DrmPoiVO drmPoiVO = new DrmPoiVO();
            drmPoiVO.setPoiId(poiId);
            DrmPoiVO resultVO = sgpDrmService.searchPoiDetail(drmPoiVO);
            model.addAttribute("resultVO", resultVO);

        } catch (DataIntegrityViolationException e) {
            logger.warn("시스템 오류가 발생했습니다: {}", "데이터 제약조건 위반", e);

        } catch (NullPointerException e) {
            // 객체 참조 오류 (데이터 매핑 실패 등)
            logger.error("시스템 오류가 발생했습니다: {}", "데이터 처리 중 널 참조 발생", e);

        } catch (DataAccessException e) {
            // DB 접속 불능, SQL 문법 오류 등 데이터 계층 예외
            logger.error("시스템 오류가 발생했습니다: {}", "DB 오류 발생", e);

        } catch (Exception e) {
            logger.error("시스템 오류가 발생했습니다: {}", "poi 패널 상세 조회", e);
        }

        return "sgp/drm/include/poiPanelDetail";
    }
    @GetMapping("/poiList.do")
    public ResponseEntity<Map<String, Object>> searchPoiList (
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(required = false) String searchPlcNm,
            @RequestParam(required = false) String searchPoiPbadmsGu,
            @RequestParam(required = false) String sortKey,
            @RequestParam(required = false) String sortDirection
    ) {
        DrmPoiVO drmPoiVO = new DrmPoiVO();
        PaginationInfo paginationInfo = new PaginationInfo();
        Map<String, Object> response = new HashMap<>();

        try {
            drmPoiVO.setPageIndex(page);
            drmPoiVO.setPlcNm(searchPlcNm);
            drmPoiVO.setPbadmsGu(searchPoiPbadmsGu);
            drmPoiVO.setSortKey(sortKey);
            drmPoiVO.setSortDirection(sortDirection);
            drmPoiVO.setPageSize(3);

            paginationInfo.setCurrentPageNo(page);
            paginationInfo.setRecordCountPerPage(drmPoiVO.getRecordCountPerPage());
            paginationInfo.setPageSize(drmPoiVO.getPageSize());

            drmPoiVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
            drmPoiVO.setLastIndex(paginationInfo.getLastRecordIndex());
            drmPoiVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());

            List<DrmPoiVO> resultList = sgpDrmService.selectPOIList(drmPoiVO);
            int totalCount = sgpDrmService.selectPOIListCnt(drmPoiVO);
            paginationInfo.setTotalRecordCount(totalCount);

            response.put("result", resultList);
            response.put("totalCount", totalCount);
            response.put("paginationInfo", paginationInfo);
            return ResponseEntity.ok(response);

        } catch (DataIntegrityViolationException e) {
            logger.warn("시스템 오류가 발생했습니다: {}", "poi 목록 조회", e);
            return ResponseEntity.status(HttpStatus.CONFLICT).body(response);

        } catch (NullPointerException e) {
            // 객체 참조 오류 (데이터 매핑 실패 등)
            logger.error("시스템 오류가 발생했습니다: {}", "poi 목록 조회", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();

        } catch (DataAccessException e) {
            // DB 접속 불능, SQL 문법 오류 등 데이터 계층 예외
            logger.error("시스템 오류가 발생했습니다: {}", "poi 목록 조회", e);
            return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build();

        } catch (Exception e) {
            logger.error("시스템 오류가 발생했습니다: {}", "poi 목록 조회", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
    @GetMapping("/poiDetail.do")
    public ResponseEntity<Map<String, Object>> searchPoiDetail (@RequestParam(required = false) Long poiId) {
        DrmPoiVO drmPoiVO = new DrmPoiVO();
        Map<String, Object> response = new HashMap<>();
        try {
            drmPoiVO.setPoiId(poiId);
            DrmPoiVO resultVO = sgpDrmService.searchPoiDetail(drmPoiVO);
            response.put("result", resultVO);
            return ResponseEntity.ok(response);

        } catch (DataIntegrityViolationException e) {
            logger.warn("시스템 오류가 발생했습니다: {}", "poi 상세 조회", e);
            return ResponseEntity.status(HttpStatus.CONFLICT).body(response);

        } catch (NullPointerException e) {
            logger.error("시스템 오류가 발생했습니다: {}", "poi 상세 조회", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();

        } catch (DataAccessException e) {
            logger.error("시스템 오류가 발생했습니다: {}", "poi 상세 조회", e);
            return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build();

        } catch (Exception e) {
            logger.error("시스템 오류가 발생했습니다: {}", "poi 상세 조회", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }

    /* CONTENT */
    @GetMapping("/contentPanelPop.do")
    public String showcontentPanelPop(@RequestParam(required = false) Long contsId, ModelMap model) {
        try {
            DrmContentVO resultVO = sgpDrmService.searchContentDetail(contsId);

            // 파일 시스템 경로 확인
            Path filePath = ((sgpDrmServiceImpl) sgpDrmService).getSgpFilePath(resultVO.getContsClsf(), resultVO.getContsFileNm());
            if (!Files.exists(filePath)) {
                throw new FileNotFoundException("기존 파일이 존재하지 않습니다: " + filePath);
            }

            // 파일 정보
            long fileSize = Files.size(filePath);
            resultVO.setFileSize(fileSize);
            String fileUrl = "/sgp/drm/content/" + contsId;
            resultVO.setFileUrl(fileUrl);
            model.addAttribute("resultVO", resultVO);
        } catch (FileNotFoundException e) {
            // 파일이 없으면 404 Not Found
            logger.error("시스템 오류가 발생했습니다: {}", "콘텐츠 패널 파일 조회", e);

        } catch (DataIntegrityViolationException e) {
            logger.warn("시스템 오류가 발생했습니다: {}", "콘텐츠 패널 상세 조회", e);

        } catch (NullPointerException | DataAccessException e) {
            logger.error("시스템 오류가 발생했습니다: {}", "콘텐츠 패널 상세 조회", e);

        } catch (Exception e) {
            logger.error("시스템 오류가 발생했습니다: {}", "콘텐츠 패널 상세 조회", e);
        }

        return "sgp/drm/include/contentPanelDetail";
    }
    @GetMapping("/contentList.do")
    public ResponseEntity<Map<String, Object>> searchContentList (
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(required = false) String searchContsNm,
            @RequestParam(required = false) String searchContsClsf,
            @RequestParam(required = false) String panelContsShtDtStart,
            @RequestParam(required = false) String panelContsShtDtEnd,
            @RequestParam(required = false) String sortKey,
            @RequestParam(required = false) String sortDirection
    ) {
        DrmContentVO drmContentVO = new DrmContentVO();
        PaginationInfo paginationInfo = new PaginationInfo();
        Map<String, Object> response = new HashMap<>();

        try {
            drmContentVO.setPageIndex(page);
            drmContentVO.setContsNm(searchContsNm);
            drmContentVO.setContsClsf(searchContsClsf);
            drmContentVO.setContsShtDtStart(panelContsShtDtStart);
            drmContentVO.setContsShtDtEnd(panelContsShtDtEnd);
            drmContentVO.setSortKey(sortKey);
            drmContentVO.setSortDirection(sortDirection);
            drmContentVO.setPageSize(3);

            /* 정보공개 등급별 데이터 권한 > 대민시스템이므로 공개 데이터만 조회 */
            drmContentVO.setPermission_data_unclassified(false);
            drmContentVO.setPermission_data_public(true);
            drmContentVO.setPermission_data_limit(false);
            drmContentVO.setPermission_data_private(false);

            paginationInfo.setCurrentPageNo(page);
            paginationInfo.setRecordCountPerPage(drmContentVO.getRecordCountPerPage());
            paginationInfo.setPageSize(drmContentVO.getPageSize());

            drmContentVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
            drmContentVO.setLastIndex(paginationInfo.getLastRecordIndex());
            drmContentVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());

            List<DrmContentVO> resultList = sgpDrmService.selectContentList(drmContentVO);
            int totalCount = sgpDrmService.selectContentListCnt(drmContentVO);
            paginationInfo.setTotalRecordCount(totalCount);

            response.put("result", resultList);
            response.put("totalCount", totalCount);
            response.put("paginationInfo", paginationInfo);
            return ResponseEntity.ok(response);

        } catch (DataIntegrityViolationException e) {
            logger.warn("시스템 오류가 발생했습니다: {}", "콘텐츠 목록 조회", e);
            return ResponseEntity.status(HttpStatus.CONFLICT).body(response);

        } catch (NullPointerException e) {
            logger.error("시스템 오류가 발생했습니다: {}", "콘텐츠 목록 조회", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();

        } catch (DataAccessException e) {
            logger.error("시스템 오류가 발생했습니다: {}", "콘텐츠 목록 조회", e);
            return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build();

        } catch (Exception e) {
            logger.error("시스템 오류가 발생했습니다: {}", "콘텐츠 목록 조회", e);
            response.put("message", "콘텐츠 목록 조회 중 오류 발생");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
    @GetMapping("/contentDetail.do")
    public ResponseEntity<Map<String, Object>> searchContentDetail (@RequestParam(required = false) Long contsId) {
        Map<String, Object> response = new HashMap<>();
        try {
            DrmContentVO resultVO = sgpDrmService.searchContentDetail(contsId);

            // 파일 시스템 경로 확인
            Path filePath = ((sgpDrmServiceImpl) sgpDrmService).getSgpFilePath(resultVO.getContsClsf(), resultVO.getContsFileNm());
            if (!Files.exists(filePath)) {
                throw new FileNotFoundException("기존 파일이 존재하지 않습니다: " + filePath);
            }

            // 파일 정보
            long fileSize = Files.size(filePath);
            resultVO.setFileSize(fileSize);
            String fileUrl = "/sgp/drm/content/" + contsId;
            resultVO.setFileUrl(fileUrl);
            response.put("result", resultVO);
            return ResponseEntity.ok(response);

        } catch (FileNotFoundException e) {
            // 파일이 없으면 404 Not Found
            logger.error("시스템 오류가 발생했습니다: {}", "콘텐츠 파일 조회", e);
            return ResponseEntity.notFound().build();

        } catch (DataIntegrityViolationException e) {
            logger.warn("시스템 오류가 발생했습니다: {}", "콘텐츠 상세 조회", e);
            return ResponseEntity.status(HttpStatus.CONFLICT).body(response);

        } catch (NullPointerException e) {
            logger.error("시스템 오류가 발생했습니다: {}", "콘텐츠 상세 조회", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();

        } catch (DataAccessException e) {
            logger.error("시스템 오류가 발생했습니다: {}", "콘텐츠 상세 조회", e);
            return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build();

        } catch (Exception e) {
            logger.error("시스템 오류가 발생했습니다: {}", "콘텐츠 상세 조회", e);
            response.put("status", "error");
            response.put("message", "콘텐츠 상세 조회 중 오류 발생");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
}