package com.ga.api.controller.upload;

import com.ga.api.service.upload.TargetFieldMetaService;
import com.ga.api.service.upload.TargetFieldMetaService.TargetFieldMeta;
import com.ga.api.service.upload.UploadResultResp;
import com.ga.api.service.upload.UploadService;
import com.ga.api.service.upload.UploadService.ExcelHeaderResp;
import com.ga.common.annotation.RequirePermission;
import com.ga.common.model.ApiResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.Max;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;

@Tag(name = "엑셀 업로드")
@Validated
@RestController
@RequiredArgsConstructor
public class UploadController {

    private final UploadService uploadService;
    private final TargetFieldMetaService metaService;

    @Operation(summary = "엑셀 업로드 처리",
               description = "templateCode 에 해당하는 템플릿으로 파일을 파싱 · 변환 · 배치 INSERT 한다.")
    @PostMapping("/api/upload/{templateCode}")
    @RequirePermission(menu = "SYSTEM_UPLOAD_TEMPLATE", perm = "CREATE")
    public ApiResponse<UploadResultResp> upload(@PathVariable String templateCode,
                                                @RequestParam("file") MultipartFile file) {
        UploadResultResp result = uploadService.processUpload(templateCode, file);
        return ApiResponse.ok(result);
    }

    @Operation(summary = "업로드 미리보기 (상위 5행)",
               description = "DB 에 저장하지 않고 변환 결과만 반환한다.")
    @PostMapping("/api/upload-templates/{templateCode}/preview")
    @RequirePermission(menu = "SYSTEM_UPLOAD_TEMPLATE", perm = "READ")
    public ApiResponse<List<Map<String, Object>>> preview(
            @PathVariable String templateCode,
            @RequestParam("file") MultipartFile file,
            @Max(100) @RequestParam(value = "limit", defaultValue = "5") int limit) {
        List<Map<String, Object>> rows = uploadService.preview(templateCode, file, limit);
        return ApiResponse.ok(rows);
    }

    @Operation(summary = "샘플 엑셀 헤더 추출",
               description = "템플릿 등록 전에 샘플 파일 첫 행 헤더 + 미리보기 행을 추출한다. " +
                             "프론트는 이 결과로 sourceColumn(A,B,C..) + sourceHeader 를 자동 채운다.")
    @PostMapping("/api/upload-templates/excel-headers")
    @RequirePermission(menu = "SYSTEM_UPLOAD_TEMPLATE", perm = "READ")
    public ApiResponse<ExcelHeaderResp> extractHeaders(
            @RequestParam("file") MultipartFile file,
            @RequestParam(value = "headerRow",   defaultValue = "1") int headerRow,
            @RequestParam(value = "sheetIndex",  defaultValue = "0") int sheetIndex,
            @RequestParam(value = "previewRows", defaultValue = "5") int previewRows) {
        return ApiResponse.ok(uploadService.extractHeaders(file, headerRow, sheetIndex, previewRows));
    }

    @Operation(summary = "target_table 별 사용 가능한 컬럼 메타",
               description = "프론트의 target_field Select 옵션 + 타입 자동 채우기에 사용한다.")
    @GetMapping("/api/upload-templates/target-fields/{targetTable}")
    @RequirePermission(menu = "SYSTEM_UPLOAD_TEMPLATE", perm = "READ")
    public ApiResponse<List<TargetFieldMeta>> targetFields(@PathVariable String targetTable) {
        return ApiResponse.ok(metaService.getFields(targetTable));
    }

    @Operation(summary = "사용 가능한 target_table 목록")
    @GetMapping("/api/upload-templates/target-tables")
    @RequirePermission(menu = "SYSTEM_UPLOAD_TEMPLATE", perm = "READ")
    public ApiResponse<List<String>> targetTables() {
        return ApiResponse.ok(metaService.getAvailableTables());
    }
}
