package com.kamco.cd.kamcoback.scene.service;

import com.kamco.cd.kamcoback.common.enums.CommonUseStatus;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ResponseObj;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.MapSheet;
import com.kamco.cd.kamcoback.postgres.core.MapInkxMngCoreService;
import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto;
import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto.MapList;
import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto.UseInferReq;
import jakarta.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LinearRing;
import org.locationtech.jts.geom.PrecisionModel;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class MapInkxMngService {

  private final MapInkxMngCoreService mapInkxMngCoreService;

  public Page<MapList> findMapInkxMngList(
      MapInkxMngDto.searchReq searchReq, CommonUseStatus useInference, String searchVal) {
    return mapInkxMngCoreService.findMapInkxMngList(searchReq, useInference, searchVal);
  }

  public ResponseObj saveMapInkx5k(@Valid MapInkxMngDto.AddMapReq req) {

    String[] coordinates = req.getCoordinates().split("\\r?\\n");
    List<Coordinate> coords = new ArrayList<Coordinate>();

    for (String line : coordinates) {
      String[] parts = line.trim().split("\\s+");

      double lon = Double.parseDouble(parts[0]); // 경도
      double lat = Double.parseDouble(parts[1]); // 위도

      coords.add(new Coordinate(lon, lat));
    }

    // Polygon은 반드시 닫혀 있어야 함
    if (!coords.get(0).equals2D(coords.get(coords.size() - 1))) {
      coords.add(coords.get(0));
    }

    GeometryFactory GEOMETRY_FACTORY = new GeometryFactory(new PrecisionModel(), 4326);
    LinearRing shell = GEOMETRY_FACTORY.createLinearRing(coords.toArray(new Coordinate[0]));

    return mapInkxMngCoreService.saveMapInkx5k(req, GEOMETRY_FACTORY.createPolygon(shell));
  }

  // 도엽의 상태를 업데이트한다.
  @Transactional
  public MapSheet updateUseInference(@Valid UseInferReq useInferReq) {
    return mapInkxMngCoreService.updateUseInference(
        useInferReq.getMapidcdNo(), useInferReq.getUseInference());
  }
}
