package com.ruoyi.excel.wecom.service;

import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.excel.wecom.mapper.CustomerExportDataMapper;
import com.ruoyi.excel.wecom.vo.CustomerExportDataVO;
import com.ruoyi.system.service.ISysExportTaskService;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Date;
import java.util.List;

/**
 * 客户数据异步导出服务
 */
@Service
public class CustomerExportAsyncService
{
    private static final Logger log = LoggerFactory.getLogger(CustomerExportAsyncService.class);

    private static final int BATCH_SIZE = 5000;
    private static final int ROW_ACCESS_WINDOW = 1000;

    @Autowired
    private CustomerExportDataMapper customerExportDataMapper;

    @Autowired
    private ISysExportTaskService exportTaskService;

    @Async("threadPoolTaskExecutor")
    public void executeExport(Long taskId, String corpId, Date startDate, Date endDate, String customerName)
    {
        log.info("开始执行异步导出任务，taskId: {}, corpId: {}", taskId, corpId);
        String filePath = null;
        String fileName = null;
        File file = null;
        SXSSFWorkbook workbook = null;
        FileOutputStream fos = null;

        try
        {
            int totalCount = customerExportDataMapper.countCustomerExportDataVOList(corpId, startDate, endDate, customerName);
            log.info("导出任务 taskId: {}, 总数据量: {}", taskId, totalCount);

            if (totalCount == 0)
            {
                exportTaskService.markSuccess(taskId, "", "无数据.xlsx", 0L);
                return;
            }

            exportTaskService.updateProgress(taskId, 0, totalCount);

            String dateStr = DateUtils.dateTimeNow("yyyyMMddHHmmss");
            fileName = "客户统计数据_" + dateStr + ".xlsx";
            String downloadPath = RuoYiConfig.getDownloadPath();
            File dir = new File(downloadPath);
            if (!dir.exists())
            {
                dir.mkdirs();
            }
            filePath = downloadPath + fileName;
            file = new File(filePath);

            workbook = new SXSSFWorkbook(ROW_ACCESS_WINDOW);
            Sheet sheet = workbook.createSheet("客户统计数据");

            CellStyle headerStyle = createHeaderStyle(workbook);
            CellStyle dataStyle = createDataStyle(workbook);

            String[] headers = {
                "客户名称", "描述", "添加人", "添加人账号", "添加人所属部门", "添加时间", "来源",
                "手机", "企业", "邮箱", "地址", "职务", "电话",
                "标签组1(投放)", "标签组2(公司孵化)", "标签组3(商务)", "标签组4(成交日期)", "标签组5(年级组)",
                "标签组6(客户属性)", "标签组7(成交)", "标签组8(成交品牌)", "标签组9(线索通标签)", "标签组10(A1组)",
                "标签组11(B1组)", "标签组12(C1组)", "标签组13(D1组)", "标签组14(E1组)", "标签组15(意向度)",
                "标签组16(自然流)", "标签组17(F1组)", "标签组18(G1组)"
            };

            Row headerRow = sheet.createRow(0);
            for (int i = 0; i < headers.length; i++)
            {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
                sheet.setColumnWidth(i, 20 * 256);
            }

            int processedCount = 0;
            int rowIndex = 1;
            int offset = 0;

            while (offset < totalCount)
            {
                List<CustomerExportDataVO> dataList = customerExportDataMapper.selectCustomerExportDataVOListByPage(
                        corpId, startDate, endDate, customerName, offset, BATCH_SIZE);

                if (dataList == null || dataList.isEmpty())
                {
                    break;
                }

                for (CustomerExportDataVO data : dataList)
                {
                    Row row = sheet.createRow(rowIndex++);
                    fillRowData(row, data, dataStyle);
                    processedCount++;
                }

                offset += BATCH_SIZE;

                exportTaskService.updateProgress(taskId, processedCount, totalCount);
            }

            fos = new FileOutputStream(file);
            workbook.write(fos);
            fos.flush();

            long fileSize = file.length();
            exportTaskService.markSuccess(taskId, filePath, fileName, fileSize);
            log.info("导出任务完成，taskId: {}, 文件: {}, 大小: {} bytes", taskId, fileName, fileSize);
        }
        catch (Exception e)
        {
            log.error("导出任务执行失败，taskId: {}", taskId, e);
            exportTaskService.markFailed(taskId, "导出失败：" + e.getMessage());
        }
        finally
        {
            try
            {
                if (fos != null)
                {
                    fos.close();
                }
                if (workbook != null)
                {
                    workbook.dispose();
                    workbook.close();
                }
            }
            catch (Exception e)
            {
                log.error("关闭资源失败", e);
            }
        }
    }

    private CellStyle createHeaderStyle(Workbook workbook)
    {
        CellStyle style = workbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        style.setBorderRight(BorderStyle.THIN);
        style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderLeft(BorderStyle.THIN);
        style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderTop(BorderStyle.THIN);
        style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderBottom(BorderStyle.THIN);
        style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        Font font = workbook.createFont();
        font.setBold(true);
        font.setFontName("Arial");
        font.setFontHeightInPoints((short) 10);
        style.setFont(font);
        return style;
    }

    private CellStyle createDataStyle(Workbook workbook)
    {
        CellStyle style = workbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setBorderRight(BorderStyle.THIN);
        style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderLeft(BorderStyle.THIN);
        style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderTop(BorderStyle.THIN);
        style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderBottom(BorderStyle.THIN);
        style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        Font font = workbook.createFont();
        font.setFontName("Arial");
        font.setFontHeightInPoints((short) 10);
        style.setFont(font);
        return style;
    }

    private void fillRowData(Row row, CustomerExportDataVO data, CellStyle style)
    {
        int col = 0;
        createCell(row, col++, data.getCustomerName(), style);
        createCell(row, col++, data.getDescription(), style);
        createCell(row, col++, data.getAddUserName(), style);
        createCell(row, col++, data.getAddUserAccount(), style);
        createCell(row, col++, data.getAddUserDepartment(), style);
        createCell(row, col++, formatDate(data.getAddTime()), style);
        createCell(row, col++, data.getSource(), style);
        createCell(row, col++, data.getMobile(), style);
        createCell(row, col++, data.getCompany(), style);
        createCell(row, col++, data.getEmail(), style);
        createCell(row, col++, data.getAddress(), style);
        createCell(row, col++, data.getPosition(), style);
        createCell(row, col++, data.getPhone(), style);
        createCell(row, col++, data.getTagGroup1(), style);
        createCell(row, col++, data.getTagGroup2(), style);
        createCell(row, col++, data.getTagGroup3(), style);
        createCell(row, col++, data.getTagGroup4(), style);
        createCell(row, col++, data.getTagGroup5(), style);
        createCell(row, col++, data.getTagGroup6(), style);
        createCell(row, col++, data.getTagGroup7(), style);
        createCell(row, col++, data.getTagGroup8(), style);
        createCell(row, col++, data.getTagGroup9(), style);
        createCell(row, col++, data.getTagGroup10(), style);
        createCell(row, col++, data.getTagGroup11(), style);
        createCell(row, col++, data.getTagGroup12(), style);
        createCell(row, col++, data.getTagGroup13(), style);
        createCell(row, col++, data.getTagGroup14(), style);
        createCell(row, col++, data.getTagGroup15(), style);
        createCell(row, col++, data.getTagGroup16(), style);
        createCell(row, col++, data.getTagGroup17(), style);
        createCell(row, col++, data.getTagGroup18(), style);
    }

    private void createCell(Row row, int column, String value, CellStyle style)
    {
        Cell cell = row.createCell(column);
        cell.setCellValue(value == null ? "" : value);
        cell.setCellStyle(style);
    }

    private String formatDate(Date date)
    {
        if (date == null)
        {
            return "";
        }
        return DateUtils.parseDateToStr("yyyy-MM-dd", date);
    }
}
