package incheon.ags.pss.edit.web;

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

import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
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.multipart.MultipartFile;

import incheon.ags.pss.edit.service.LayerManageService;
import incheon.ags.pss.edit.vo.BoundaryDetailVO;
import incheon.ags.pss.edit.vo.BoundaryVO;
import incheon.com.cmm.api.DefaultApiResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 안건지도 경계 관리 컨트롤러
 * @author hj
 */
@Controller
@RequiredArgsConstructor
@Slf4j
@RequestMapping("/pss/edit/boundary") // 예시 URL
public class LayerManageController {

    private final LayerManageService layerManageService;

    //1. '구' 목록 조회 API
    @GetMapping("/guList.do")
    public ResponseEntity<DefaultApiResponse> getGuList() throws Exception {
        List<Map<String, Object>> list = layerManageService.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 = layerManageService.selectDongList(sigCd);
        return ResponseEntity.ok(DefaultApiResponse.success(list));
    }
    
    @GetMapping("/getEmdData.do")
    public ResponseEntity<DefaultApiResponse> getEmdData(@RequestParam String emdCd) throws Exception {
        BoundaryDetailVO vo = layerManageService.selectEmdDataForDetail(emdCd);
        return ResponseEntity.ok(
                DefaultApiResponse.success(vo, "행정동 좌표가 조회되었습니다.")
            );
    }
    
    /**
     * 경계 목록 조회
     * @param bizNo 안건지도 번호
     * @return 
     * @return List<LayerManageVO>
     * @throws Exception
     */
    @GetMapping("/list.do")
    public ResponseEntity<DefaultApiResponse> selectBoundaryList(@RequestParam Long bizNo) throws Exception {
    	List<BoundaryVO> list = layerManageService.selectBoundaryList(bizNo);
    	
        return ResponseEntity.ok(
                DefaultApiResponse.success(list, "조회되었습니다.")
            );
    }

    /**
     * 경계 상세 조회
     * @param bndryNo 경계 번호
     * @return 
     * @return LayerManageVO
     * @throws Exception
     */
    @GetMapping("/detail.do")
    public ResponseEntity<DefaultApiResponse> selectBoundary(@RequestParam Long bndryNo) throws Exception {
    			
    	BoundaryVO vo = layerManageService.selectBoundary(bndryNo);
    	
        return ResponseEntity.ok(
                DefaultApiResponse.success(vo, "조회되었습니다.")
            );
    }
    
    /**
     * 경계 등록
     * @param vo LayerManageVO
     * @throws Exception
     */
    @PostMapping("/save.do")
    public ResponseEntity<DefaultApiResponse> insertBoundary(@RequestBody BoundaryVO vo) throws Exception {
        layerManageService.insertBoundary(vo);
    	
        return ResponseEntity.ok(
                DefaultApiResponse.success(vo.getBndryNo(), "저장되었습니다.")
            );
    }

    /**
     * 경계 수정
     * @param vo LayerManageVO
     * @throws Exception
     */
    @PostMapping("/update.do")
    public ResponseEntity<DefaultApiResponse> updateBoundary(@RequestBody BoundaryVO vo) throws Exception {
    	layerManageService.updateBoundary(vo);
    	
        return ResponseEntity.ok(
                DefaultApiResponse.success(vo.getBndryNo(), "수정되었습니다.")
            );
    }

    /**
     * 경계 삭제
     * @param bndryNo 경계 번호
     * @throws Exception
     */
    @PostMapping("/delete.do")
    public ResponseEntity<DefaultApiResponse> deleteBoundary(@RequestParam Long bndryNo) throws Exception {
    	layerManageService.deleteBoundary(bndryNo);
         
    	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 {
        
    	BoundaryDetailVO vo = layerManageService.findIntersectingArea(params);
        
        return ResponseEntity.ok(
                DefaultApiResponse.success(vo, "교차 영역이 조회되었습니다.")
            );
    }
    
    /**
     * Shapefile 미리보기
     * <p>
     * 업로드된 Shapefile(zip)을 서버에 저장하지 않고 메모리에서 직접 GeoJSON으로 변환하여 반환합니다.
     * 이를 통해 디스크 I/O를 최소화하고 성능을 개선합니다.
     * </p>
     * @param file Shapefile(.shp, .shx, .dbf 등)을 포함하는 zip 압축 파일
     * @return FeatureCollection GeoJSON 문자열
     * @throws Exception Shapefile 처리 중 발생하는 예외
     */
    @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 미리보기가 생성되었습니다.")
        );
    }
}