package com.ruoyi.ccdi.project.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.ccdi.project.domain.dto.CcdiFileUploadQueryDTO;
import com.ruoyi.ccdi.project.domain.dto.CcdiPullBankInfoSubmitDTO;
import com.ruoyi.ccdi.project.domain.entity.CcdiFileUploadRecord;
import com.ruoyi.ccdi.project.domain.vo.CcdiFileUploadStatisticsVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiIdCardParseVO;
import com.ruoyi.ccdi.project.service.CcdiProjectAccessService;
import com.ruoyi.ccdi.project.service.ICcdiFileUploadService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.lsfx.constants.LsfxConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.concurrent.RejectedExecutionException;

/**
 * 文件上传 Controller
 *
 * @author ruoyi
 * @date 2026-03-05
 */
@Slf4j
@RestController
@RequestMapping("/ccdi/file-upload")
@Tag(name = "文件上传管理", description = "项目文件上传相关接口")
public class CcdiFileUploadController extends BaseController {

    @Resource
    private ICcdiFileUploadService fileUploadService;

    @Resource
    private CcdiProjectAccessService projectAccessService;

    /**
     * 批量上传文件（异步）
     */
    @PostMapping("/batch")
    @Operation(summary = "批量上传文件", description = "异步批量上传流水文件")
    @PreAuthorize("@ss.hasPermi('ccdi:project:edit')")
    public AjaxResult batchUpload(@RequestParam Long projectId,
                                    @RequestParam MultipartFile[] files) {
        // 参数校验
        if (projectId == null) {
            return AjaxResult.error("项目ID不能为空");
        }
        projectAccessService.assertCanOperate(projectId);
        if (files == null || files.length == 0) {
            return AjaxResult.error("请选择要上传的文件");
        }
        if (files.length > 100) {
            return AjaxResult.error("单次最多上传100个文件");
        }

        // 校验文件数量、空文件和大小，文件名业务规则统一在 Service 层处理
        for (MultipartFile file : files) {
            if (file.isEmpty()) {
                return AjaxResult.error("文件不能为空");
            }
            if (file.getSize() > 50 * 1024 * 1024) {
                return AjaxResult.error("文件 " + file.getOriginalFilename() + " 超过50MB限制");
            }
        }

        try {
            String username = SecurityUtils.getUsername();
            String batchId = fileUploadService.batchUploadFiles(projectId, files, username);
            return AjaxResult.success("上传任务已提交", batchId);
        } catch (RejectedExecutionException e) {
            log.warn("线程池已满，拒绝上传请求: projectId={}, fileCount={}", projectId, files.length);
            return AjaxResult.error("系统繁忙，请稍后再试");
        } catch (Exception e) {
            log.error("批量上传失败: projectId={}", projectId, e);
            return AjaxResult.error("上传失败：" + e.getMessage());
        }
    }

    /**
     * 解析身份证文件
     */
    @PostMapping("/parse-id-card-file")
    @Operation(summary = "解析身份证文件", description = "解析首个sheet第一列的身份证号")
    @PreAuthorize("@ss.hasPermi('ccdi:project:edit')")
    public AjaxResult parseIdCardFile(@RequestParam MultipartFile file) {
        if (file == null || file.isEmpty()) {
            return AjaxResult.error("身份证文件不能为空");
        }
        List<String> idCards = fileUploadService.parseIdCardFile(file);
        return AjaxResult.success("解析成功", new CcdiIdCardParseVO(idCards, idCards.size()));
    }

    /**
     * 提交拉取行内/金综流水任务
     */
    @PostMapping("/pull-bank-info")
    @Operation(summary = "拉取行内/金综流水", description = "按证件号码批量提交拉取行内/金综流水任务")
    @PreAuthorize("@ss.hasPermi('ccdi:project:edit')")
    public AjaxResult pullBankInfo(@RequestBody CcdiPullBankInfoSubmitDTO dto) {
        if (dto == null || dto.getProjectId() == null) {
            return AjaxResult.error("项目ID不能为空");
        }
        projectAccessService.assertCanOperate(dto.getProjectId());
        if (CollectionUtils.isEmpty(dto.getIdCards())) {
            return AjaxResult.error("身份证号不能为空");
        }
        if (!StringUtils.hasText(dto.getDataChannelCode())) {
            return AjaxResult.error("流水来源不能为空");
        }
        String dataChannelCode = dto.getDataChannelCode().trim().toUpperCase();
        if (!LsfxConstants.DATA_CHANNEL_ZJRCU.equals(dataChannelCode)
            && !LsfxConstants.DATA_CHANNEL_JZL.equals(dataChannelCode)) {
            return AjaxResult.error("流水来源不支持");
        }
        if (LsfxConstants.DATA_CHANNEL_ZJRCU.equals(dataChannelCode)
            && (!StringUtils.hasText(dto.getStartDate()) || !StringUtils.hasText(dto.getEndDate()))) {
            return AjaxResult.error("开始日期和结束日期不能为空");
        }

        Long userId = SecurityUtils.getUserId();
        String username = SecurityUtils.getUsername();
        String batchId = fileUploadService.submitPullBankInfo(
            dto.getProjectId(),
            dto.getIdCards(),
            dataChannelCode,
            dto.getStartDate(),
            dto.getEndDate(),
            userId,
            username
        );
        return AjaxResult.success("拉取任务已提交", batchId);
    }

    /**
     * 查询上传记录列表
     */
    @GetMapping("/list")
    @Operation(summary = "查询上传记录列表", description = "分页查询文件上传记录")
    public TableDataInfo list(CcdiFileUploadQueryDTO queryDTO) {
        projectAccessService.assertCanRead(queryDTO.getProjectId());
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Page<CcdiFileUploadRecord> page = new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize());
        Page<CcdiFileUploadRecord> result = fileUploadService.selectPage(page, queryDTO);
        return getDataTable(result.getRecords(), result.getTotal());
    }

    /**
     * 查询上传统计
     */
    @GetMapping("/statistics/{projectId}")
    @Operation(summary = "查询上传统计", description = "统计各状态的文件数量")
    public AjaxResult getStatistics(@PathVariable Long projectId) {
        projectAccessService.assertCanRead(projectId);
        CcdiFileUploadStatisticsVO statistics = fileUploadService.countByStatus(projectId);
        return AjaxResult.success(statistics);
    }

    /**
     * 查询记录详情
     */
    @GetMapping("/detail/{id}")
    @Operation(summary = "查询记录详情", description = "根据ID查询文件上传记录详情")
    public AjaxResult getDetail(@PathVariable Long id) {
        projectAccessService.assertCanReadByFileRecordId(id);
        CcdiFileUploadRecord record = fileUploadService.getById(id);
        return AjaxResult.success(record);
    }

    /**
     * 删除上传记录
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除上传文件", description = "按上传记录ID删除文件并清理流水")
    @PreAuthorize("@ss.hasPermi('ccdi:project:edit')")
    public AjaxResult deleteFile(@PathVariable Long id) {
        projectAccessService.assertCanOperateByFileRecordId(id);
        Long userId = SecurityUtils.getUserId();
        String message = fileUploadService.deleteFileUploadRecord(id, userId);
        return AjaxResult.success(message);
    }
}
