package com.kamco.cd.kamcoback.geojson.controller;

import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnDataEntity;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnDataGeomEntity;
import com.kamco.cd.kamcoback.postgres.repository.MapSheetLearnDataGeomRepository;
import com.kamco.cd.kamcoback.postgres.repository.MapSheetLearnDataRepository;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;

/** GeoJSON 데이터 조회 및 테스트용 API 컨트롤러 */
@Slf4j
@RequiredArgsConstructor
public class GeoJsonDataController {

  private final MapSheetLearnDataRepository mapSheetLearnDataRepository;
  private final MapSheetLearnDataGeomRepository mapSheetLearnDataGeomRepository;

  /** 학습 데이터 목록 조회 */
  @GetMapping("/learn-data")
  public ResponseEntity<Map<String, Object>> getLearnDataList(
      @RequestParam(defaultValue = "0") int page,
      @RequestParam(defaultValue = "10") int size,
      @RequestParam(required = false) String dataState,
      @RequestParam(required = false) String analState) {
    try {
      PageRequest pageRequest = PageRequest.of(page, size);
      List<MapSheetLearnDataEntity> learnDataList;

      if (dataState != null) {
        learnDataList = mapSheetLearnDataRepository.findByDataState(dataState);
      } else if (analState != null) {
        learnDataList = mapSheetLearnDataRepository.findByAnalState(analState);
      } else {
        learnDataList = mapSheetLearnDataRepository.findAll(pageRequest).getContent();
      }

      Map<String, Object> response = new HashMap<>();
      response.put("data", learnDataList);
      response.put("totalCount", learnDataList.size());
      response.put("page", page);
      response.put("size", size);

      return ResponseEntity.ok(response);
    } catch (Exception e) {
      log.error("학습 데이터 목록 조회 실패", e);
      return ResponseEntity.internalServerError()
          .body(Map.of("error", "데이터 조회 실패: " + e.getMessage()));
    }
  }

  /** 특정 학습 데이터 상세 조회 */
  @GetMapping("/learn-data/{id}")
  public ResponseEntity<Map<String, Object>> getLearnDataDetail(@PathVariable Long id) {
    try {
      if (id == null) {
        return ResponseEntity.badRequest().body(Map.of("error", "ID가 필요합니다."));
      }

      Optional<MapSheetLearnDataEntity> learnDataOpt = mapSheetLearnDataRepository.findById(id);

      if (learnDataOpt.isEmpty()) {
        return ResponseEntity.notFound().build();
      }

      MapSheetLearnDataEntity learnData = learnDataOpt.get();
      List<MapSheetLearnDataGeomEntity> geometryList =
          mapSheetLearnDataGeomRepository.findByDataUid(id);

      Map<String, Object> response = new HashMap<>();
      response.put("learnData", learnData);
      response.put("geometryData", geometryList);
      response.put("geometryCount", geometryList.size());

      return ResponseEntity.ok(response);
    } catch (Exception e) {
      log.error("학습 데이터 상세 조회 실패: {}", id, e);
      return ResponseEntity.internalServerError()
          .body(Map.of("error", "데이터 조회 실패: " + e.getMessage()));
    }
  }

  /** Geometry 데이터 목록 조회 */
  @GetMapping("/geometry")
  public ResponseEntity<Map<String, Object>> getGeometryDataList(
      @RequestParam(defaultValue = "0") int page,
      @RequestParam(defaultValue = "10") int size,
      @RequestParam(required = false) Long dataUid,
      @RequestParam(required = false) String geoType) {
    try {
      List<MapSheetLearnDataGeomEntity> geometryList;

      if (dataUid != null) {
        geometryList = mapSheetLearnDataGeomRepository.findByDataUid(dataUid);
      } else if (geoType != null) {
        geometryList = mapSheetLearnDataGeomRepository.findByGeoType(geoType);
      } else {
        PageRequest pageRequest = PageRequest.of(page, size);
        geometryList = mapSheetLearnDataGeomRepository.findAll(pageRequest).getContent();
      }

      Map<String, Object> response = new HashMap<>();
      response.put("data", geometryList);
      response.put("totalCount", geometryList.size());
      response.put("page", page);
      response.put("size", size);

      return ResponseEntity.ok(response);
    } catch (Exception e) {
      log.error("Geometry 데이터 목록 조회 실패", e);
      return ResponseEntity.internalServerError()
          .body(Map.of("error", "데이터 조회 실패: " + e.getMessage()));
    }
  }

  /** 시스템 통계 정보 조회 */
  @GetMapping("/statistics")
  public ResponseEntity<Map<String, Object>> getStatistics() {
    try {
      long totalLearnData = mapSheetLearnDataRepository.count();
      long totalGeometryData = mapSheetLearnDataGeomRepository.count();

      List<MapSheetLearnDataEntity> processedData =
          mapSheetLearnDataRepository.findByDataState("PROCESSED");
      List<MapSheetLearnDataEntity> pendingAnalysis =
          mapSheetLearnDataRepository.findByAnalState("PENDING");
      List<MapSheetLearnDataEntity> completedAnalysis =
          mapSheetLearnDataRepository.findByAnalState("COMPLETED");
      List<MapSheetLearnDataEntity> errorAnalysis =
          mapSheetLearnDataRepository.findByAnalState("ERROR");

      Map<String, Object> statistics = new HashMap<>();
      statistics.put("totalLearnData", totalLearnData);
      statistics.put("totalGeometryData", totalGeometryData);
      statistics.put("processedDataCount", processedData.size());
      statistics.put("pendingAnalysisCount", pendingAnalysis.size());
      statistics.put("completedAnalysisCount", completedAnalysis.size());
      statistics.put("errorAnalysisCount", errorAnalysis.size());

      // 처리 완료율 계산
      if (totalLearnData > 0) {
        double completionRate = (double) completedAnalysis.size() / totalLearnData * 100;
        statistics.put("completionRate", Math.round(completionRate * 100.0) / 100.0);
      } else {
        statistics.put("completionRate", 0.0);
      }

      return ResponseEntity.ok(
          Map.of("statistics", statistics, "timestamp", java.time.Instant.now()));
    } catch (Exception e) {
      log.error("통계 정보 조회 실패", e);
      return ResponseEntity.internalServerError()
          .body(Map.of("error", "통계 조회 실패: " + e.getMessage()));
    }
  }

  /** 데이터 상태별 카운트 조회 */
  @GetMapping("/status-counts")
  public ResponseEntity<Map<String, Object>> getStatusCounts() {
    try {
      Map<String, Long> dataStateCounts = new HashMap<>();
      Map<String, Long> analStateCounts = new HashMap<>();

      // 데이터 상태별 카운트
      dataStateCounts.put(
          "PROCESSED", mapSheetLearnDataRepository.findByDataState("PROCESSED").size() + 0L);
      dataStateCounts.put(
          "PENDING",
          mapSheetLearnDataRepository.findByDataStateIsNullOrDataState("PENDING").size() + 0L);

      // 분석 상태별 카운트
      analStateCounts.put(
          "PENDING", mapSheetLearnDataRepository.findByAnalState("PENDING").size() + 0L);
      analStateCounts.put(
          "COMPLETED", mapSheetLearnDataRepository.findByAnalState("COMPLETED").size() + 0L);
      analStateCounts.put(
          "ERROR", mapSheetLearnDataRepository.findByAnalState("ERROR").size() + 0L);

      return ResponseEntity.ok(
          Map.of(
              "dataStateCounts", dataStateCounts,
              "analStateCounts", analStateCounts,
              "timestamp", java.time.Instant.now()));
    } catch (Exception e) {
      log.error("상태별 카운트 조회 실패", e);
      return ResponseEntity.internalServerError()
          .body(Map.of("error", "카운트 조회 실패: " + e.getMessage()));
    }
  }
}
