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

import com.nanri.aiimage.common.api.ApiResponse;
import com.nanri.aiimage.modules.deletebrand.model.dto.DeleteBrandRunRequest;
import com.nanri.aiimage.modules.deletebrand.model.dto.DeleteBrandSubmitResultRequest;
import com.nanri.aiimage.modules.deletebrand.model.dto.DeleteBrandTaskBatchRequest;
import com.nanri.aiimage.modules.deletebrand.model.vo.DeleteBrandHistoryVo;
import com.nanri.aiimage.modules.deletebrand.model.vo.DeleteBrandRunVo;
import com.nanri.aiimage.modules.deletebrand.model.vo.DeleteBrandTaskBatchVo;
import com.nanri.aiimage.modules.deletebrand.model.vo.DeleteBrandTaskDeletionStatusVo;
import com.nanri.aiimage.modules.deletebrand.service.DeleteBrandRunService;
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.http.HttpHeaders;
import org.springframework.http.HttpStatus;
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 org.springframework.web.server.ResponseStatusException;

import java.io.InputStream;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;


@RestController
@RequiredArgsConstructor
@RequestMapping("/api/delete-brand")
@Tag(name = "删除品牌", description = "解析固定格式 Excel 的删除ASIN数据（暂不联动紫鸟）。")
public class DeleteBrandRunController {

    private final DeleteBrandRunService deleteBrandRunService;

    @PostMapping("/run")
    @Operation(summary = "执行删除品牌解析", description = "读取上传的删除品牌 Excel，按国家分组解析并在每个国家内按 ASIN 去重，返回完整 payload。")
    @ApiResponses({
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "执行成功", content = @Content(schema = @Schema(implementation = DeleteBrandRunVo.class)))
    })
    public ApiResponse<DeleteBrandRunVo> run(@Valid @RequestBody DeleteBrandRunRequest request) {
        return ApiResponse.success(deleteBrandRunService.run(request));
    }

    @GetMapping("/history")
    @Operation(summary = "查询删除品牌历史", description = "按 user_id 查询删除品牌历史。")
    public ApiResponse<DeleteBrandHistoryVo> history(
            @Parameter(name = "user_id", description = "当前登录用户 ID", required = true, in = ParameterIn.QUERY)
            @RequestParam("user_id") Long userId) {
        return ApiResponse.success(deleteBrandRunService.listHistory(userId));
    }

    @DeleteMapping("/history/{resultId}")
    @Operation(summary = "删除删除品牌历史", description = "按 user_id 删除一条删除品牌历史。")
    public ApiResponse<Void> deleteHistory(
            @PathVariable Long resultId,
            @Parameter(name = "user_id", description = "当前登录用户 ID", required = true, in = ParameterIn.QUERY)
            @RequestParam("user_id") Long userId) {
        deleteBrandRunService.deleteHistory(resultId, userId);
        return ApiResponse.success(null);
    }

    @GetMapping("/tasks/{taskId}")
    @Operation(summary = "获取删除品牌任务详情", description = "根据任务ID返回任务基础信息 + Redis 中的实时行级进度（文件/国家/ASIN）。")
    public ApiResponse<com.nanri.aiimage.modules.deletebrand.model.vo.DeleteBrandTaskDetailVo> getTask(
            @PathVariable Long taskId) {
        return ApiResponse.success(deleteBrandRunService.getTaskDetail(taskId));
    }

    @PostMapping("/tasks/batch")
    @Operation(summary = "批量获取删除品牌任务详情", description = "合并多个 taskId 的详情查询，减少轮询期对 DB/Redis 的压力。")
    public ApiResponse<DeleteBrandTaskBatchVo> getTasksBatch(@Valid @RequestBody DeleteBrandTaskBatchRequest request) {
        return ApiResponse.success(deleteBrandRunService.getTaskDetails(request.getTaskIds()));
    }

    @GetMapping("/tasks/{taskId}/deletion-status")
    @Operation(summary = "获取删除品牌任务删除状态", description = "供 Python/插件按 taskId 查询该删除品牌任务是否已被前端删空。")
    public ApiResponse<DeleteBrandTaskDeletionStatusVo> getTaskDeletionStatus(
            @PathVariable Long taskId,
            @Parameter(name = "user_id", description = "当前登录用户 ID", required = true, in = ParameterIn.QUERY)
            @RequestParam("user_id") Long userId) {
        return ApiResponse.success(deleteBrandRunService.getTaskDeletionStatus(taskId, userId));
    }

    @PostMapping("/tasks/{taskId}/result")
    @Operation(summary = "提交删除品牌处理结果", description = "插件/前端分片回传处理结果；后端累计分片并推进进度，全部完成后再执行最终组装与落库。")
    public ApiResponse<Void> submitResult(
            @PathVariable Long taskId,
            @Valid @RequestBody DeleteBrandSubmitResultRequest request) {
        deleteBrandRunService.submitResult(taskId, request);
        return ApiResponse.success(null);
    }

    @GetMapping("/tasks/{taskId}/download")
    @Operation(summary = "下载删除品牌任务结果", description = "返回任务结果文件流，便于桌面端通过 save_file_from_url 直接保存。")
    public void download(@PathVariable Long taskId, jakarta.servlet.http.HttpServletResponse response) {
        String url = deleteBrandRunService.resolveTaskDownloadUrl(taskId);
        String filename = deleteBrandRunService.resolveTaskDownloadFilename(taskId);
        if (url == null || url.isBlank()) {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND, "任务无可下载结果");
        }
        if (filename == null || filename.isBlank()) {
            String rawPath = URI.create(url).getPath();
            filename = rawPath == null ? "delete-brand_" + taskId + ".xlsx" : rawPath.substring(rawPath.lastIndexOf('/') + 1);
        }

        try {
            String encodedFilename = URLEncoder.encode(filename, StandardCharsets.UTF_8).replace("+", "%20");
            response.setContentType("application/octet-stream");
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
                    "attachment; filename=\"" + filename + "\"; filename*=UTF-8''" + encodedFilename);
            try (InputStream in = URI.create(url).toURL().openStream()) {
                byte[] buffer = new byte[65536];
                int read;
                while ((read = in.read(buffer)) != -1) {
                    response.getOutputStream().write(buffer, 0, read);
                }
                response.getOutputStream().flush();
            }
        } catch (Exception ex) {
            throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "下载失败");
        }
    }
}
