package com.artfess.cqxy.ledger.manager.impl;

import com.artfess.base.feign.UCFeignService;
import com.artfess.base.query.*;
import com.artfess.base.util.StringUtil;
import com.artfess.cqxy.contract.manager.ContractManager;
import com.artfess.cqxy.contract.model.Contract;
import com.artfess.cqxy.ledger.manager.ContractLedgerManager;
import com.artfess.cqxy.ledger.vo.ContractKeeperVo;
import com.artfess.cqxy.ledger.vo.ContractLedgerVo;
import com.artfess.cqxy.processManagermant.manager.ProgressManageManager;
import com.artfess.cqxy.processManagermant.model.ProgressManage;
import com.artfess.cqxy.projectManagement.dao.ProjectManagementDao;
import com.artfess.cqxy.projectManagement.manager.ProjectManagementManager;
import com.artfess.cqxy.projectManagement.manager.ProjectPersonnelManager;
import com.artfess.cqxy.projectManagement.model.ProjectManagement;
import com.artfess.cqxy.utils.BizUtils;
import com.artfess.poi.util.ExcelUtil;
import com.artfess.sysConfig.persistence.manager.SysDictionaryManager;
import com.artfess.sysConfig.persistence.param.DictModel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @author Limuhua
 * @date 2022/3/18 10:49
 */
@Service
public class ContractLedgerManagerImpl implements ContractLedgerManager {

    @Autowired
    private ProjectManagementManager projectManager;
    @Autowired
    private SysDictionaryManager sdm;
    @Autowired
    ContractManager contractManager;
    @Autowired
    private ProjectPersonnelManager projectPersonnelManager;

    @Autowired
    private UCFeignService ucFeignService;

    @Autowired
    private ProjectManagementDao projectManagementDao;

    @Autowired
    private ProgressManageManager progressManageManager;

    @Override
    public Map<String, Object> queryByPage(QueryFilter<Contract> queryFilter) {
        // 获取字典
        List<DictModel> bidType = sdm.queryDictListItemsByCode("zbfs");
//        List<DictModel> contractType = sdm.queryDictListItemsByCode("htgl-htlb");
        queryFilter.withSorter(new FieldSort("pm.PROJECT_TYPE_", Direction.ASC));
        queryFilter.withSorter(new FieldSort("bc.PROJECT_ID_", Direction.ASC));
        if (BizUtils.isProjectIdFields(queryFilter.getQuerys())) {
            List<String> projectList = BizUtils.handProjectAuthByUser(ucFeignService, projectPersonnelManager, projectManagementDao);
            if (null != projectList && projectList.size() > 0) {
                queryFilter.addFilter("bc.PROJECT_ID_", projectList, QueryOP.IN);
            }
        }
        // 处理数据
        PageList<Contract> contract = contractManager.queryContractByPage(queryFilter);
        List<Contract> contractList = null == contract.getRows() ? new ArrayList<>() : contract.getRows();
        List<ContractLedgerVo> data = new ArrayList<>();
        for (Contract ele : contractList) {
            ContractLedgerVo temp = ContractLedgerVo.contractToVo(ele, bidType);

            ProjectManagement project = projectManager.getOne(new QueryWrapper<ProjectManagement>().eq("ID_", ele.getProjectId()).eq("IS_DELE_", "0"));
            temp.setAgent(project.getProjectManager());
            temp.setProjectName(project.getProjectName());
            temp.setProjectCode(project.getProjectCode());
            QueryWrapper queryWrapper = new QueryWrapper<ProgressManage>();
            queryWrapper.eq("contract_id_", ele.getId());
            queryWrapper.select(" IFNULL( max(AMOUNT_APPROPRIATED_),0) as maxAmount");
            Map<String, BigDecimal> map = progressManageManager.getMap(queryWrapper);
            DecimalFormat df1 = new DecimalFormat("#.##");
            BigDecimal amountAppropriated = map.get("maxAmount");
            if (df1.format(amountAppropriated).equals("0")) {
                temp.setAmountAppropriated("-");
            } else {
                temp.setAmountAppropriated(df1.format(amountAppropriated));
            }
            if(StringUtils.isEmpty(ele.getContractReceiver())){
                ele.setContractReceiver(project.getProjectManager());
            }

            if (temp.getContractAmount() == null || temp.getContractAmount().trim().isEmpty()) {
                temp.setRemainingAmount("-");
                temp.setRatioAmount("0.00%");

            } else {
                if(StringUtils.isNotBlank(temp.getContractAmount()) ){
                    BigDecimal bigDecimal = new BigDecimal(temp.getContractAmount());
                    if(bigDecimal.compareTo(BigDecimal.ZERO) == 0 ){
                        temp.setRemainingAmount("0.00");
                    }else {
                        temp.setRemainingAmount(df1.format(bigDecimal.subtract(amountAppropriated)));
                    }

                }else {
                    temp.setRemainingAmount("0.00");
                }

                if(StringUtils.isNotBlank(temp.getContractAmount())){
                    BigDecimal bigDecimal = new BigDecimal(temp.getContractAmount());
                    if(bigDecimal.compareTo(BigDecimal.ZERO) == 0 ){
                        temp.setRatioAmount("0.00%");
                    }else {
                        DecimalFormat df = new DecimalFormat("0.00%");
                        String ratio = df.format(amountAppropriated.divide(bigDecimal, 4, BigDecimal.ROUND_HALF_UP));
                        temp.setRatioAmount(ratio);
                    }

                }else {
                    temp.setRatioAmount("0.00%");
                }

            }


            data.add(temp);
        }
        // 封装结果
        Map<String, Object> result = new HashMap<>(4);
        result.put("data", data);
        result.put("total", contract.getTotal());
        result.put("page", contract.getPage());
        result.put("pageSize", contract.getPageSize());
        return result;
    }

    @Override
    public void exportDataToExcel(QueryFilter<Contract> queryFilter, HttpServletResponse response) throws IOException {
        // 文件名
        String fileName = "";
        for (QueryField qf : queryFilter.getQuerys()) {
            if (StringUtil.equals("bc.CONTRACT_NUMBER_", qf.getProperty().trim())) {
                fileName += qf.getValue() + "年";
            }
        }
        queryFilter.getPageBean().setPageSize(-1);
        fileName += "合同管理台账";
        // 获取数据
        queryFilter.withSorter(new FieldSort("PROJECT_TYPE_", Direction.ASC));
        Map<String, List<ContractLedgerVo>> data = classifyData((List<ContractLedgerVo>) queryByPage(queryFilter).get("data"));
        // 创建excel工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();

        // 合同编号说明 表
        HSSFSheet numberExplanation = workbook.createSheet("合同编号说明");
        String[] numberData = {"01 G-工程类%房建、市政道路、维修施工合同及补充协议%（20**）建设工程*号",
                "02 J-技术咨询类%招标代理、造价咨询、监理、施工图设计审查、设计、勘察合同等%（20**）建设技术*号",
                "03 F-服务类%管理服务、道路联建、监测钻井、管网监测合同%（20**）建设服务*号",
                "04 C-采购类%%（20**）建设采购*号",
                "05 P-配套类%大、小配套合同%（20**）建设配套*号",
                "06 O-其他% % "};
        for (int i = 0; i < numberData.length; i++) {
            HSSFRow numberTitie = numberExplanation.createRow(i);
            String[] rowData = numberData[i].split("[%]");
            for (int t = 0; t < rowData.length; t++) {
                BizUtils.handelCell(workbook, "合同编号说明", numberTitie.createCell(t), rowData[t]);
            }
        }
        HSSFSheet NoSheet = workbook.getSheet("合同编号说明");
        NoSheet.setColumnWidth(0, 5000);
        NoSheet.setColumnWidth(1, 8000);
        NoSheet.setColumnWidth(2, 7000);

        // 工程类合同表
        String GSheetName = "G-工程类合同";
        HSSFSheet GSheet = initSheet(workbook, GSheetName, "西永公司工程项目" + GSheetName.split("-")[1] + "执行台账");
        fillDataToSheet(workbook, GSheetName, data.get("G"));

        // 技术类合同表
        String JSheetName = "J-技术类合同";
        HSSFSheet JSheet = initSheet(workbook, JSheetName, "西永公司工程项目" + JSheetName.split("-")[1] + "执行台账");
        fillDataToSheet(workbook, JSheetName, data.get("J"));

        // 服务类合同表
        String FSheetName = "F-服务类合同";
        HSSFSheet FSheet = initSheet(workbook, FSheetName, "西永公司工程项目" + FSheetName.split("-")[1] + "执行台账");
        fillDataToSheet(workbook, FSheetName, data.get("F"));

        // 采购类合同表
        String CSheetName = "C-采购类合同";
        HSSFSheet CSheet = initSheet(workbook, CSheetName, "西永公司工程项目" + CSheetName.split("-")[1] + "执行台账");
        fillDataToSheet(workbook, CSheetName, data.get("C"));

        // 配套类合同表
        String PSheetName = "P-配套类合同";
        HSSFSheet PSheet = initSheet(workbook, PSheetName, "西永公司工程项目" + PSheetName.split("-")[1] + "执行台账");
        fillDataToSheet(workbook, PSheetName, data.get("P"));

        // 其它合同表
        String OSheetName = "O-其他合同";
        HSSFSheet OSheet = initSheet(workbook, OSheetName, "西永公司工程项目" + OSheetName.split("-")[1] + "执行台账");
        fillDataToSheet(workbook, OSheetName, data.get("O"));

        ExcelUtil.downloadExcel(workbook, fileName, response);
    }

    @Override
    public void updateContractReceiverById(ContractKeeperVo contractKeeperVo) {
        String contractReceiver = contractKeeperVo.getContractReceiver();
        String id = contractKeeperVo.getId();
        UpdateWrapper<Contract>   updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("CONTRACT_RECEIVER_", contractReceiver).eq("ID_", id);
        contractManager.update(updateWrapper);
    }

    /**
     * 将数据分类
     *
     * @param data 数据
     * @return 已经分好类的数据
     */
    private Map<String, List<ContractLedgerVo>> classifyData(List<ContractLedgerVo> data) {
        Map<String, List<ContractLedgerVo>> result = new HashMap<>(5);
        if (null == data) {
            return result;
        }
        // 变量命名对应台账sheet前缀
        List<ContractLedgerVo> G = new ArrayList<>();
        List<ContractLedgerVo> J = new ArrayList<>();
        List<ContractLedgerVo> F = new ArrayList<>();
        List<ContractLedgerVo> C = new ArrayList<>();
        List<ContractLedgerVo> P = new ArrayList<>();
        List<ContractLedgerVo> O = new ArrayList<>();// 其他
        for (ContractLedgerVo ele : data) {
            String type = ele.getContractNumber();
            if (StringUtils.isNotBlank(type) && type.contains("建设工程")) {
                G.add(ele);
            } else if (StringUtils.isNotBlank(type) && type.contains("建设技术")) {
                J.add(ele);
            } else if (StringUtils.isNotBlank(type) && type.contains("建设服务")) {
                F.add(ele);
            } else if (StringUtils.isNotBlank(type) && type.contains("建设采购")) {
                C.add(ele);
            } else if (StringUtils.isNotBlank(type) && type.contains("建设配套")) {
                P.add(ele);
            } else {
                O.add(ele);
            }
        }
        result.put("G", G);
        result.put("J", J);
        result.put("F", F);
        result.put("C", C);
        result.put("P", P);
        result.put("O", O);
        return result;
    }

    /**
     * 初始化sheet表
     *
     * @param workbook  工作簿
     * @param sheetName sheet表名
     * @return 初始化完成的Sheet对象
     */
    private HSSFSheet initSheet(HSSFWorkbook workbook, String sheetName, String titile) {
        HSSFSheet sheet = workbook.createSheet(sheetName);
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        //设置字体
        HSSFFont font = workbook.createFont();
        //设置字体名称
        font.setFontName("宋体");
        // 表头数据
        String[] heards = {"序号", "合同编号", "二级分类", "招标方式", "决策文件", "合同类别", "合同涉及事项", "我方主体",
                "其他相对方主体", "合同签订时间", "合同约定完成时间", "投资总金额（万元）", "已支付金额（万元）", "剩余金额（万元）", "已支付比例", "合同履行异常记录", "合同执行进度",
                "项目负责人", "留存份数", "备注", "合同存放处", "合同保管人", "合同经办人"};
        // 标题行
        HSSFRow tiele = sheet.createRow(0);
        BizUtils.handelCell(workbook, cellStyle, font, sheetName, tiele.createCell(0), titile, true);

        // 创建标题行并写入数据
        HSSFRow titleRow1 = sheet.createRow(1);

        for (int i = 0; i < heards.length; i++) {
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, titleRow1.createCell(i), heards[i]);
        }
        // 合并单元格
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 22));


        return sheet;
    }

    private void fillDataToSheet(HSSFWorkbook workbook, String sheetName, List<ContractLedgerVo> data) {
        // 获取数据表
        HSSFSheet sheet = workbook.getSheet(sheetName);
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        //设置字体
        HSSFFont font = workbook.createFont();
        //设置字体名称
        font.setFontName("宋体");
        cellStyle.setFont(font);


        // 处理数据
        for (int i = 0; i < data.size(); i++) {
            // 数据行,从2行开始,共data.size行
            HSSFRow listRow = sheet.createRow(i + 2);
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(0), String.valueOf(i + 1));
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(1), StringUtils.isEmpty(data.get(i).getContractNumber()) ? "无" : data.get(i).getContractNumber());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(2), StringUtils.isEmpty(data.get(i).getSecondLevelType()) ? "无" : data.get(i).getSecondLevelType());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(3), StringUtils.isEmpty(data.get(i).getBiddingChargeType()) ? "无" : data.get(i).getBiddingChargeType());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(4), StringUtils.isEmpty(data.get(i).getDecisionDocuments()) ? "无" : data.get(i).getDecisionDocuments());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(5), StringUtils.isEmpty(data.get(i).getType()) ? "无" : data.get(i).getType());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(6), StringUtils.isEmpty(data.get(i).getName()) ? "无" : data.get(i).getName());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(7), StringUtils.isEmpty(data.get(i).getOurPart()) ? "无" : data.get(i).getOurPart());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(8), StringUtils.isEmpty(data.get(i).getOtherPart()) ? "无" : data.get(i).getOtherPart());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(9), StringUtils.isEmpty(data.get(i).getContractDate()) ? "无" : data.get(i).getContractDate());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(10), StringUtils.isEmpty(data.get(i).getEndDate()) ? "无" : data.get(i).getEndDate());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(11), StringUtils.isEmpty(data.get(i).getContractAmount()) ? "无" : data.get(i).getContractAmount());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(12), StringUtils.isEmpty(data.get(i).getAmountAppropriated()) ? "无" : data.get(i).getAmountAppropriated());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(13), StringUtils.isEmpty(data.get(i).getRemainingAmount()) ? "无" : data.get(i).getRemainingAmount());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(14), StringUtils.isEmpty(data.get(i).getRatioAmount()) ? "无" : data.get(i).getRatioAmount());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(15), StringUtils.isEmpty(data.get(i).getContractExceptionLog()) ? "无" : data.get(i).getContractExceptionLog());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(16), StringUtils.isEmpty(data.get(i).getContractSchedule()) ? "无" : data.get(i).getContractSchedule());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(17), StringUtils.isEmpty(data.get(i).getAgent()) ? "无" : data.get(i).getAgent());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(18), StringUtils.isEmpty(data.get(i).getContractCopsNum().toString()) ? "无" : data.get(i).getContractCopsNum().toString());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(19), StringUtils.isEmpty(data.get(i).getEstablishmentRemarks()) ? "无" : data.get(i).getEstablishmentRemarks());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(20), StringUtils.isEmpty(data.get(i).getContractStorage()) ? "无" : data.get(i).getContractStorage());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(21), StringUtils.isEmpty(data.get(i).getContractKeeper()) ? "无" : data.get(i).getContractKeeper());
            BizUtils.handelCell(workbook, cellStyle, font, sheetName, listRow.createCell(22), StringUtils.isEmpty(data.get(i).getContractReceiver()) ? "无" : data.get(i).getContractReceiver());
        }
        sheet.setColumnWidth(0, 2000);
        sheet.setColumnWidth(1, 4000);
        sheet.setColumnWidth(2, 2000);
        sheet.setColumnWidth(3, 4000);
        sheet.setColumnWidth(4, 3000);
        sheet.setColumnWidth(5, 4000);
        sheet.setColumnWidth(6, 6000);
        sheet.setColumnWidth(7, 6000);
        sheet.setColumnWidth(8, 4000);
        sheet.setColumnWidth(9, 4000);
        sheet.setColumnWidth(10, 4000);
        sheet.setColumnWidth(11, 4000);
        sheet.setColumnWidth(12, 4000);
        sheet.setColumnWidth(13, 4000);
        sheet.setColumnWidth(14, 4000);
        sheet.setColumnWidth(15, 4000);
        sheet.setColumnWidth(16, 4000);
        sheet.setColumnWidth(17, 4000);
        sheet.setColumnWidth(18, 3000);
        sheet.setColumnWidth(19, 3000);
        sheet.setColumnWidth(20, 3000);
        sheet.setColumnWidth(21, 3000);
        sheet.setColumnWidth(22, 3000);
    }

}
