package com.ruoyi.ccdi.project.service.impl;

import com.ruoyi.ccdi.project.domain.excel.CcdiProjectAbnormalAccountExcel;
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectEmployeeCreditNegativeExcel;
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectUnsubmittedAccountFlowExcel;
import com.ruoyi.common.utils.file.FileUtils;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

/**
 * 风险明细工作簿导出器
 */
@Component
public class CcdiProjectRiskDetailWorkbookExporter {

    private static final String CONTENT_TYPE =
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

    public void export(
        HttpServletResponse response,
        Long projectId,
        List<CcdiProjectSuspiciousTransactionExcel> suspiciousRows,
        List<CcdiProjectEmployeeCreditNegativeExcel> creditRows,
        List<CcdiProjectAbnormalAccountExcel> abnormalRows,
        List<CcdiProjectUnsubmittedAccountFlowExcel> unsubmittedRows
    ) throws IOException {
        response.setContentType(CONTENT_TYPE);
        FileUtils.setAttachmentResponseHeader(response, "风险明细_" + projectId + ".xlsx");

        try (Workbook workbook = new XSSFWorkbook()) {
            writeSuspiciousSheet(workbook.createSheet("涉疑交易明细"), suspiciousRows);
            writeCreditSheet(workbook.createSheet("员工负面征信信息"), creditRows);
            writeAbnormalAccountSheet(workbook.createSheet("异常账户人员信息"), abnormalRows);
            writeUnsubmittedAccountSheet(workbook.createSheet("未提交账户流水"), unsubmittedRows);
            workbook.write(response.getOutputStream());
        }
    }

    private void writeSuspiciousSheet(Sheet sheet, List<CcdiProjectSuspiciousTransactionExcel> rows) {
        Row header = sheet.createRow(0);
        String[] headers = {
            "交易时间",
            "本方账户",
            "本方主体",
            "对方名称",
            "对方账户",
            "关联员工",
            "摘要",
            "交易类型",
            "交易金额",
            "异常标签"
        };
        writeHeader(header, headers);

        for (int i = 0; i < rows.size(); i++) {
            CcdiProjectSuspiciousTransactionExcel item = rows.get(i);
            Row row = sheet.createRow(i + 1);
            row.createCell(0).setCellValue(safeText(item.getTrxDate()));
            row.createCell(1).setCellValue(safeText(item.getLeAccountNo()));
            row.createCell(2).setCellValue(safeText(item.getLeAccountName()));
            row.createCell(3).setCellValue(safeText(item.getCustomerAccountName()));
            row.createCell(4).setCellValue(safeText(item.getCustomerAccountNo()));
            row.createCell(5).setCellValue(safeText(item.getRelatedStaffDisplay()));
            row.createCell(6).setCellValue(safeText(item.getUserMemo()));
            row.createCell(7).setCellValue(safeText(item.getCashType()));
            row.createCell(8).setCellValue(safeNumber(item.getDisplayAmount()));
            row.createCell(9).setCellValue(safeText(item.getHitTags()));
        }
    }

    private void writeCreditSheet(Sheet sheet, List<CcdiProjectEmployeeCreditNegativeExcel> rows) {
        Row header = sheet.createRow(0);
        String[] headers = {
            "员工姓名",
            "身份证号",
            "最近征信查询日期",
            "民事案件笔数",
            "民事案件金额",
            "强制执行笔数",
            "强制执行金额",
            "行政处罚笔数",
            "行政处罚金额"
        };
        writeHeader(header, headers);

        for (int i = 0; i < rows.size(); i++) {
            CcdiProjectEmployeeCreditNegativeExcel item = rows.get(i);
            Row row = sheet.createRow(i + 1);
            row.createCell(0).setCellValue(safeText(item.getPersonName()));
            row.createCell(1).setCellValue(safeText(item.getPersonId()));
            row.createCell(2).setCellValue(safeText(item.getQueryDate()));
            row.createCell(3).setCellValue(item.getCivilCnt() == null ? 0 : item.getCivilCnt());
            row.createCell(4).setCellValue(safeNumber(item.getCivilLmt()));
            row.createCell(5).setCellValue(item.getEnforceCnt() == null ? 0 : item.getEnforceCnt());
            row.createCell(6).setCellValue(safeNumber(item.getEnforceLmt()));
            row.createCell(7).setCellValue(item.getAdmCnt() == null ? 0 : item.getAdmCnt());
            row.createCell(8).setCellValue(safeNumber(item.getAdmLmt()));
        }
    }

    private void writeAbnormalAccountSheet(Sheet sheet, List<CcdiProjectAbnormalAccountExcel> rows) {
        Row header = sheet.createRow(0);
        String[] headers = { "账号", "开户人", "银行", "异常类型", "异常发生时间", "状态", "命中原因", "涉及金额" };
        writeHeader(header, headers);

        for (int i = 0; i < rows.size(); i++) {
            CcdiProjectAbnormalAccountExcel item = rows.get(i);
            Row row = sheet.createRow(i + 1);
            row.createCell(0).setCellValue(safeText(item.getAccountNo()));
            row.createCell(1).setCellValue(safeText(item.getAccountName()));
            row.createCell(2).setCellValue(safeText(item.getBankName()));
            row.createCell(3).setCellValue(safeText(item.getAbnormalType()));
            row.createCell(4).setCellValue(safeText(item.getAbnormalTime()));
            row.createCell(5).setCellValue(safeText(item.getStatus()));
            row.createCell(6).setCellValue(safeText(item.getReasonDetail()));
            row.createCell(7).setCellValue(safeNumber(item.getInvolvedAmount()));
        }
    }

    private void writeUnsubmittedAccountSheet(Sheet sheet, List<CcdiProjectUnsubmittedAccountFlowExcel> rows) {
        Row header = sheet.createRow(0);
        String[] headers = {
            "主体名称",
            "未提交账号",
            "交易时间",
            "本方账号",
            "本方主体",
            "对方名称",
            "对方账号",
            "摘要",
            "交易类型",
            "流入金额",
            "流出金额"
        };
        writeHeader(header, headers);

        for (int i = 0; i < rows.size(); i++) {
            CcdiProjectUnsubmittedAccountFlowExcel item = rows.get(i);
            Row row = sheet.createRow(i + 1);
            row.createCell(0).setCellValue(safeText(item.getSubjectName()));
            row.createCell(1).setCellValue(safeText(item.getAccountNo()));
            row.createCell(2).setCellValue(safeText(item.getTrxDate()));
            row.createCell(3).setCellValue(safeText(item.getLeAccountNo()));
            row.createCell(4).setCellValue(safeText(item.getLeAccountName()));
            row.createCell(5).setCellValue(safeText(item.getCustomerAccountName()));
            row.createCell(6).setCellValue(safeText(item.getCustomerAccountNo()));
            row.createCell(7).setCellValue(safeText(item.getUserMemo()));
            row.createCell(8).setCellValue(safeText(item.getCashType()));
            row.createCell(9).setCellValue(safeNumber(item.getAmountCr()));
            row.createCell(10).setCellValue(safeNumber(item.getAmountDr()));
        }
    }

    private void writeHeader(Row row, String[] headers) {
        for (int i = 0; i < headers.length; i++) {
            row.createCell(i).setCellValue(headers[i]);
        }
    }

    private String safeText(String value) {
        return value == null ? "" : value;
    }

    private double safeNumber(BigDecimal value) {
        return value == null ? 0D : value.doubleValue();
    }
}
