package incheon.ags.dss.under.web;

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

import javax.servlet.http.HttpServletRequest;

import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
import incheon.com.cmm.api.DefaultApiResponse;
// import incheon.com.cmm.util.RequestContext;

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.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import incheon.ags.dss.under.service.UrbUdgdSnkgHistService;
import incheon.ags.dss.under.vo.UrbUdgdSnkgHistVO;
import incheon.ags.dss.under.web.dto.UrbUdgdSnkgOpenApiDetailResDTO;
import incheon.ags.dss.under.web.dto.UrbUdgdSnkgOpenApiListResDTO;
import incheon.ags.dss.under.web.dto.UrbUdgdSnkgOpenApiReqDTO;
// Swagger Imports
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 지반침하(싱크홀) 이력(UrbUdgdSnkgHist) 기능의 JSON 데이터를 반환하는 API 컨트롤러 (R-Only)
 */
@Tag(name = "지반침하(싱크홀) 이력", description = "지반침하(싱크홀) 이력 데이터 조회 API")
@RestController 
@RequiredArgsConstructor
@Slf4j
@RequestMapping("/api/v1/dss/urb/udgdSnkgHist")
public class UrbUdgdSnkgHistApiController {

    private final UrbUdgdSnkgHistService urbUdgdSnkgHistService;

    /**
     * 지반침하 이력 목록 데이터 조회 (JSON)
     */
    @Operation(summary = "지반침하 이력 목록 조회", description = "검색 조건 및 페이징 처리에 따른 지반침하 이력 목록을 조회합니다.")
    @GetMapping("/list.do")
    public ResponseEntity<DefaultApiResponse> getUrbUdgdSnkgHistList(
            @Parameter(description = "검색 조건 및 페이징 정보 (VO)", hidden = true) 
            @ModelAttribute UrbUdgdSnkgHistVO searchVO) throws Exception {
        
        log.info("API: getUrbUdgdSnkgHistList (Page: {}, Keyword: {})", searchVO.getPageIndex(), searchVO.getSearchKeyword());
        
        PaginationInfo paginationInfo = new PaginationInfo();
        paginationInfo.setCurrentPageNo(searchVO.getPageIndex());
        paginationInfo.setRecordCountPerPage(searchVO.getRecordCountPerPage());
        paginationInfo.setPageSize(searchVO.getPageSize());

        searchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
        // searchVO.setLOGIN_USER_ID(RequestContext.getCurrentUserId());

        List<UrbUdgdSnkgHistVO> list = urbUdgdSnkgHistService.selectUrbUdgdSnkgHistList(searchVO);
        int totalCount = urbUdgdSnkgHistService.selectUrbUdgdSnkgHistListCnt(searchVO);
        paginationInfo.setTotalRecordCount(totalCount);
        
        Map<String, Object> result = new HashMap<>();
        result.put("list", list);
        result.put("paging", paginationInfo);
        
        return ResponseEntity.ok(DefaultApiResponse.success(result, "조회되었습니다."));
    }

    /**
     * 지반침하 이력 상세 데이터 조회 (JSON)
     */
    @Operation(summary = "지반침하 이력 상세 조회", description = "사고 번호(acdntNo)를 기준으로 단건 상세 정보를 조회합니다.")
    @GetMapping("/detail.do")
    public ResponseEntity<DefaultApiResponse> getUrbUdgdSnkgHistDetail(
            @Parameter(description = "사고 번호 (PK)", required = true, example = "1") 
            @RequestParam("acdntNo") int acdntNo) throws Exception {
        
        log.info("API: getUrbUdgdSnkgHistDetail (acdntNo: {})", acdntNo);
        
        UrbUdgdSnkgHistVO vo = new UrbUdgdSnkgHistVO();
        vo.setAcdntNo(acdntNo); // 변경된 필드명 사용
        
        UrbUdgdSnkgHistVO resultSet = urbUdgdSnkgHistService.selectUrbUdgdSnkgHistDetail(vo);
        
        return ResponseEntity.ok(DefaultApiResponse.success(resultSet, "조회되었습니다."));
    }
    
    /**
     * [NEW] DB 적재 데이터 전용 조회 API
     * Open API를 타지 않고 우리 DB(icdss.urb_udgd_snkg_hist)에서 직접 데이터를 반환합니다.
     */
    @Operation(summary = "지반침하 이력 DB 조회 (전용)", description = "로컬 DB에 적재된 데이터를 DTO 규격으로 조회합니다.")
    @GetMapping("/db/incheon-list.do")
    public ResponseEntity<DefaultApiResponse> getDbSubsidenceList(
            @ModelAttribute UrbUdgdSnkgOpenApiReqDTO reqDto) throws Exception {
        
        log.info("API: getDbSubsidenceList (ZoneNo: {}, Period: {}~{})", 
                 reqDto.getZoneNo(), reqDto.getSagoDateFrom(), reqDto.getSagoDateTo());

        // 신규 서비스 메서드 호출
        List<UrbUdgdSnkgOpenApiListResDTO> resultList = urbUdgdSnkgHistService.selectIncheonSubsidenceDbList(reqDto);

        Map<String, Object> response = new HashMap<>();
        response.put("list", resultList);
        response.put("count", resultList.size());

        return ResponseEntity.ok(DefaultApiResponse.success(response, "DB 데이터 조회 성공"));
    }
    
    /**
     * [실제 사용] 인천광역시 지반침하 사고 전수 조회 (자동 페이징 + 필터링)
     * 로직: 100건씩 전체 조회 -> 인천광역시만 필터링 -> 반환
     */
    @Operation(summary = "인천광역시 지반침하 사고 전체 조회", description = "Open API를 반복 호출하여 인천광역시 데이터만 추출합니다.")
    @GetMapping("/openapi/incheon-list.do")
    public ResponseEntity<DefaultApiResponse> getIncheonSubsidenceList(
            @ModelAttribute UrbUdgdSnkgOpenApiReqDTO reqDto
         // reqDto 안에 zoneNo=60 등이 들어오면 자동 매핑됨
    ) throws Exception {
        
        log.info("API: getIncheonSubsidenceList (Start: {}, End: {})", reqDto.getSagoDateFrom(), reqDto.getSagoDateTo());

        // Service 호출 (내부에서 반복문 및 필터링 수행)
        List<UrbUdgdSnkgOpenApiListResDTO> resultList = urbUdgdSnkgHistService.fetchAllIncheonSubsidenceDtlList(reqDto);//urbUdgdSnkgHistService.fetchAllIncheonSubsidenceList(reqDto);

        Map<String, Object> response = new HashMap<>();
        response.put("list", resultList);
        response.put("count", resultList.size()); // 추출된 건수

        return ResponseEntity.ok(DefaultApiResponse.success(response, "인천광역시 데이터 추출 성공"));
    }
    
    /**
     * [Test] Open API 목록 조회
     */
    @Operation(summary = "[Test] Open API 목록 조회", description = "공공데이터 포털 실시간 호출")
    @GetMapping("/openapi/list.do")
    public ResponseEntity<DefaultApiResponse> getOpenApiList(
            @ModelAttribute UrbUdgdSnkgOpenApiReqDTO reqDto
    ) throws Exception {
        
        // Service에서 List<DTO> 반환
        List<UrbUdgdSnkgOpenApiListResDTO> resultList = urbUdgdSnkgHistService.getOpenApiSubsidenceList(reqDto);

        // 결과 Map핑 (페이징 정보 등은 API 응답 헤더나 별도 필드에 있다면 추가 처리 필요)
        Map<String, Object> response = new HashMap<>();
        response.put("list", resultList);

        return ResponseEntity.ok(DefaultApiResponse.success(response, "Open API 목록 조회 성공"));
    }

    /**
     * [Test] Open API 상세 조회
     */
    @Operation(summary = "[Test] Open API 상세 조회", description = "공공데이터 포털 실시간 호출")
    @GetMapping("/openapi/detail.do")
    public ResponseEntity<DefaultApiResponse> getOpenApiDetail(
            @RequestParam String sagoNo
    ) throws Exception {
        
        // Service에서 단건 DTO 반환
        UrbUdgdSnkgOpenApiDetailResDTO resultDetail = urbUdgdSnkgHistService.getOpenApiSubsidenceDetail(sagoNo);

        return ResponseEntity.ok(DefaultApiResponse.success(resultDetail, "Open API 상세 조회 성공"));
    }
    
    @GetMapping("/manual/sync.do")
    public ResponseEntity<DefaultApiResponse> manualSync() throws Exception {
        urbUdgdSnkgHistService.syncIncheonSubsidenceData();
        return ResponseEntity.ok(DefaultApiResponse.success(null, "수동 동기화 성공"));
    }
    
}