package gc.mda.signal_batch.monitoring.controller;

import gc.mda.signal_batch.migration.unix_timestamp.MissingDataFiller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * MIGRATION_V2: Unix timestamp 마이그레이션 관리 컨트롤러
 */
@Slf4j
@RestController
@RequestMapping("/api/migration")
@ConditionalOnProperty(name = "vessel.batch.scheduler.enabled", havingValue = "true", matchIfMissing = true)
@RequiredArgsConstructor
@Tag(name = "마이그레이션 API", description = "Unix timestamp 기반 항적 데이터 마이그레이션 및 누락 데이터 복구 API")
public class MigrationController {
    
    private final MissingDataFiller missingDataFiller;
    
    @PostMapping("/fill-hourly")
    @Operation(summary = "Hourly 누락 데이터 채우기", description = "지정된 시간의 누락된 Hourly 집계 데이터를 5분 데이터로부터 생성합니다")
    public ResponseEntity<Map<String, Object>> fillHourlyData(
            @Parameter(description = "대상 시간 (형식: yyyy-MM-dd HH:mm:ss)")
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime timeBucket) {
        
        try {
            int count = missingDataFiller.fillMissingHourlyData(timeBucket);
            
            return ResponseEntity.ok(Map.of(
                "status", "success",
                "message", String.format("Filled %d missing hourly records for %s", count, timeBucket),
                "count", count
            ));
        } catch (Exception e) {
            log.error("Failed to fill hourly data", e);
            return ResponseEntity.internalServerError().body(Map.of(
                "status", "error",
                "message", e.getMessage()
            ));
        }
    }
    
    @PostMapping("/fill-daily")
    @Operation(summary = "Daily 누락 데이터 채우기", description = "지정된 날짜의 누락된 Daily 집계 데이터를 Hourly 데이터로부터 생성합니다")
    public ResponseEntity<Map<String, Object>> fillDailyData(
            @Parameter(description = "대상 날짜 (형식: yyyy-MM-dd)")
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date) {
        
        try {
            int count = missingDataFiller.fillMissingDailyData(date.atStartOfDay());
            
            return ResponseEntity.ok(Map.of(
                "status", "success",
                "message", String.format("Filled %d missing daily records for %s", count, date),
                "count", count
            ));
        } catch (Exception e) {
            log.error("Failed to fill daily data", e);
            return ResponseEntity.internalServerError().body(Map.of(
                "status", "error",
                "message", e.getMessage()
            ));
        }
    }
    
    @GetMapping("/status")
    @Operation(summary = "마이그레이션 상태 조회", description = "지정된 날짜의 마이그레이션 상태를 조회합니다")
    public ResponseEntity<Map<String, Object>> getStatus(
            @Parameter(description = "대상 날짜 (형식: yyyy-MM-dd)")
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date) {
        
        String sql = """
            SELECT 
                '5min' as type,
                COUNT(*) as total,
                COUNT(track_geom) as v1_count,
                COUNT(track_geom_v2) as v2_count
            FROM signal.t_vessel_tracks_5min
            WHERE DATE(time_bucket) = ?
            """;
        
        // 상태 조회 로직
        return ResponseEntity.ok(Map.of(
            "status", "success",
            "date", date.toString()
        ));
    }
    
    /**
     * Unix timestamp 검증 및 자동 수정
     * - track_geom_v2가 비어있으면 채우기
     * - M값이 잘못되었으면(9시간 차이) 수정
     */
    @PostMapping("/fix-unix-timestamps")
    @Operation(summary = "Unix timestamp 검증 및 수정", description = "track_geom_v2가 비어있거나 M값이 잘못된 레코드를 자동으로 수정합니다")
    public ResponseEntity<Map<String, Object>> fixUnixTimestamps(
            @Parameter(description = "테이블 타입 (5min, hourly, daily)") @RequestParam String tableName,
            @Parameter(description = "시작 시간") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @Parameter(description = "종료 시간") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            @Parameter(description = "배치 크기") @RequestParam(defaultValue = "1000") int batchSize) {
        
        try {
            FixResult result = missingDataFiller.fixUnixTimestamps(tableName, startTime, endTime, batchSize);
            
            return ResponseEntity.ok(Map.of(
                "status", "success",
                "processed", result.processedCount,
                "filled", result.filledCount,
                "corrected", result.correctedCount,
                "skipped", result.skippedCount,
                "lastTimeBucket", result.lastTimeBucket != null ? result.lastTimeBucket.toString() : "none",
                "message", String.format("Processed %d time buckets: filled=%d, corrected=%d, skipped=%d",
                    result.processedCount, result.filledCount, result.correctedCount, result.skippedCount)
            ));
        } catch (Exception e) {
            log.error("Failed to fix unix timestamps", e);
            return ResponseEntity.internalServerError().body(Map.of(
                "status", "error",
                "message", e.getMessage()
            ));
        }
    }
    
    /**
     * Unix timestamp 검증 (수정 없이 확인만)
     */
    @GetMapping("/verify-unix-timestamps")
    @Operation(summary = "Unix timestamp 검증", description = "지정된 테이블과 시간의 Unix timestamp 정합성을 검증합니다 (수정 없음)")
    public ResponseEntity<Map<String, Object>> verifyUnixTimestamps(
            @Parameter(description = "테이블 타입 (5min, hourly, daily)") @RequestParam String tableName,
            @Parameter(description = "대상 시간") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime timeBucket) {
        
        try {
            VerifyResult result = missingDataFiller.verifyUnixTimestamps(tableName, timeBucket);
            
            return ResponseEntity.ok(Map.of(
                "status", "success",
                "tableName", tableName,
                "timeBucket", timeBucket.toString(),
                "totalRecords", result.totalRecords,
                "emptyV2", result.emptyV2Count,
                "correctV2", result.correctV2Count,
                "incorrectV2", result.incorrectV2Count,
                "samples", result.samples
            ));
        } catch (Exception e) {
            log.error("Failed to verify unix timestamps", e);
            return ResponseEntity.internalServerError().body(Map.of(
                "status", "error",
                "message", e.getMessage()
            ));
        }
    }
    
    public static class FixResult {
        public int processedCount;
        public int filledCount;
        public int correctedCount;
        public int skippedCount;
        public int createdBuckets;
        public LocalDateTime lastTimeBucket;
    }
    
    public static class VerifyResult {
        public int totalRecords;
        public int emptyV2Count;
        public int correctV2Count;
        public int incorrectV2Count;
        public Map<String, Object>[] samples;
    }
}