package incheon.uis.ums.web;

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

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import incheon.ags.ias.comCd.vo.ComCdVO;
import incheon.com.security.annotation.RequirePermission;
import incheon.com.security.util.SecurityUtil;
import incheon.uis.ums.service.UisAccessService;
import incheon.uis.ums.service.UisUserDeptService;
import incheon.uis.ums.util.UisConfigUtils;
import lombok.RequiredArgsConstructor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

/**
 * @ClassName : UisUmsController.java
 * @Description : 지도 플랫폼 컨트롤러 - UIS 패널 구성 관리
 *
 * @author : 이재룡
 * @since : 2025. 09. 15
 * @version : 1.0
 *
 */
@Controller
@RequestMapping("/uis/ums")
@RequiredArgsConstructor
public class UisUmsController {

    private final UisConfigUtils uisConfigUtils;
    private final UisAccessService uisAccessService;
    private final UisUserDeptService uisUserDeptService;
    @Autowired private ObjectMapper objectMapper;

    private String mapprimeUrl = "/MapPrimeServer";

    @Value("${gis.server.prefix:incheon}")
    private String workspace;

    /**
     * UIS 지도 화면
     * 
     * @param model
     * @return JSP 페이지
     * @exception Exception
     */
    @GetMapping("/view.do")
    @RequirePermission(system = "UIS", permissions = "PERM_MENU_ACCESS")
    public String uisMapView(
            @RequestParam(name = "viewType", required = false, defaultValue = "road") String viewType,
            ModelMap model, HttpSession session) throws Exception {

        // road/construction.yml 파일에서 대장관리 정보 파싱
        Map<String, Object> constructionData = uisConfigUtils.parseSearchYmlData("construction");

        // road/facilities.yml 파일에서 시설물관리 정보 파싱
        Map<String, Object> facilityData = uisConfigUtils.parseSearchYmlData("facilities");

        // 접근 가능 레이어 카테고리 리스트
        List<ComCdVO> groupList = uisAccessService.getAccessibleRootGroupList();

        boolean canUisEdit = SecurityUtil.hasPermission("UIS", "PERM_FUNC_EDIT");
        boolean canUisExport = SecurityUtil.hasPermission("UIS", "PERM_DATA_EXPORT");

        // 좌측 패널: 탭(레이어목록, 통합검색, 대장검색, 시설물검색) 구성
        List<PanelConfig> leftPanels = Arrays.asList(
                new PanelConfig("layerList", "/WEB-INF/jsp/uis/ums/panels/layerListPanel_new.jsp", "레이어목록", "left"),
                new PanelConfig("constructionSearch", "/WEB-INF/jsp/uis/ums/panels/constructionSearchPanel.jsp", "대장검색",
                        "left"),
                new PanelConfig("facilitySearch", "/WEB-INF/jsp/uis/ums/panels/facilitySearchPanel.jsp", "시설물검색",
                        "left"));

        // 우측 패널: 상세내역
        List<PanelConfig> rightPanels = Arrays.asList(
                new PanelConfig("detailSearch", "/WEB-INF/jsp/uis/ums/panels/detailSearchPanel.jsp", "상세내역", "left"));

        // 지도 기본 설정 (인천 시청)
        Map<String, Object> mapConfig = new HashMap<>();
        mapConfig.put("center", Map.of("lat", 37.4563, "lng", 126.7052));
        mapConfig.put("zoom", 13);
        mapConfig.put("domainType", "uisMap");

        // JSON 데이터로 변환하여 JavaScript에서 사용할 수 있도록 전달
        String constructionDataJson;
        String facilityDataJson;
        String groupListJson;
        try {
            constructionDataJson = objectMapper.writeValueAsString(constructionData);
        } catch (JsonProcessingException e) {
            constructionDataJson = "{}";
        }
        try {
            facilityDataJson = objectMapper.writeValueAsString(facilityData);
        } catch (JsonProcessingException e) {
            facilityDataJson = "{}";
        }
        // 2025-10-24 seyoung : 사용자 접근 가능한 카테고리 리스트
        try {
            groupListJson = objectMapper.writeValueAsString(groupList);
        } catch (JsonProcessingException e) {
            groupListJson = "{}";
        }

        // 2025-11-06 seyoung : 편집권한 여부
        session.removeAttribute("canUisEdit");
        session.setAttribute("canUisEdit", canUisEdit);
        session.removeAttribute("canUisExport");
        session.setAttribute("canUisExport", canUisExport);
        
        // 2025-11-13 seyoung : 사용자 부서와 연결된 관리기관 코드 (없으면 null)
        session.removeAttribute("accessibleMngtFilter");
        session.setAttribute("accessibleMngtFilter", uisUserDeptService.getAuthorizedMngtFilter());

        model.addAttribute("leftPanels", leftPanels);
        model.addAttribute("rightPanels", rightPanels);
        model.addAttribute("mapConfig", mapConfig);
        model.addAttribute("domainType", "uisMap");
        model.addAttribute("pageTitle", "도시기반시설물 관리");
        model.addAttribute("constructionData", constructionData);
        model.addAttribute("constructionDataJson", constructionDataJson);
        model.addAttribute("facilityData", facilityData);
        model.addAttribute("facilityDataJson", facilityDataJson);
        model.addAttribute("groupList", groupList);
        model.addAttribute("groupListJson", groupListJson);
        model.addAttribute("mapprimeUrl", mapprimeUrl);
        model.addAttribute("workspace", workspace);

        return "uis/ums/view";
    }

    /**
     * 패널 설정 클래스
     */
    public static class PanelConfig {
        private String id;
        private String componentPath;
        private String title;
        private String position;
        private Map<String, Object> data;

        // 기존 호환성을 위한 생성자
        public PanelConfig(String id, String componentPath, String title) {
            this(id, componentPath, title, "left"); // 기본값은 left
        }

        public PanelConfig(String id, String componentPath, String title, String position) {
            this.id = id;
            this.componentPath = componentPath;
            this.title = title;
            this.position = position;
            this.data = new HashMap<>();
        }

        // Getters and Setters
        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getComponentPath() {
            return componentPath;
        }

        public void setComponentPath(String componentPath) {
            this.componentPath = componentPath;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getPosition() {
            return position;
        }

        public void setPosition(String position) {
            this.position = position;
        }

        public Map<String, Object> getData() {
            return data;
        }

        public void setData(Map<String, Object> data) {
            this.data = data;
        }
    }
}