package com.nanri.aiimage.modules.dedupe.controller;

import com.nanri.aiimage.common.api.ApiResponse;
import com.nanri.aiimage.modules.dedupe.model.dto.DedupeRunRequest;
import com.nanri.aiimage.modules.dedupe.model.vo.DedupeHistoryVo;
import com.nanri.aiimage.modules.dedupe.model.vo.DedupeRunVo;
import com.nanri.aiimage.modules.dedupe.service.DedupeRunService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/dedupe")
@Tag(name = "数据去重", description = "按照旧 Python 桌面端规则执行列保留和 ID 过滤。桌面端交互不变，只将处理逻辑迁到 Java。")
public class DedupeRunController {

    private final DedupeRunService dedupeRunService;

    @PostMapping("/run")
    @Operation(
            summary = "执行数据去重",
            description = """
                    根据上传文件、保留列、ID 保留规则执行数据去重，生成清洗后的 Excel 结果文件。

                    规则与旧 Python 桌面端保持一致：
                    - 表头会先做文本清洗；
                    - 遇到“缩略图地址8”停止继续识别表头；
                    - 仅保留 selectedColumns 中指定的列；
                    - keepIntegerIds=true 时保留纯数字 ID；
                    - keepUnderscoreIds=true 时保留类似 1_1 的 ID；
                    - keepIntegerMainIdsWhenNoSubIds=true 且文件中不存在 1_1 这类子 ID 时，会自动保留纯数字主 ID；
                    - 整理后的数据会再按 ASIN 与去重总数据表比对，命中的行不会出现在最终输出文件；
                    - 上传文件内如果存在重复 ASIN，只保留第一次出现的那一行；
                    - 输出文件命名遵循 原文件名_cleaned.xlsx，若重名自动追加序号。
                    """)
    @ApiResponses({
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "执行成功，返回处理统计与结果列表", content = @Content(schema = @Schema(implementation = DedupeRunVo.class))),
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数不合法或缺少必要字段"),
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "执行数据去重失败")
    })
    public ApiResponse<DedupeRunVo> run(@Valid @RequestBody DedupeRunRequest request) {
        return ApiResponse.success(dedupeRunService.run(request));
    }

    @GetMapping("/history")
    @Operation(summary = "查询去重历史", description = "查询当前用户最近的去重成功记录，用于页面右侧历史下载列表展示。")
    @ApiResponses({
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功", content = @Content(schema = @Schema(implementation = DedupeHistoryVo.class)))
    })
    public ApiResponse<DedupeHistoryVo> history(
            @Parameter(name = "user_id", description = "当前登录用户 ID", required = true, in = ParameterIn.QUERY)
            @RequestParam("user_id") Long userId) {
        DedupeHistoryVo vo = new DedupeHistoryVo();
        vo.setItems(dedupeRunService.listHistory(userId));
        return ApiResponse.success(vo);
    }

    @DeleteMapping("/history/{resultId}")
    @Operation(summary = "删除去重历史", description = "删除当前用户的一条去重历史记录。")
    @ApiResponses({
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功"),
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "结果记录不存在")
    })
    public ApiResponse<Void> deleteHistory(
            @Parameter(description = "去重结果记录 ID", required = true) @PathVariable Long resultId,
            @Parameter(name = "user_id", description = "当前登录用户 ID", required = true, in = ParameterIn.QUERY)
            @RequestParam("user_id") Long userId) {
        dedupeRunService.deleteHistory(resultId, userId);
        return ApiResponse.success(null);
    }

    @GetMapping("/results/{resultId}/download")
    @Operation(summary = "下载数据去重结果", description = "根据结果记录 ID 下载当前用户的清洗后 Excel 文件。")
    @ApiResponses({
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "返回结果文件流"),
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "结果文件不存在")
    })
    public ResponseEntity<Resource> download(
            @Parameter(description = "去重结果记录 ID", required = true) @PathVariable Long resultId,
            @Parameter(name = "user_id", description = "当前登录用户 ID", required = true, in = ParameterIn.QUERY)
            @RequestParam("user_id") Long userId) {
        Resource resource = dedupeRunService.getResultFile(resultId, userId);
        return ResponseEntity.ok()
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment")
                .body(resource);
    }
}
