package incheon.ags.dss.regen.web;

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

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import incheon.com.cmm.api.DefaultApiResponse;
import incheon.ags.dss.regen.service.UrbFcltyAnlsService;
import incheon.ags.dss.regen.vo.UrbFcltyAnlsMstVO;
import incheon.ags.dss.regen.vo.UrbFcltyAnlsDtlVO;

import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;

// Swagger Imports
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;

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

/**
 * 도시재생 - 시설 분석 및 접근도 분석 컨트롤러
 * @author hj
 * @since 2025.11.28
 */
@Tag(name = "도시재생-시설/접근도 분석", description = "도시재생 구역 내 시설물 분석 및 접근도 분석 관련 API")
@RestController
@RequiredArgsConstructor
@Slf4j
@RequestMapping("/api/v1/dss/urb/fcltyAnls")
public class UrbFcltyAnlsApiController {

    private final UrbFcltyAnlsService service;

    /**
     * 분석 진행 상태 조회 (Polling용)
     */
    @GetMapping("/status.do")
    public ResponseEntity<DefaultApiResponse> getAnalysisStatus(@RequestParam("fcltAnlsNo") int fcltAnlsNo) throws Exception {
//        // 1. 결과 상세 테이블(urb_fclty_anls_dtl) 조회용 VO 생성
//        UrbFcltyAnlsDtlVO searchVO = new UrbFcltyAnlsDtlVO();
//        searchVO.setFcltAnlsNo(String.valueOf(fcltAnlsNo));
//
//        // 2. 현재 저장된 결과 데이터 개수 조회 (Service에 이미 존재하는 메서드 활용)
//        int count = service.selectAnalysisResultListCnt(searchVO);

        Map<String, Object> result = new HashMap<>();

//        // 3. 데이터가 1건이라도 있으면 '분석 완료(Y)'로 판단
//        // (비동기 로직이 delete -> insert 순서로 동작하므로, insert가 시작되면 count > 0이 됨)
//        result.put("status", count > 0 ? "Y" : "N");
    	
    	UrbFcltyAnlsMstVO mst = service.selectUrbFcltyAnlsMstDetail(fcltAnlsNo);
    	
    	// 상태 확인 로직
        String flag = mst.getLastMdfcnId();

        // 'RUNNING'이면 아직 도는 중
        if ("RUNNING".equals(flag)) {
            result.put("status", "N"); // 진행 중
        } else if ("NO_DATA".equals(flag)) {
            result.put("status", "Y");
            result.put("message", "설정된 반경 내에 분석 대상 시설물이 존재하지 않습니다.");
        } else if ("ERROR".equals(flag)) {
            // [추가] 에러 발생 시 처리
            result.put("status", "Y"); // 폴링 종료를 위해 Y 반환
            result.put("message", "분석 중 서버 오류가 발생했습니다. 관리자에게 문의하세요.");
        } else {
            // 정상 완료 (SUCCESS 또는 사용자 ID 복구됨)
            result.put("status", "Y");
        }

        return ResponseEntity.ok(DefaultApiResponse.success(result));
    }

    /**
     * 분석 실행 (POST)
     * 시나리오 1(시설분석): mainUsgCd 필수
     * 시나리오 2(접근도분석): trgtClsfNo 필수 (createTarget 선행)
     */
    @Operation(summary = "분석 실행", description = "입력된 파라미터(구역, 반경, 시설코드 등)를 기반으로 거리 분석을 수행합니다.")
    @PostMapping("/run.do")
    public ResponseEntity<DefaultApiResponse> runAnalysis(
            @Parameter(description = "분석 설정 정보 (zoneNo, radu, mainUsgCd OR trgtClsfNo)")
            @RequestBody UrbFcltyAnlsMstVO vo) throws Exception {

        // vo: zoneNo, radu, mainUsgCd('18%') 등
        int anlsNo = service.runFacilityAnalysis(vo);

        Map<String, Object> result = new HashMap<>();
        result.put("fcltAnlsNo", anlsNo);

        return ResponseEntity.ok(DefaultApiResponse.success(result, "분석이 완료되었습니다."));
    }

    /**
     * [시나리오 2] 분석 대상 사전 생성 (목록 선택 버튼 클릭 시)
     */
    @Operation(summary = "분석 대상 목록 생성 (접근도)", description = "접근도 분석을 위해 특정 시설물 목록을 미리 추출하여 저장합니다.")
    @PostMapping("/createTarget.do")
    public ResponseEntity<DefaultApiResponse> createTarget(
            @Parameter(description = "대상 생성 정보 (zoneNo, mainUsgCd)")
            @RequestBody UrbFcltyAnlsMstVO vo) throws Exception {

        // vo: zoneNo, mainUsgCd
        int trgtClsfNo = service.createTargetClassification(vo);

        Map<String, Object> result = new HashMap<>();
        result.put("trgtClsfNo", trgtClsfNo);
        // 필요하다면 여기서 바로 생성된 목록을 조회해서 리턴해줄 수도 있음 (urb_trgt_clsf_dtl 조회)

        return ResponseEntity.ok(DefaultApiResponse.success(result, "대상 목록이 생성되었습니다."));
    }

    /**
     * 분석 이력 목록 조회
     */
    @Operation(summary = "분석 이력 조회", description = "수행된 시설/접근도 분석 이력 목록을 페이징 처리하여 조회합니다.")
    @GetMapping("/list.do")
    public ResponseEntity<DefaultApiResponse> getList(
            @Parameter(description = "검색 조건 및 페이징 정보")
            @ModelAttribute UrbFcltyAnlsMstVO searchVO) throws Exception {

        PaginationInfo paginationInfo = new PaginationInfo();
        paginationInfo.setCurrentPageNo(searchVO.getPageIndex());
        paginationInfo.setRecordCountPerPage(5);
        paginationInfo.setPageSize(5);
        searchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());

        List<UrbFcltyAnlsMstVO> list = service.selectAnalysisList(searchVO);
        int totalCount = service.selectAnalysisListCnt(searchVO);
        paginationInfo.setTotalRecordCount(totalCount);

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

        return ResponseEntity.ok(DefaultApiResponse.success(result, "조회되었습니다."));
    }

    /**
     * 분석 결과 상세 조회 (스크롤 페이징)
     */
    @Operation(summary = "분석 결과 상세 조회", description = "특정 분석 번호(fcltAnlsNo)에 해당하는 결과를 페이징하여 조회합니다.")
    @GetMapping("/result.do")
    public ResponseEntity<DefaultApiResponse> getResult(
            @Parameter(description = "검색 VO (fcltAnlsNo, pageIndex 등)")
            @ModelAttribute UrbFcltyAnlsDtlVO searchVO) throws Exception {

        // 1. 페이징 설정 (기본값: 1페이지, 20개씩)
        PaginationInfo paginationInfo = new PaginationInfo();
        paginationInfo.setCurrentPageNo(searchVO.getPageIndex() > 0 ? searchVO.getPageIndex() : 1);
        paginationInfo.setRecordCountPerPage(searchVO.getRecordCountPerPage() > 0 ? searchVO.getRecordCountPerPage() : 20); // 한 번에 가져올 개수
        paginationInfo.setPageSize(1); // 스크롤 페이징에서는 크게 의미 없음

        searchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
        searchVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());

        // 2. 데이터 조회
        List<UrbFcltyAnlsDtlVO> list = service.selectAnalysisResultList(searchVO); // Service 파라미터 변경 필요
        int totalCount = service.selectAnalysisResultListCnt(searchVO); // Service 메소드 추가 필요

        // 3. 결과 맵핑
        Map<String, Object> result = new HashMap<>();
        result.put("list", list);
        result.put("totalCount", totalCount);
        result.put("currentPage", paginationInfo.getCurrentPageNo());

        // 더 가져올 데이터가 있는지 여부 (프론트 판단용)
        boolean hasNext = (paginationInfo.getFirstRecordIndex() + list.size()) < totalCount;
        result.put("hasNext", hasNext);

        return ResponseEntity.ok(DefaultApiResponse.success(result, "조회되었습니다."));
    }

    /**
     * [수정] 분석 상세 결과 단건 삭제
     * 목록에 있는 X 버튼/휴지통 버튼 클릭 시 호출
     */
    @Operation(summary = "분석 상세 결과 삭제", description = "특정 상세 결과(rsltNo) 하나를 삭제합니다.")
    @PostMapping("/deleteItem.do")
    public ResponseEntity<DefaultApiResponse> deleteItem(
            @Parameter(description = "삭제할 상세 번호가 담긴 VO")
            @RequestBody UrbFcltyAnlsDtlVO vo) throws Exception {

        // Service에 deleteResultItem 메소드 추가 필요 (구현은 mapper.deleteUrbFcltyAnlsDtlItem 호출)
        service.deleteResultItem(vo.getRsltNo());

        return ResponseEntity.ok(DefaultApiResponse.success(null, "해당 항목이 삭제되었습니다."));
    }

    /**
     * 접근도 분석 결과 마스터 목록 조회
     */
    @Operation(summary = "접근도 분석 결과 목록 조회", description = "특정 대상집합(trgtClsfNo)에 연결된 분석 결과 마스터 목록을 조회합니다.")
    @GetMapping("/anlsMstList.do")
    public ResponseEntity<DefaultApiResponse> getAnlsMstList(@ModelAttribute UrbFcltyAnlsMstVO searchVO) throws Exception {
        List<UrbFcltyAnlsMstVO> list = service.selectAceiAnlsMstList(searchVO);
        Map<String, Object> result = new HashMap<>();
        result.put("list", list);
        return ResponseEntity.ok(DefaultApiResponse.success(result));
    }

    /**
     * 분석 결과 삭제
     */
    @Operation(summary = "분석 결과 삭제", description = "특정 분석 결과(fcltAnlsNo) 마스터 및 상세 내역을 모두 삭제합니다.")
    @PostMapping("/deleteAnalysis.do")
    public ResponseEntity<DefaultApiResponse> deleteAnalysis(
            @Parameter(description = "삭제할 분석 번호가 담긴 VO")
            @RequestBody UrbFcltyAnlsMstVO vo) throws Exception {

        service.deleteAnalysis(Integer.valueOf(vo.getFcltAnlsNo()));

        return ResponseEntity.ok(DefaultApiResponse.success(null, "분석 결과가 삭제되었습니다."));
    }

    /**
     * [신규] 분석 대상 시설물 미리보기 조회
     */
    @Operation(summary = "분석 대상 조회", description = "설정된 반경 내 분석 대상 시설물 목록을 반환합니다.")
    @PostMapping("/targets.do")
    public ResponseEntity<DefaultApiResponse> getTargets(@RequestBody UrbFcltyAnlsMstVO vo) throws Exception {
        List<UrbFcltyAnlsDtlVO> list = service.selectTargetFacilities(vo);
        return ResponseEntity.ok(DefaultApiResponse.success(Map.of("list", list)));
    }
}
