package incheon.ags.dss.config.web;

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

import javax.servlet.http.HttpServletRequest;

import incheon.ags.pss.edit.service.LayerManageService;
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
import incheon.com.cmm.api.DefaultApiResponse;
// import incheon.com.cmm.util.RequestContext; // (로그인 ID용)

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
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.RestController;

import incheon.ags.dss.common.service.DssCommonService;
import incheon.ags.dss.config.service.SimZoneService;
import incheon.ags.dss.config.vo.SimZoneMstVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

/**
 * 시뮬레이션 구역(SimZone) 기능의 JSON 데이터를 반환하는 API 컨트롤러
 */
@RestController 
@RequiredArgsConstructor
@Slf4j
@RequestMapping("/api/v1/dss/sim/simZone") // API 전용 경로
public class SimZoneApiController {

    private final SimZoneService simZoneService;
    private final DssCommonService dssCommonService;

    private final LayerManageService layerManageService;

    //1. '구' 목록 조회 API
    @GetMapping("/guList.do")
    public ResponseEntity<DefaultApiResponse> getGuList() throws Exception {
        List<Map<String, Object>> list = dssCommonService.selectGuList();
        return ResponseEntity.ok(DefaultApiResponse.success(list));
    }
    
    //2. '동' 목록 조회 API
    @GetMapping("/dongList.do")
    public ResponseEntity<DefaultApiResponse> getDongList(@RequestParam String sigCd) throws Exception {
        List<Map<String, Object>> list = dssCommonService.selectDongList(sigCd);
        return ResponseEntity.ok(DefaultApiResponse.success(list));
    }
    
    @GetMapping("/getEmdData.do")
    public ResponseEntity<DefaultApiResponse> getEmdData(@RequestParam String emdCd) throws Exception {
        return ResponseEntity.ok(
                DefaultApiResponse.success(dssCommonService.selectEmdDataForDetail(emdCd), "행정동 좌표가 조회되었습니다.")
            );
    }
    
    //TODO moon : 스크롤 다운으로 페이징처리
    /**
     * 구역 목록(Mst) 데이터 조회 (JSON)
     * (요청하신 'getMyProjects' 예시와 동일한 페이징 로직 적용)
     */
    @GetMapping("/list.do")
    public ResponseEntity<DefaultApiResponse> getSimZoneList(
            @RequestParam(defaultValue = "1") int pageIndex,
            @RequestParam(defaultValue = "5") int recordCountPerPage,
            @RequestParam(required = false) String searchKeyword) throws Exception {
        
        log.warn("API: getSimZoneList (Page: {}, Keyword: {})", pageIndex, searchKeyword);
        
        // 1. PaginationInfo 생성 (eGov)
        PaginationInfo paginationInfo = new PaginationInfo();
        paginationInfo.setCurrentPageNo(pageIndex);
        paginationInfo.setRecordCountPerPage(recordCountPerPage);
         paginationInfo.setPageSize(recordCountPerPage);

        // 2. SearchVO (SimZoneMstVO) 생성 및 페이징 값 세팅
        SimZoneMstVO searchVO = new SimZoneMstVO();
        searchVO.setPageIndex(pageIndex);
        searchVO.setRecordCountPerPage(recordCountPerPage);
        searchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
        
        if (searchKeyword != null) {
            searchVO.setSearchKeyword(searchKeyword);
        }
        
        // 3. 서비스 호출 (List + Count)
        List<SimZoneMstVO> list = simZoneService.selectSimZoneList(searchVO);
        int totalCount = simZoneService.selectSimZoneListCnt(searchVO);
        paginationInfo.setTotalRecordCount(totalCount);
        
        // 4. Map에 담아 반환
        Map<String, Object> result = new HashMap<>();
        result.put("list", list);
        result.put("paging", paginationInfo);
        
        return ResponseEntity.ok(DefaultApiResponse.success(result, "조회되었습니다."));
    }

    /**
     * 구역 상세(Mst + Dtl) 데이터 조회 (JSON)
     */
    @GetMapping("/detail.do")
    public ResponseEntity<DefaultApiResponse> getSimZoneDetail(@RequestParam("zoneNo") Long zoneNo) throws Exception {
        
        log.info("API: getSimZoneDetail (zoneNo: {})", zoneNo);
        
        SimZoneMstVO vo = new SimZoneMstVO();
        vo.setZoneNo(zoneNo);
        
        // 룰 5: Mst + Dtl(itemList)이 포함된 VO를 한 번에 조회
        SimZoneMstVO resultSet = simZoneService.selectSimZoneDetail(vo);
        
        return ResponseEntity.ok(DefaultApiResponse.success(resultSet, "조회되었습니다."));
    }

    /**
     * 구역 정보(Mst + Dtl) 저장 (JSON)
     * (JSP가 아닌 3D 클라이언트 등에서 JSON으로 직접 호출할 경우 @RequestBody 사용)
     * (JSP 폼에서 호출할 경우 @ModelAttribute 사용 - 여기서는 JSON을 표준으로 @RequestBody 사용)
     */
    @PostMapping("/save.do")
    public ResponseEntity<DefaultApiResponse> saveSimZone(
            @RequestBody SimZoneMstVO vo, // JSON(application/json)으로 전송 시
            HttpServletRequest request) throws Exception {
        
        log.info("API: saveSimZone (zoneNm: {}, {} items)", vo.getZoneNm(), vo.getItemList() != null ? vo.getItemList().size() : 0);
        
        // Mst + Dtl(itemList)을 한 번에 저장/수정
        Long zoneNo = simZoneService.saveSimZone(vo);
        
        return ResponseEntity.ok(DefaultApiResponse.success(zoneNo, "저장되었습니다."));
    }

    /**
     * 구역 정보(Mst + Dtl) 삭제 (JSON) (룰 3)
     */
    @PostMapping("/delete.do")
    public ResponseEntity<DefaultApiResponse> deleteSimZone(
            @RequestParam("zoneNo") Long zoneNo,
            HttpServletRequest request) throws Exception {
        
        log.info("API: deleteSimZone (zoneNo: {})", zoneNo);
        
        SimZoneMstVO vo = new SimZoneMstVO();
        vo.setZoneNo(zoneNo);
        
        // 룰 5: Mst + Dtl(및 10개 자식 테이블)을 한 번에 삭제
        simZoneService.deleteSimZone(vo);
        
        return ResponseEntity.ok(DefaultApiResponse.success(null, "삭제되었습니다."));
    }
    
    /**
     * 사용자가 그린 영역(geom)과 교차하는 행정구역/지적도 목록을 반환
     * @param params (geom: "POLYGON(...)", layerType: 'emd', 'cadastral')
     */
    @PostMapping("/findIntersectingArea.do")
    public ResponseEntity<DefaultApiResponse> findIntersectingArea(@RequestBody Map<String, Object> params) throws Exception {
        return ResponseEntity.ok(
                DefaultApiResponse.success(dssCommonService.findIntersectingArea(params), "교차 영역이 조회되었습니다.")
            );
    }

    @PostMapping("/previewShape.do")
    public ResponseEntity<DefaultApiResponse> previewShape(@RequestParam("file") MultipartFile file) throws Exception {
        Map<String, Object> geojson = layerManageService.previewShape(file);

        return ResponseEntity.ok(
                DefaultApiResponse.success(Collections.singletonMap("geojson", geojson), "Shapefile 미리보기가 생성되었습니다.")
        );
    }
}