package incheon.ags.pss.project.web;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import de.huxhorn.sulky.ulid.ULID;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;

import incheon.ags.pss.project.vo.UserSearchVO;
import incheon.ags.pss.project.service.ProjectService;
import incheon.ags.pss.project.vo.ProjectSearchVO;
import incheon.ags.pss.project.vo.ProjectVO;
import incheon.com.cmm.api.DefaultApiResponse;
import incheon.com.cmm.context.RequestContext;

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

import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 안건지도 관련 컨트롤러
 * 
 * @author hj
 */
@Controller
@RequiredArgsConstructor
@Slf4j
@RequestMapping("/pss/biz")
public class ProjectController {

    /** 안건지도 서비스 */
    private final ProjectService service;
    private final ULID ulid = new ULID(); // ULID 생성기

    @GetMapping("/list.do")
    public String list(ModelMap model) throws Exception {
        String loginUserId = RequestContext.getCurrentUserId();
        setProjects(model, loginUserId);

        return "pss/pjt/wrapper";
    }

    private void setProjects(ModelMap model, String loginUserId) throws Exception {
        log.info("loginUserId: {}", loginUserId);
        // 최근 항목 (최대 2개)
        ProjectSearchVO recentVO = new ProjectSearchVO();
        recentVO.setUserId(loginUserId);
        model.addAttribute("recentProjects", service.selectRecentProjects(recentVO));

        // 내 안건지도
        ProjectSearchVO mySearchVO = new ProjectSearchVO();
        mySearchVO.setUserId(loginUserId);
        int myPage = mySearchVO.getPageIndex();
        PaginationInfo paginationInfoMy = new PaginationInfo();
        paginationInfoMy.setCurrentPageNo(myPage);
        paginationInfoMy.setRecordCountPerPage(3);// mySearchVO.getRecordCountPerPage());
        paginationInfoMy.setPageSize(mySearchVO.getPageSize());
        mySearchVO.setFirstIndex(paginationInfoMy.getFirstRecordIndex());
        mySearchVO.setRecordCountPerPage(3);
        int myTotalCount = service.selectProjectListCnt(mySearchVO);
        paginationInfoMy.setTotalRecordCount(myTotalCount);
        model.addAttribute("myProjects", service.selectProjectList(mySearchVO));
        model.addAttribute("paginationInfoMy", paginationInfoMy);

        // 공유받은 안건지도
        ProjectSearchVO sharedSearchVO = new ProjectSearchVO();
        sharedSearchVO.setUserId(loginUserId);
        int sharedPage = sharedSearchVO.getPageIndex();
        PaginationInfo paginationInfoShared = new PaginationInfo();
        paginationInfoShared.setCurrentPageNo(sharedPage);
        paginationInfoShared.setRecordCountPerPage(3);// mySearchVO.getRecordCountPerPage());
        paginationInfoShared.setPageSize(sharedSearchVO.getPageSize());
        sharedSearchVO.setFirstIndex(paginationInfoShared.getFirstRecordIndex());
        sharedSearchVO.setRecordCountPerPage(3);
        int sharedTotalCount = service.selectSharedProjectsCnt(sharedSearchVO);
        paginationInfoShared.setTotalRecordCount(sharedTotalCount);
        model.addAttribute("sharedProjects", service.selectSharedProjects(sharedSearchVO));
        model.addAttribute("paginationInfoShared", paginationInfoShared);
    }

    /**
     * 안건지도 목록 조회
     * 
     * @param model 모델 맵
     * @return 안건지도 목록 JSP 경로
     * @throws Exception 예외 발생 시
     */
    @GetMapping("/pjtList.do")
    public String projectList(ModelMap model) throws Exception {
        String loginUserId = RequestContext.getCurrentUserId();
        setProjects(model, loginUserId);

        return "pss/pjt/list";
    }

    @GetMapping("/user/search.do")
    @ResponseBody
    public Map<String, Object> searchUsers(
            @RequestParam(defaultValue = "1") int pageIndex,
            @RequestParam(defaultValue = "10") int recordCountPerPage,
            @ModelAttribute UserSearchVO vo) throws Exception {

        vo.setPageIndex(pageIndex);
        vo.setRecordCountPerPage(recordCountPerPage);

        PaginationInfo paginationInfo = new PaginationInfo();
        paginationInfo.setCurrentPageNo(pageIndex);
        paginationInfo.setRecordCountPerPage(recordCountPerPage);
        paginationInfo.setPageSize(vo.getPageSize());

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

        int totalCount = service.selectUserCnt(vo);
        List<Map<String, Object>> userList = service.selectUserList(vo);
        paginationInfo.setTotalRecordCount(totalCount);

        Map<String, Object> result = new HashMap<>();
        result.put("userList", userList);
        result.put("totalCount", totalCount);
        result.put("paginationInfo", paginationInfo);

        return result;
    }

    @GetMapping("/detail.do")
    public String projectDetail(@RequestParam(required = false) Long bizNo, ModelMap model) throws Exception {
        String loginUserId = RequestContext.getCurrentUserId();
        if (bizNo != null) {
            ProjectSearchVO searchVO = new ProjectSearchVO();
            searchVO.setUserId(loginUserId);
            model.addAttribute("project", service.selectProject(bizNo));
            model.addAttribute("boundaryCount", service.countBoundaries(bizNo));
            model.addAttribute("imageCount", service.countImages(bizNo));
            model.addAttribute("modelCount", service.countModels(bizNo));
            model.addAttribute("viewpointCount", service.countViewpoints(bizNo));
            model.addAttribute("sketchCount", service.countSketches(bizNo));
            model.addAttribute("simulationCount", service.countSimulations(bizNo));
            model.addAttribute("sharedUsers", service.selectSharedUsers(bizNo));
        }
        return "pss/pjt/detail";
    }

    /**
     * 안건지도 상세 정보(JSON) 조회 (cepo_crdnt 포함)
     */
    @GetMapping("/getProjectJson.do")
    public ResponseEntity<DefaultApiResponse> getProjectJson(@RequestParam Long bizNo) throws Exception {
        ProjectVO project = service.selectProject(bizNo); // Mapper에서 ST_AsText로 변환된 좌표 포함
        return ResponseEntity.ok(
                DefaultApiResponse.success(project, "조회되었습니다."));
    }

    @GetMapping("/regist.do")
    public String projectRegist(ModelMap model) throws Exception {
        // LoginVO loginVO = (LoginVO) authentication.getPrincipal();
        model.addAttribute("project", new ProjectVO());
        return "pss/biz/projectRegist";
    }
    // 기존 delete, save, addSharedUser 메서드 유지

    @GetMapping("/delete.do")
    public String delete(@RequestParam Long bizNo, ModelMap model) throws Exception {
        log.info("bizNo: {}", bizNo);
        // LoginVO loginVO = (LoginVO) authentication.getPrincipal();
        // String loginUserId = loginVO.getUserId();
        service.deleteProject(bizNo);
        return "redirect:/pss/biz/list.do";
    }

    @PostMapping("/save.do")
    public ResponseEntity<DefaultApiResponse> save(@ModelAttribute ProjectVO projectVO, ModelMap model)
            throws Exception {
        // LoginVO loginVO = (LoginVO) authentication.getPrincipal();
        // projectVO.setUserId(loginVO.getUserId());
        Long bizNo = service.insertOrUpdate(projectVO);
        // return "redirect:/pss/biz/detail.do?bizNo=" + bizNo;

        return ResponseEntity.ok(
                DefaultApiResponse.success(bizNo, "저장되었습니다."));
    }

    /**
     * 안건지도 편집 화면 이동
     */
    @GetMapping("/edit.do")
    public String projectEdit(@RequestParam Long bizNo, ModelMap model) throws Exception {
        model.addAttribute("bizNo", bizNo); // bizNo 전달
        model.addAttribute("project", service.selectProject(bizNo));
        model.addAttribute("readOnly", false); // 편집 모드이므로 readOnly는 false
        return "pss/menu/wrapper";
    }

    /**
     * 안건지도 공유 URL 생성
     */
    @PostMapping("/generateShareUrl.do") // (updateShrnUrl.do -> generateShareUrl.do)
    public ResponseEntity<DefaultApiResponse> generateShareUrl(@RequestBody Map<String, Object> params)
            throws Exception {

        Long bizNo = Long.parseLong(params.get("bizNo").toString());
        String shrnKey = ulid.nextValue().toString(); // ULID 생성

        // [수정] 프론트엔드로 반환할 '전체 URL' 생성 (상대 경로, 쿼리 파라미터 방식)
        String fullUrl = "/pss/view/map.do?key=" + shrnKey; // [수정] 쿼리 파라미터 방식으로 변경

        // ProjectVO 객체에 bizNo와 생성된 fullUrl을 설정하여 DB에 저장
        ProjectVO projectVO = new ProjectVO();
        projectVO.setBizNo(bizNo);
        projectVO.setShrnUrl(fullUrl); // shrn_url 필드에 전체 URL 저장
        projectVO.setLastMdfcnId(RequestContext.getCurrentUserId()); // 최종 수정자 ID 설정
        service.updateProjectShrnUrl(projectVO); // ProjectService의 updateProjectShrnUrl 메서드 활용

        return ResponseEntity.ok(
                DefaultApiResponse.success(fullUrl, "URL이 생성되었습니다."));
    }

    // 탭 JSP 반환
    @GetMapping("/tab/boundary.do")
    public String getBoundaryTab(@RequestParam(defaultValue = "false") boolean readOnly, ModelMap model) {
        model.addAttribute("readOnly", readOnly);
        return "pss/menu/tab_boundary";
    }

    @GetMapping("/tab/floorplan.do")
    public String getFloorplanTab(@RequestParam(defaultValue = "false") boolean readOnly, ModelMap model) {
        model.addAttribute("readOnly", readOnly);
        return "pss/menu/tab_floorplan";
    }

    @GetMapping("/tab/model.do")
    public String getModelTab(@RequestParam(defaultValue = "false") boolean readOnly, ModelMap model) {
        model.addAttribute("readOnly", readOnly);
        return "pss/menu/tab_model";
    }

    @GetMapping("/tab/viewpoint.do")
    public String getViewpointTab(@RequestParam(defaultValue = "false") boolean readOnly, ModelMap model) {
        model.addAttribute("readOnly", readOnly);
        return "pss/menu/tab_viewpoint";
    }

    @GetMapping("/tab/drawing.do")
    public String getDrawingTab(@RequestParam(defaultValue = "false") boolean readOnly, ModelMap model) {
        model.addAttribute("readOnly", readOnly);
        return "pss/menu/tab_drawing";
    }

    @GetMapping("/tab/simulation.do")
    public String getSimulationTab(@RequestParam(defaultValue = "false") boolean readOnly, ModelMap model) {
        model.addAttribute("readOnly", readOnly);
        return "pss/menu/tab_simulation";
    }

    // 모달 JSP 반환
    @GetMapping("/modal/boundaryUpload.do")
    public String getBoundaryUploadModal() {
        return "pss/modal/modal_boundary_upload";
    }

    @GetMapping("/modal/adminSelect.do")
    public String getAdminSelectModal() {
        return "pss/modal/modal_admin_select";
    }

    @GetMapping("/modal/imageUpload.do")
    public String getImageUploadModal() {
        return "pss/modal/modal_image_upload";
    }

    @GetMapping("/modal/modelUpload.do")
    public String getModelUploadModal() {
        return "pss/modal/modal_model_upload";
    }

    @GetMapping("/modal/confirmDelete.do")
    public String getConfirmDeleteModal() {
        return "pss/modal/modal_confirm_delete";
    }

    // 시뮬레이션
    @GetMapping("/modal/windAnalysis.do")
    public String getWindAnalysisModal() {
        return "pss/smlt/modal_wind_analysis";
    }

    @GetMapping("/modal/insolationAnalysis.do")
    public String getInsolationAnalysisModal() {
        return "pss/smlt/modal_insolation_analysis";
    }

    @GetMapping("/modal/viewshedAnalysis.do")
    public String getViewshedAnalysisModal() {
        return "pss/smlt/modal_viewshed_analysis";
    }

    @GetMapping("/modal/slopeAnalysis.do")
    public String getSlopeAnalysisModal() {
        return "pss/smlt/modal_slope_analysis";
    }

    @GetMapping("/modal/vrViewer.do")
    public String getVrViewerModal() {
        return "pss/smlt/modal_vr_viewer";
    }

    @GetMapping("/modal/windMonthly.do")
    public String getWindMonthlyModal() {
        return "pss/smlt/modal_wind_monthly";
    }
    
    @GetMapping("/modal/sectionAnalysis.do")
    public String getSectionAnalysis() {
        return "pss/smlt/modal_section_analysis";
    }

    @GetMapping("/modal/earthworkAnalysis.do")
    public String getEarthworkAnalysisModal() {
        return "pss/smlt/modal_earthwork_analysis";
    }

}
