// NOTE: Adjust the package line if your project uses a different package.
package incheon.uis.uld.web;

import com.fasterxml.jackson.databind.ObjectMapper;
import incheon.uis.uld.dto.AdditionalOptionsDTO;
import incheon.uis.uld.service.UisFileUploadService;
import incheon.uis.uld.vo.FileUploadVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.bind.annotation.RequestBody;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

@RestController
@RequestMapping("/api/uis/uld/upload")
public class UisFileUploadController {

    private final UisFileUploadService uisFileUploadService;
    @Autowired private ObjectMapper objectMapper;

    @Autowired
    public UisFileUploadController(UisFileUploadService uisFileUploadService) {
        this.uisFileUploadService = uisFileUploadService;
    }

    // ---------------------------------------------------------------------
    // [EXISTING] 업로드 + (필요 시) 변환 후 미리보기용 GeoJSON 반환
    // ---------------------------------------------------------------------
    // 그대로 교체
    @PostMapping(
            value = "/upload.do",
            consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE
    )
    @ResponseBody
    public ResponseEntity<Map<String, Object>> handleFileUpload(
            @ModelAttribute AdditionalOptionsDTO options,
            @ModelAttribute FileUploadVO fileUploadVO) {

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

        try {
            MultipartFile file = options.getFile();
            if (file == null || file.isEmpty()) {
                throw new IllegalArgumentException("업로드 파일이 없습니다.");
            }

            //업로드는 '항상' 미리보기 목적(서버 측에서 강제)
            options.setPreviewOnly(Boolean.TRUE);
            // 혹시라도 클라에서 actionType을 보내더라도 영향 없도록 무시/고정
            options.setActionType("PREVIEW");

            List<String> shapeColumns = Optional.ofNullable(options.getShapeColumns()).orElseGet(ArrayList::new);
            String firstColumn   = options.getFirstColumn();
            String secondColumn  = options.getSecondColumn();

            String pkColumn      = options.getPkColumn();     // 미리보기 단계에선 의미 없음
            String tableName     = options.getTableName();    // 미리보기 단계에선 의미 없음

            boolean previewOnly  = true; // 강제
            Integer previewLimit = options.getPreviewLimit();

            // 업로드 + (필요 시) 변환 → GeoJSON 경로들 반환 (DB 저장 없음)
            List<String> geoJsonPaths = uisFileUploadService.uploadFile(
                    file, fileUploadVO, shapeColumns, firstColumn, secondColumn,
                    "PREVIEW", pkColumn, tableName, previewOnly
            );

            // 미리보기용 GeoJSON을 실제 객체로 읽어 전달
            List<Object> geojsonList = new ArrayList<>();
            List<String> layerNames  = new ArrayList<>();

            for (String p : geoJsonPaths) {
                String txt;
                try {
                    txt = Files.readString(Paths.get(p), StandardCharsets.UTF_8);
                } catch (Exception e) {
                    txt = Files.readString(Paths.get(p), Charset.forName("EUC-KR"));
                }
                Object json = objectMapper.readValue(txt, Object.class);
                geojsonList.add(json);

                if (json instanceof Map<?,?> root) {
                    Object name = ((Map<?,?>) root).get("name");
                    if (name != null) layerNames.add(String.valueOf(name));
                }
            }

            data.put("geojsonList", geojsonList);
            data.put("paths", geoJsonPaths);
            data.put("layers", layerNames);
            data.put("coordinate", fileUploadVO.getFilecoordinate());
            data.put("count", geojsonList.size());
            data.put("previewOnly", true);
            data.put("previewLimit", previewLimit);

            res.put("success", true);
            res.put("data", data);
            return ResponseEntity.ok(res);

        } catch (Exception e) {
            res.put("success", false);
            res.put("message", "요청 처리 중 오류가 발생했습니다.");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(res);
        }
    }


    // ---------------------------------------------------------------------
    // [ADDED] 미리보기 결과를 테이블에 저장
    //  - 기존 로직은 그대로 두고, 새 엔드포인트만 추가합니다.
    //  - 프론트에서 window.lastPreviewGeojsonList를 넘겨 호출
    // ---------------------------------------------------------------------
    @PostMapping(
            value = "/saveFromPreview.do",
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE
    )
    @ResponseBody
    public ResponseEntity<Map<String, Object>> savePreview(@RequestBody Map<String, Object> req) {
        Map<String, Object> res = new HashMap<>();
        Map<String, Object> data = new HashMap<>();
        try {
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> geojsonList =
                    (List<Map<String, Object>>) req.get("geojsonList");

            if (geojsonList == null || geojsonList.isEmpty()) {
                throw new IllegalArgumentException("미리보기 데이터(geojsonList)가 없습니다.");
            }

            // 선택 파라미터(없어도 됨)
            @SuppressWarnings("unchecked")
            List<String> tableNameList = (List<String>) req.get("tableNameList"); // 생략 가능
            String coordinate = (String) req.get("coordinate");
            String actionType = (String) req.get("actionType");
            String pkColumn   = (String) req.get("pkColumn");
            Integer srid      = null;
            Object sridRaw = req.get("srid");
            if (sridRaw instanceof Number) srid = ((Number) sridRaw).intValue();
            else if (sridRaw instanceof String s && !s.isBlank()) srid = Integer.valueOf(s);

            int saved = uisFileUploadService.saveFromPreview(
                    geojsonList,
                    coordinate,
                    tableNameList,
                    actionType,
                    pkColumn,
                    srid
            );

            data.put("savedCount", saved);
            res.put("success", true);
            res.put("message", "저장 완료 (" + saved + ")");
            res.put("data", data);
            return ResponseEntity.ok(res);

        } catch (Exception e) {
            res.put("success", false);
            res.put("message", "요청 처리 중 오류가 발생했습니다.");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(res);
        }
    }
}
