package com.ecep.contract.controller.customer;

import com.ecep.contract.MessageHolder;
import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.model.*;
import com.ecep.contract.service.CompanyCustomerEntityService;
import com.ecep.contract.service.CompanyCustomerFileService;
import com.ecep.contract.service.CompanyCustomerService;
import com.ecep.contract.task.Tasker;
import com.ecep.contract.util.UITools;
import lombok.Setter;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFTable;
import com.ecep.contract.util.ProxyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Pageable;
import org.springframework.util.StringUtils;

import java.io.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;

import static com.ecep.contract.util.ExcelUtils.*;

public class CompanyCustomerExportExcelTasker extends Tasker<Object> {
    private static final Logger logger = LoggerFactory.getLogger(CompanyCustomerExportExcelTasker.class);

    @Setter
    File destFile;

    CompanyCustomerService customerService;
    CompanyCustomerEntityService customerEntityService;
    CompanyCustomerFileService customerFileService;

    CompanyCustomerService getCustomerService() {
        if (customerService == null)
            customerService = getBean(CompanyCustomerService.class);
        return customerService;
    }

    CompanyCustomerFileService getCustomerFileService() {
        if (customerFileService == null)
            customerFileService = getBean(CompanyCustomerFileService.class);
        return customerFileService;
    }

    CompanyCustomerEntityService getCustomerEntityService() {
        if (customerEntityService == null)
            customerEntityService = getBean(CompanyCustomerEntityService.class);
        return customerEntityService;
    }

    @Override
    protected Object execute(MessageHolder holder) throws Exception {
        if (destFile.exists()) {
            holder.warn("文件已存在, 输出将覆盖文件...");
        }
        String path = getConfService().getString("customer.evaluation.book.template");
        if (!StringUtils.hasText(path)) {
            holder.error("模板文件未设置，模板文件");
            return null;
        }
        File template = new File(path);
        if (!template.exists()) {
            holder.warn("模板文件 " + template.getAbsolutePath() + " 不存在，请检查");
            return null;
        }
        try (
                InputStream inp = new FileInputStream(template);
                Workbook wb = WorkbookFactory.create(inp);) {
            String sheetName = "客户资信台账";
            Sheet sheet = null;
            for (int i = 0; i < wb.getNumberOfSheets(); i++) {
                Sheet s = wb.getSheetAt(i);
                if (s.getSheetName().contains(sheetName)) {
                    sheet = s;
                    break;
                }
            }
            if (sheet == null) {
                holder.error("找不到" + sheetName + "Sheet");
                return null;
            }

            setCellValue(sheet, "H2", "年度：" + LocalDate.now().getYear());

            setCellValue(sheet, "A19", "Build by CMS @ " + MyDateTimeUtils.format(LocalDateTime.now()));

            int rowIndex = 0;
            for (CompanyCustomer customer : getCustomerService().findAll(null, Pageable.unpaged())) {
                Company company = customer.getCompany();
                if (company == null) {
                    holder.warn("客户 #" + customer.getId() + " 不存在对应公司");
                    continue;
                }
                if (!ProxyUtils.isInitialized(company)) {
                    company = getCompanyService().findById(company.getId());
                }

                LocalDate devDate = null;
                List<CompanyCustomerEntity> entities = getCustomerEntityService().findAllByCustomer(customer);
                for (CompanyCustomerEntity entity : entities) {
                    if (devDate == null || devDate.isAfter(entity.getDevelopDate())) {
                        devDate = entity.getDevelopDate();
                    }
                }

                CompanyCustomerEvaluationFormFile evaluationFormFile = getCustomerFileService()
                        .findAllCustomerEvaluationFormFiles(customer).stream().filter(v -> {
                            CompanyCustomerFile customerFile = v.getCustomerFile();
                            if (customerFile == null) {
                                return false;
                            }
                            return customerFile.isValid();
                        }).max(Comparator.comparing(v -> v.getCustomerFile().getSignDate())).orElse(null);

                if (evaluationFormFile == null) {
                    holder.warn(company.getName() + " 未匹配的客户评估");
                    continue;
                }

                CompanyCustomerFile customerFile = evaluationFormFile.getCustomerFile();
                if (devDate != null && devDate.isAfter(customerFile.getSignDate())) {
                    holder.debug(company.getName() + " 最新评估日期早于客户开发日期，评估日期：" + customerFile.getSignDate() + ", 开发日期："
                            + devDate);
                }

                rowIndex++;

                if (rowIndex > 11) {
                    // 插入行，并复制行的格式
                    sheet.shiftRows(rowIndex + 3, sheet.getLastRowNum(), 1);
                    Row templateRow = getRow(sheet, rowIndex + 2, true);
                    Row newRow = getRow(sheet, rowIndex + 3, true);
                    if (templateRow != null && newRow != null) {
                        for (int i = 0; i < templateRow.getLastCellNum(); i++) {
                            Cell templateCell = templateRow.getCell(i);
                            Cell newCell = getCell(newRow, i, true);
                            if (templateCell != null && newCell != null) {
                                newCell.setCellStyle(templateCell.getCellStyle());
                            }
                        }
                    }
                }

                Row row = getRow(sheet, rowIndex + 3, true);

                setCellValue(row, 0, rowIndex);
                setCellValue(row, 1, company.getName());
                // 客户类型
                setCellValue(row, 2, evaluationFormFile.getCatalog());
                setCellValue(row, 3, devDate);
                setCellValue(row, 4, "无");
                setCellValue(row, 5, "无");
                setCellValue(row, 6, evaluationFormFile.getCreditLevel());

                setCellValue(row, 7, "更新 " + customerFile.getSignDate());
            }

            for (XSSFTable table : ((XSSFSheet) sheet).getTables()) {
                if ("表2".equals(table.getName())) {
                    holder.info("找到表=" + table.getName() + ", style=" + table.getStyleName());
                    table.setCellReferences(
                            new AreaReference("$A$4:$H$" + (rowIndex + 4), SpreadsheetVersion.EXCEL2007));

                    // table.setDataRowCount(rowIndex);
                    // table.getCTTable().setRef("$A$4:$H$" + (rowIndex + 4));
                }
            }

            wb.setPrintArea(wb.getSheetIndex(sheet), "A1:H" + (rowIndex + 7));
            PrintSetup printSetup = sheet.getPrintSetup();
            printSetup.setPaperSize(PrintSetup.A4_PAPERSIZE); // A4 纸
            printSetup.setFitHeight((short) 0);
            printSetup.setFitWidth((short) 1); // 调整为 1 页宽

            sheet.setFitToPage(true);
            sheet.setRepeatingRows(CellRangeAddress.valueOf("$1:$4"));
            sheet.getFooter().setCenter("第 &P 页, 共 &N 页");
            sheet.getFooter().setRight("&D &T");

            try (OutputStream fileOut = new FileOutputStream(destFile)) {
                wb.write(fileOut);
            } catch (FileNotFoundException e) {
                UITools.showExceptionAndWait("写时发生文件错误", e);
            }
        } catch (Exception e) {
            UITools.showExceptionAndWait("保存失败", e);
        }

        return null;
    }
}
