package incheon.ags.mrb.analysis.web;

import incheon.ags.mrb.analysis.service.AnalysisHistoryService;
import incheon.ags.mrb.analysis.vo.AnlsHstryJoinVO;
import incheon.ags.mrb.analysis.service.ExcelDownloadService;
import incheon.com.security.vo.LoginVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Tag(name = "분석 이력 엑셀 다운로드 API")
@RestController
@RequestMapping("/ags/mrb/analysis")
@RequiredArgsConstructor
public class AnalysisHistoryExcelController {

    private static final Logger logger = LoggerFactory.getLogger(AnalysisHistoryExcelController.class);

    private final AnalysisHistoryService analysisHistoryService;
    private final ExcelDownloadService excelDownloadService;

    /**
     * 분석이력 엑셀 다운로드 API
     */
    @Operation(summary = "분석이력 엑셀 다운로드", description = "현재 로그인한 사용자의 분석이력을 엑셀 파일로 다운로드합니다.")
    @GetMapping("/history/excel")
    public ResponseEntity<Resource> downloadAnalysisHistoryExcel(
            @RequestParam(defaultValue = "0") int offset,
            @RequestParam(defaultValue = "1000") int limit,
            @RequestParam(required = false) String analysisType,
            @RequestParam(required = false) String status,
            @RequestParam(defaultValue = "DESC") String sortOrder,
            Authentication authentication) {

        logger.info("분석이력 엑셀 다운로드 요청 - offset: {}, limit: {}, analysisType: {}, status: {}, sortOrder: {}",
                    offset, limit, analysisType, status, sortOrder);

        try {
            // 현재 접속한 사용자 ID 설정
            String currentUserId = "system";
            if (authentication != null) {
                LoginVO loginVO = (LoginVO) authentication.getPrincipal();
                currentUserId = loginVO.getUserId();
            }

            // 분석이력 조회 (필터 적용)
            List<AnlsHstryJoinVO> historyList = analysisHistoryService.getAnalysisHistory(
                currentUserId, offset, limit, analysisType, status, sortOrder);

            if (historyList == null || historyList.isEmpty()) {
                throw new RuntimeException("다운로드할 분석 이력 데이터가 없습니다.");
            }

            // VO를 Map으로 변환
            List<Map<String, Object>> data = convertToMapList(historyList);

            // 컬럼 맵 정의 (영문키 -> 한글헤더)
            Map<String, String> columnMap = createColumnMap();

            // 파일명 생성 (분석이력_YYYYMMDD_HHMMSS)
            String timestamp = java.time.LocalDateTime.now()
                    .format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
            String fileName = "분석이력_" + timestamp;

            // 엑셀 다운로드
            return excelDownloadService.downloadExcel(fileName, data, columnMap);
        } catch (IOException e) {
            logger.error("분석이력 엑셀 다운로드 실패", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }

    /**
     * VO를 Map 리스트로 변환
     */
    private List<Map<String, Object>> convertToMapList(List<AnlsHstryJoinVO> historyList) {
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        return historyList.stream()
                .map(vo -> {
                    Map<String, Object> map = new LinkedHashMap<>();
                    map.put("anlsHstryId", vo.getAnlsHstryId());
                    map.put("anlsKnd", vo.getAnlsKnd() != null ? getAnalysisKindKorean(vo.getAnlsKnd()) : "");
                    map.put("anlsSourcLyrNm", vo.getAnlsSourcLyrNm());
                    map.put("anlsBndryLyrNm", vo.getAnlsBndryLyrNm());
                    map.put("anlsStcd", vo.getAnlsStcd() != null ? getAnalysisStatusKorean(vo.getAnlsStcd()) : "");
                    map.put("anlsSttsMssage", vo.getAnlsSttsMssage());
                    map.put("dmndTm", vo.getDmndTm() != null ? vo.getDmndTm().format(dateFormatter) : "");
                    map.put("cmptnTm", vo.getCmptnTm() != null ? vo.getCmptnTm().format(dateFormatter) : "");
                    map.put("userLyrId", vo.getUserLyrId());
                    map.put("anlsOption", vo.getAnlsOption() != null ? vo.getAnlsOption() : "");
                    return map;
                })
                .collect(Collectors.toList());
    }

    /**
     * AnalysisKind 한글 변환
     */
    private String getAnalysisKindKorean(incheon.ags.mrb.analysis.domain.AnalysisKind kind) {
        switch (kind) {
            case AGGREGATE_POINTS: return "포인트 집계";
            case BUFFER: return "버퍼";
            case CLIP: return "클립";
            case CLUSTERING: return "클러스터링";
            case DENSITY: return "밀도 분석";
            case DISSOLVE: return "디졸브";
            case EXTRACT: return "추출";
            case HOTSPOT: return "핫스팟";
            case INTERSECT: return "교차";
            case MERGE: return "병합";
            case SUMMARIZE_NEARBY: return "주변 요약";
            case SUMMARIZE_WITHIN: return "범위 요약";
            case UNION: return "유니온";
            case JOIN_FEATURES: return "조인 피처";
            default: return kind.name();
        }
    }

    /**
     * AnalysisStatus 한글 변환
     */
    private String getAnalysisStatusKorean(incheon.ags.mrb.analysis.domain.AnalysisStatus status) {
        switch (status) {
            case PENDING: return "대기중";
            case RUNNING: return "실행중";
            case SUCCESS: return "성공";
            case FAILED: return "실패";
            case DELETED: return "삭제됨";
            default: return status.name();
        }
    }

    /**
     * 엑셀 컬럼 맵 생성 (영문 키 -> 한글 헤더)
     */
    private Map<String, String> createColumnMap() {
        Map<String, String> columnMap = new LinkedHashMap<>();
        columnMap.put("anlsHstryId", "이력 ID");
        columnMap.put("anlsKnd", "분석 종류");
        columnMap.put("anlsSourcLyrNm", "소스 레이어");
        columnMap.put("anlsBndryLyrNm", "경계 레이어");
        columnMap.put("anlsStcd", "상태");
        columnMap.put("anlsSttsMssage", "상태 메시지");
        columnMap.put("dmndTm", "시작 시간");
        columnMap.put("cmptnTm", "완료 시간");
        columnMap.put("userLyrId", "결과 레이어 ID");
        columnMap.put("anlsOption", "분석 옵션");
        return columnMap;
    }
}
