package com.ecep.contract.controller.customer;

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

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDate;
import java.util.Comparator;
import java.util.List;

import com.ecep.contract.service.*;
import com.ecep.contract.util.CompanyUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;
import com.ecep.contract.util.ProxyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.ecep.contract.CompanyCustomerFileType;
import com.ecep.contract.SpringApp;
import com.ecep.contract.model.CloudTyc;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyCustomer;
import com.ecep.contract.model.CompanyCustomerEvaluationFormFile;
import com.ecep.contract.model.CompanyCustomerFile;

import javafx.concurrent.Task;
import lombok.Setter;

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

    @Setter
    private CompanyCustomer customer;
    @Setter
    private CompanyService companyService;
    private CompanyContactService companyContactService;

    private CompanyCustomerService companyCustomerService;
    @Setter
    private CompanyCustomerFileService companyCustomerFileService;

    private CompanyService getCompanyService() {
        if (companyService == null) {
            companyService = SpringApp.getBean(CompanyService.class);
        }
        return companyService;
    }

    private CompanyCustomerService getCompanyCustomerService() {
        if (companyCustomerService == null) {
            companyCustomerService = SpringApp.getBean(CompanyCustomerService.class);
        }
        return companyCustomerService;
    }

    private CompanyContactService getCompanyContactService() {
        if (companyContactService == null) {
            companyContactService = SpringApp.getBean(CompanyContactService.class);
        }
        return companyContactService;
    }

    private CompanyCustomerFileService getCompanyCustomerFileService() {
        if (companyCustomerFileService == null) {
            companyCustomerFileService = SpringApp.getBean(CompanyCustomerFileService.class);
        }
        return companyCustomerFileService;
    }

    @Override
    protected Object call() throws Exception {
        try {
            updateEvaluationForm();
        } catch (Exception ex) {
            updateMessage(ex.getMessage());
        }
        return null;
    }

    private File getEvaluationFormTemplate() {
        return getCompanyCustomerFileService().getEvaluationFormTemplate();
    }

    public void updateEvaluationForm() {
        if (!StringUtils.hasText(customer.getPath())) {
            updateMessage("供应商目录未设置，请先设置供应商目录");
            return;
        }
        File template = getEvaluationFormTemplate();
        if (template == null) {
            updateMessage("评价表模板文件未设置，请先设置评价表模板文件");
            return;
        }
        if (!template.exists()) {
            updateMessage("评价表模板文件 " + template.getAbsolutePath() + " 不存在，请检查");
            return;
        }

        File dir = new File(customer.getPath());
        String template_file_name = template.getName();
        File destFile = new File(dir, template_file_name);

        if (destFile.exists()) {
            updateMessage("表单文件已经存在，" + destFile.getName());
            try (
                    InputStream inp = new FileInputStream(destFile);
                    Workbook wb = WorkbookFactory.create(inp)) {
                updateEvaluationForm(wb, destFile);
                updateMessage("评价表已更新");
            } catch (Exception e) {
                updateMessage(e.getMessage());
                logger.error(e.getMessage(), e);
            }
        } else {
            updateMessage("根据模板 " + template_file_name + " 创建表单 " + destFile.getName());
            try (
                    InputStream inp = new FileInputStream(template);
                    Workbook wb = WorkbookFactory.create(inp)) {
                updateEvaluationForm(wb, destFile);
                updateMessage("评价表已创建");
                CompanyCustomerFile customerFile = new CompanyCustomerFile();
                customerFile.setCustomer(customer);
                customerFile.setFilePath(destFile.getAbsolutePath());
                customerFile.setType(CompanyCustomerFileType.General);
                save(customerFile);
            } catch (Exception e) {
                updateMessage(e.getMessage());
                logger.error(e.getMessage(), e);
            }
        }
        updateProgress(1, 1);
    }

    private void save(CompanyCustomerFile customerFile) {
        getCompanyCustomerFileService().save(customerFile);
    }

    /**
     * 更新客户评估表，依据模板创建，如果已经存在生成的文件，则更新评估表
     *
     * @param wb       work book
     * @param destFile 目标文件
     */
    public void updateEvaluationForm(
            Workbook wb, File destFile) throws IOException {
        Company company = customer.getCompany();
        if (!ProxyUtils.isInitialized(company)) {
            company = getCompanyService().findById(company.getId());
            customer.setCompany(company);
        }

        Sheet sheet = wb.getSheetAt(0);
        updateSheet(company, sheet);
        // 输出到文件
        try (OutputStream fileOut = new FileOutputStream(destFile)) {
            wb.write(fileOut);

        } catch (FileNotFoundException e) {
            updateMessage("写评估表时发生文件错误，请检查评估表是否被打开中");
            updateMessage(e.getMessage());
            logger.error(e.getMessage(), e);
        }
    }

    private void updateSheet(Company company, Sheet sheet) {
        setCellValue(sheet, "B3", "客户编号：" + CompanyUtils.formatCompanyVendorId(customer.getId()));
        setCellValue(sheet, "B4", "客户名称：" + company.getName());

        LocalDate suggestDate = getCompanyCustomerFileService().getNextSignDate(customer, (level, msg) -> {
            updateMessage(" - " + msg);
        });
        if (suggestDate == null) {
            suggestDate = LocalDate.now();
        }
        setCellValue(sheet, "H3", "评定时间：" + suggestDate);
        setCellValue(sheet, "H4", "统一社会信用代码：");
        setCellValue(sheet, "H5", company.getUniscid());
        // 注册所属地
        setCellValue(sheet, "B5", "注册所属地：" + company.getDistrict());
        // 经营状态
        setCellValue(sheet, "D6", "经营状态：" + company.getEntStatus());
        // 成立日期
        setCellValue(sheet, "H6", "成立日期：" + company.getSetupDate());
        // 所属行业
        setCellValue(sheet, "D7", "所属行业：" + company.getIndustry());
        setCellValue(sheet, "D8",
                "注册资金：" + company.getRegisteredCapital() + " " + company.getRegisteredCapitalCurrency());
        // 企业类型
        setCellValue(sheet, "H10", "企业类型：" + company.getEntType());
        // 天眼评分
        CloudTycService cloudTycService = SpringApp.getBean(CloudTycService.class);
        CloudTyc cloudTyc = cloudTycService.getOrCreateCloudTyc(company);
        setCellValue(sheet, "D10", "天眼评分：" + (cloudTyc.getScore() > 0 ? cloudTyc.getScore() : ""));

        // 检索评估表
        List<CompanyCustomerEvaluationFormFile> evaluationFormFiles = getCompanyCustomerFileService()
                .findAllCustomerEvaluationFormFiles(customer);
        List<CompanyCustomerEvaluationFormFile> filteredList = evaluationFormFiles.stream()
                .filter(v -> {
                    CompanyCustomerFile file = v.getCustomerFile();
                    return file.getSignDate() != null && file.isValid();
                })
                .sorted(Comparator.comparing(v -> v.getCustomerFile().getSignDate()))
                .toList();

        if (filteredList.isEmpty()) {
            setCellValue(sheet, "C40", "首次评价");
            try {
                sheet.addMergedRegion(CellRangeAddress.valueOf("C40:K40"));
            } catch (Exception ignored) {
            }
        } else {
            setCellValue(sheet, "C40", "评价日期");
            try {
                sheet.addMergedRegion(CellRangeAddress.valueOf("C40:D40"));
            } catch (Exception ignored) {
            }
            setCellValue(sheet, "E40", "经济指标");
            setCellValue(sheet, "F40", "综合指标");
            setCellValue(sheet, "G40", "资信等级");
            String[] CreditLevelTitles = new String[] { "-", "差★", " 一般★★", " 较好★★★", " 好★★★★", " " };
            int baseRow = 40;
            for (CompanyCustomerEvaluationFormFile form : filteredList) {
                CompanyCustomerFile customerFile = form.getCustomerFile();
                setCellValue(sheet, baseRow, 2, String.valueOf(customerFile.getSignDate()));
                setCellValue(sheet, baseRow, 4, form.getCatalog());
                setCellValue(sheet, baseRow, 5, form.getLevel());
                if (form.getCreditLevel() == null) {
                    setCellValue(sheet, baseRow, 6, "-");
                } else {
                    setCellValue(sheet, baseRow, 6, CreditLevelTitles[form.getCreditLevel()]);
                }
                try {
                    sheet.addMergedRegion(new CellRangeAddress(baseRow, baseRow, 2, 3));
                } catch (Exception ignored) {
                }
                baseRow++;
            }
        }
    }
}
