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

import com.nanri.aiimage.common.api.ApiResponse;
import com.nanri.aiimage.modules.convert.model.dto.ConvertRunRequest;
import com.nanri.aiimage.modules.convert.model.vo.ConvertHistoryVo;
import com.nanri.aiimage.modules.convert.model.vo.ConvertRunVo;
import com.nanri.aiimage.modules.convert.service.ConvertRunService;
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.FileSystemResource;
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;

import java.io.File;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/convert")
@Tag(name = "格式转换执行", description = "负责根据已上传文件和模板执行格式转换，并返回结果下载地址。当前先打通接口链路，下一步再把旧 Python 的模板生成逻辑完整迁移到 Java。")
public class ConvertRunController {

    private final ConvertRunService convertRunService;

    @PostMapping("/run")
    @Operation(
            summary = "执行格式转换",
            description = """
                    使用上传接口返回的 fileKey 和选中的模板执行格式转换。

                    当前已按旧 Python 桌面端规则迁移以下逻辑：
                    - required_source_columns 缺失校验；
                    - preamble_lines 输出；
                    - header_columns 输出；
                    - blank_header_rows_after_schema 空白行补齐；
                    - field_mapping 字段映射；
                    - defaults 默认值填充；
                    - ASIN 为空的行跳过；
                    - sku 按 时间戳-序号 生成。

                    输出文件名遵循模板配置的 outputFilename，若临时目录中重名则自动追加序号。
                    """)
    @ApiResponses({
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "执行成功，返回转换结果统计", content = @Content(schema = @Schema(implementation = ConvertRunVo.class))),
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数不合法或模板不存在"),
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "执行格式转换失败")
    })
    public ApiResponse<ConvertRunVo> run(@Valid @RequestBody ConvertRunRequest request) {
        return ApiResponse.success(convertRunService.run(request));
    }

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

    @GetMapping("/results/{resultId}/download")
    @Operation(summary = "下载格式转换结果", description = "根据结果记录 ID 下载当前用户的转换结果文件。桌面端前端可继续通过 save_file_from_url 选择保存位置。")
    @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) {
        File resultFile = convertRunService.getResultFile(resultId, userId);
        String encodedFilename = URLEncoder.encode(resultFile.getName(), StandardCharsets.UTF_8).replaceAll("\\+", "%20");
        return ResponseEntity.ok()
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encodedFilename)
                .body(new FileSystemResource(resultFile));
    }
}
