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

import com.artfess.base.query.*;
import com.artfess.base.util.BeanUtils;
import com.artfess.base.util.DateUtils;
import com.artfess.cqxy.bidManagement.manager.BiddingManagementManager;
import com.artfess.cqxy.bidManagement.model.BiddingManagement;
import com.artfess.cqxy.constructionPermit.manager.ConstructionPermitManager;
import com.artfess.cqxy.constructionPermit.model.ConstructionPermit;
import com.artfess.cqxy.contract.manager.ContractManager;
import com.artfess.cqxy.ledger.manager.ProjectLedgerManager;
import com.artfess.cqxy.ledger.vo.ProjectLedgerVo;
import com.artfess.cqxy.projectApproval.manager.DecisionBasisManager;
import com.artfess.cqxy.projectApproval.model.DecisionBasis;
import com.artfess.cqxy.projectManagement.manager.ProjectManagementManager;
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.toolkit.Wrappers;
import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
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.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author Limuhua
 * @date 2022/3/15 15:33
 */
@Service
public class ProjectLedgerManagerImpl implements ProjectLedgerManager {

    @Autowired
    private SysDictionaryManager sdm;
    @Autowired
    private ProjectManagementManager pmm;
    @Autowired
    private DecisionBasisManager dbm;
    @Autowired
    private BiddingManagementManager bmm;

    @Autowired
    private ContractManager contractManager;

    @Autowired
    private ConstructionPermitManager constructionPermitManager;

    @Override
    public List<Map<String, String>> getCollect(QueryFilter<ProjectManagement> queryFilter) {
        // 获取所有数据
        if(null == queryFilter){
            queryFilter = QueryFilter.build();
        }
//        queryFilter.withSorter(new FieldSort("PROJECT_TYPE_", Direction.ASC));
        List<FieldSort> sorter = queryFilter.getSorter();
        if(null != sorter && sorter.size() > 0){
            sorter.clear();
        }
        queryFilter.addFilter("PARENT_ID_","root", QueryOP.EQUAL);
        //-------------------- old ---------------------------------------------
//        queryFilter.setPageBean(new PageBean(1,-1,true));
//        List<ProjectLedgerVo> data = (List<ProjectLedgerVo>) getDataByPage(queryFilter).get("data");
        // 获取类型统计，将其封装成约定格式
//        Map<String, String> type = collectType(data);
//        List<Map<String, String>> result = new ArrayList<>(type.size());
//        for(String key : type.keySet()){
//            Map<String, String> temp = new HashMap<>(3);
//            String t = type.get(key);
//            String[] typeData = t.split("[：]");
//            temp.put("value", key);
//            temp.put("name",typeData[0]);
//            temp.put("total",typeData[1]);
//            result.add(temp);
//        }
        //------------------- old end ------------------------------------------------
        // 1.查询项目类型字典数据
        List<DictModel> pType = sdm.queryDictListItemsByCode("xmgl-xmlx");
        // 2.查询各个类型的项目总投资数据
        List<Map<String, Object>> projectMoneyGroupByTypeList = pmm.queryProjectMoneyGroupByType(queryFilter);
        // 3.处理分组数据关联到字典值
        List<Map<String, String>> result = new ArrayList<>(pType.size() + 1);
        Map<String, String> countMap = new HashMap<>();
        countMap.put("name", "总计");
        countMap.put("value", "all");
        result.add(countMap);
        BigDecimal count = BigDecimal.ZERO;
        for (DictModel ele : pType) {
            // 将字典数字翻译为单词为键
//            String key = BizUtils.convertNumber(ele.getValue());
            Map<String, String> temp = new HashMap<>();
            String key = ele.getValue();
            String name = ele.getTitle();
            temp.put("name", name);
            temp.put("value", key);
            boolean notHave = true;
            for(Map<String, Object> projectMoneyMap : projectMoneyGroupByTypeList){
                Object objTotal = projectMoneyMap.get("total");
                BigDecimal total = BigDecimal.ZERO;
                if(objTotal instanceof BigDecimal){
                    total = (BigDecimal) objTotal;
                }else {
                    if(objTotal != null && (StringUtils.isNotBlank(String.valueOf(objTotal)))){
                        total = new BigDecimal(String.valueOf(objTotal));
                    }else {
                        total = BigDecimal.ZERO;
                    }

                }
                // 四射五入保留两位小数，去掉末尾零，并不使用科学计数法转为字符串
                total = total.setScale(2, BigDecimal.ROUND_HALF_UP);
                // 计算总金额
                count = count.add(total);
                if(key.equalsIgnoreCase(String.valueOf(projectMoneyMap.get("type")))){
                    temp.put("total", total.stripTrailingZeros().toPlainString());
                    notHave = false;
                }
            }
            if(notHave){
                temp.put("total", "0");
            }
            result.add(temp);
        }
        result.get(0).put("total", count.stripTrailingZeros().toPlainString());
        return result;
    }



    public Map<String, String> getCollect2(QueryFilter<ProjectManagement> queryFilter) {
        // 获取所有数据
        if(null == queryFilter){
            queryFilter = QueryFilter.build();
        }
//        queryFilter.withSorter(new FieldSort("PROJECT_TYPE_", Direction.ASC));
        List<FieldSort> sorter = queryFilter.getSorter();
        if(null != sorter && sorter.size() > 0){
            sorter.clear();
        }
        queryFilter.addFilter("PARENT_ID_","root", QueryOP.EQUAL);
        // 1.查询项目类型字典数据
        List<DictModel> pType = sdm.queryDictListItemsByCode("xmgl-xmlx");
        // 2.查询各个类型的项目总投资数据
        List<Map<String, Object>> projectMoneyGroupByTypeList = pmm.queryProjectMoneyGroupByType(queryFilter);
        // 3.处理分组数据关联到字典值
        Map<String, String> result = new HashMap<>();

        BigDecimal count = BigDecimal.ZERO;
        for (DictModel ele : pType) {
            // 将字典数字翻译为单词为键
//            String key = BizUtils.convertNumber(ele.getValue());
            String key = ele.getValue();
            String name = ele.getTitle();

            boolean notHave = true;
            for(Map<String, Object> projectMoneyMap : projectMoneyGroupByTypeList){
                Object objTotal = projectMoneyMap.get("total");
                BigDecimal total = BigDecimal.ZERO;
                if(objTotal instanceof BigDecimal){
                    total = (BigDecimal) objTotal;
                }else {
                    if(objTotal != null && (StringUtils.isNotBlank(String.valueOf(objTotal)))){
                        total = new BigDecimal(String.valueOf(objTotal));
                    }else {
                        total = BigDecimal.ZERO;
                    }

                }
                // 四射五入保留两位小数，去掉末尾零，并不使用科学计数法转为字符串
                total = total.setScale(2, BigDecimal.ROUND_HALF_UP);
                // 计算总金额
                count = count.add(total);
                if(key.equalsIgnoreCase(String.valueOf(projectMoneyMap.get("type")))){
                    result.put(key, ele.getTitle() + "："+total.stripTrailingZeros().toPlainString());
                    notHave = false;
                }
            }
            if(notHave){
                result.put(key, ele.getTitle() + "：0.00");
            }
        }

        result.put("all", "总计：" + count.stripTrailingZeros().toPlainString());
        return result;
    }

    /**
     * 将数据按类型统计
     *
     * @param data 所有数据
     * @return 分类统计Map
     */
    private Map<String, String> collectType(List<ProjectLedgerVo> data) {
        // 将项目类型初始化到Map
        Map<String, String> type = new LinkedHashMap<>();
        List<DictModel> pType = sdm.queryDictListItemsByCode("xmgl-xmlx");
        for (DictModel ele : pType) {
            // 将字典数字翻译为单词为键
//            String key = BizUtils.convertNumber(ele.getValue());
            String key = ele.getValue();
            type.put(key, ele.getTitle() + "：0.00");
        }

        // 为各类型统计值
        for (ProjectLedgerVo ele : data) {
//            String projectType = BizUtils.convertNumber(ele.getProjectType());
            String projectType = ele.getProjectType() + "";
            BigDecimal num = new BigDecimal(type.get(projectType).split("：")[1]).add(new BigDecimal(StringUtils.isEmpty(ele.getProjectMoney()) ? "0.00" : ele.getProjectMoney()));
            type.put(projectType, BizUtils.getDicValueByCode(pType, ele.getProjectType()) + "：" + num);
        }
        // 统计总值
        BigDecimal all = new BigDecimal("0");
        for (Map.Entry<String, String> ele : type.entrySet()) {
            all = all.add(new BigDecimal(ele.getValue().split("：")[1]));
        }
        type.put("all", "总计：" + all);
        return type;
    }

    @Override
    public Map<String, Object> getDataByPage(QueryFilter<ProjectManagement> queryFilter) {
        // 获取字典
        List<DictModel> bChargeType = sdm.queryDictListItemsByCode("zbfs");
        List<DictModel> dType = sdm.queryDictListItemsByCode("xmlx-jcyj-jcwjlx");
        List<DictModel> pStatus = sdm.queryDictListItemsByCode("xmgl-xmzt");
        // 监理单位
        List<DictModel> jldw = sdm.queryDictListItemsByCode("sgxk-jldw");
        // 施工单位
        List<DictModel> sgdw = sdm.queryDictListItemsByCode("sgxk-sgdw");
        // 设计单位
        List<DictModel> sjdw = sdm.queryDictListItemsByCode("sgxk-sjdw");
        // 勘察单位
        List<DictModel> kcdw = sdm.queryDictListItemsByCode("sgxk-kcdw");
        // 获取数据
        PageList<ProjectManagement> project = pmm.queryAllByPage(queryFilter);
        List<ProjectManagement> projectManagementList = null == project ? new ArrayList<>() : project.getRows();
        List<ProjectLedgerVo> data = new ArrayList<>();
        for(ProjectManagement ele : projectManagementList){
            ProjectLedgerVo temp = new ProjectLedgerVo();
            // 查询决策依据
            DecisionBasis decisionBasis =  dbm.getOne(new QueryWrapper<DecisionBasis>().eq("PROJECT_ID_", ele.getId()).eq("IS_DELE_", "0").last("limit 1"));
            temp.setDecisionBasisType(BeanUtils.isEmpty(decisionBasis)?"":decisionBasis.getDecisionBasisType());
            // 查询招投标
            BiddingManagement biddingManagement = bmm.getOne(new QueryWrapper<BiddingManagement>().eq("PROJECT_ID_", ele.getId()).eq("IS_DELE_", "0").last("limit 1"));
            temp.setBiddingChargeType(BeanUtils.isEmpty(biddingManagement)?"":String.valueOf(biddingManagement.getBiddingChargeType()));
            // 查询施工合同总金额
            temp.setContractAmount(contractManager.queryConstructionAmount(ele.getId()));
            // 将项目数据转为台账数据
            temp = ProjectLedgerVo.convertVo(ele,temp, bChargeType, dType, pStatus);
            // 查询五方单位
            ConstructionPermit constructionPermit = constructionPermitManager.getOne(
                    new QueryWrapper<ConstructionPermit>().eq("PROJECT_ID_", ele.getId())
                    .eq("IS_DELE_", "0").last("limit 1"));
            if(null != constructionPermit){
                // 责任单位
                if(StringUtils.isNotBlank(constructionPermit.getName())){
                    temp.setResponsibleUnit(constructionPermit.getName());
                }
                // 地勘单位
                if(StringUtils.isNotBlank(constructionPermit.getSurveyUnit())){
                    temp.setGeologicalProspectingUnit(BizUtils.getDicValueByCode(kcdw, constructionPermit.getSurveyUnit()));
                }
                // 设计单位
                if(StringUtils.isNotBlank(constructionPermit.getDesignUnit())){
                    temp.setDesignUnit(BizUtils.getDicValueByCode(sjdw, constructionPermit.getDesignUnit()));
                }
                // 监理单位
                if(StringUtils.isNotBlank(constructionPermit.getSupervisorUnit())){
                    temp.setSupervisorUnit(BizUtils.getDicValueByCode(jldw, constructionPermit.getSupervisorUnit()));
                }
                // 施工单位
                if(StringUtils.isNotBlank(constructionPermit.getConstructionUnit())){
                    temp.setConstructUnit(BizUtils.getDicValueByCode(sgdw, constructionPermit.getConstructionUnit()));
                }
            }

            data.add(temp);
        }

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

    @Override
    public void exportDatatoExcel(QueryFilter<ProjectManagement> queryFilter, HttpServletResponse response) throws Exception {
        // 获取字典
        List<DictModel> pType = sdm.queryDictListItemsByCode("xmgl-xmlx");
        List<QueryField> queryFieldList = queryFilter.getQuerys();
        // 导出时查询数据需要去除分页
        queryFilter.getPageBean().setPageSize(-1);
        // 获取导出年份拼接表头
        String year = BizUtils.getYearByQueryFields(queryFieldList);
        // 拼接导出年份到文件名，没有则不添加
        String fileName = (StringUtils.isEmpty(year) ? "" : year + "年") + "建设项目台账信息";
        // 创建excel工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 创建excel表
        HSSFSheet sheet = workbook.createSheet(fileName);
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        //设置字体
        HSSFFont font = workbook.createFont();
        //设置字体名称
        font.setFontName("宋体");
        cellStyle.setFont(font);
        // 处理表头
        // 第一行
        HSSFRow titleRow = sheet.createRow(0);
        BizUtils.handelCell(workbook,fileName, titleRow.createCell(0), fileName, true);
        // 第二行
        HSSFRow titleRow1 = sheet.createRow(1);
        for (int i = 0; i < 17; i++) {
            if (i == 0) {
                HSSFCell cell = titleRow1.createCell(i);
                BizUtils.handelCell(workbook,fileName, cell, "填报单位：西永微电园公司");
                // 独立的样式设置
                HSSFCellStyle style = workbook.createCellStyle();
                style.setAlignment(HorizontalAlignment.LEFT);
                style.setVerticalAlignment(VerticalAlignment.CENTER);
                HSSFFont font1 = workbook.createFont();
                font1.setFontName("宋体");
                font1.setFontHeightInPoints((short) 10);
                style.setFont(font1);
                cell.setCellStyle(style);
            } else if (i == 16) {
                BizUtils.handelCell(workbook,fileName, titleRow1.createCell(i), "单位：万元");
            } else {
                BizUtils.handelCell(workbook,fileName, titleRow1.createCell(i), "");
            }
        }
        // 标题行
        String[] heards = {"序号", "项目名称", "项目状态", "项目负责人", "决策依据", "责任单位", "地勘单位", "设计单位",
                "监理单位", "施工单位", "施工合同金额", "发包方式", "建设地址", "建设规模及内容", "总投资", "开工时间", "完工时间"};
        HSSFRow titleRow2 = sheet.createRow(2);
        for (int i = 0; i < heards.length; i++) {
            BizUtils.handelCell(workbook,fileName, titleRow2.createCell(i), heards[i], true);
        }

        // 获取数据
        queryFilter.withSorter(new FieldSort("PROJECT_TYPE_", Direction.ASC));
        List<ProjectLedgerVo> result = (List<ProjectLedgerVo>) getDataByPage(queryFilter).get("data");
        List<ProjectLedgerVo> data = null == result ? new ArrayList<>() : result;
        // 获取数据统计
        Map<String, String> type = getCollect2(queryFilter);
//        Map<String, String> type = collectType(data);
        // [总计] 行
        HSSFRow titleRow3 = sheet.createRow(3);
        for (int i = 0; i < 17; i++) {
            if (i == 1) {
                BizUtils.handelCell(workbook,fileName, titleRow3.createCell(i), "总计", true);
            } else if (i == 14) {
                BizUtils.handelCell(workbook,fileName, titleRow3.createCell(i), type.get("all").split("：")[1],true);
            } else {
                BizUtils.handelCell(workbook,fileName, titleRow3.createCell(i), "");
            }
        }
        // 数据行,从4行开始,共data.size行
        int row = 4;
        // 当前类型标记
        int currentType = 0;
        // 计数器，当前分类下的序号标记
        int counter = 1;

        // 处理第一条数据就漏分类的情况，即不从一开始就会丢失一到第一条数据的类别统计
        for(int j = 1;j<data.get(0).getProjectType();j++){
            HSSFRow addRow = sheet.createRow(sheet.getLastRowNum() + 1);
            handleSubTitle(j,fileName, type, workbook, addRow);
            row++;
        }

        // 处理数据
        for (int i = 0; i < data.size(); i++) {
            HSSFRow listRow = sheet.createRow(row);// 创建行
            if (currentType != data.get(i).getProjectType()) {
                // 当前项目类型标记 不同于 循环中项目的项目类型时，需要为其分类
                // 更新当前项目类型标记
                currentType = data.get(i).getProjectType();
                // 处理子标题行
                handleSubTitle(currentType,fileName, type, workbook, listRow);
                // 重置子标题下的序号计数器
                counter = 1;
                // 撤销当前循环
                i--;
            }
            else if (data.get(i).getProjectType() - currentType > 1) {
                // 处理断层情况，当中间数据的项目类型丢失的情况，即上一类为1，当前类为3，那就要补上中间漏掉的类2
                for (int j = currentType++; j < data.get(i).getProjectType(); j = currentType++) {
                    HSSFRow addRow = sheet.createRow(sheet.getLastRowNum() + 1);
                    handleSubTitle(currentType,fileName, type, workbook, addRow);
                }
            } else {
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(0), String.valueOf(counter));
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(1), data.get(i).getProjectName());
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(2), data.get(i).getProjectStatus());
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(3), data.get(i).getProjectManager());
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(4), data.get(i).getDecisionBasisType());
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(5), data.get(i).getResponsibleUnit());
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(6), data.get(i).getGeologicalProspectingUnit());
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(7), data.get(i).getDesignUnit());
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(8), data.get(i).getSupervisorUnit());
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(9), data.get(i).getConstructUnit());
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(10), null == data.get(i).getContractAmount() ? "0" : data.get(i).getContractAmount().stripTrailingZeros().toPlainString());
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(11), data.get(i).getBiddingChargeType());
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(12), data.get(i).getProjectAddress());
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(13), data.get(i).getProjectContent());
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(14), data.get(i).getProjectMoney());
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(15), BizUtils.handleDateFormat(data.get(i).getCommencementTime()));
                BizUtils.handelCell(workbook, cellStyle, font, fileName, listRow.createCell(16), BizUtils.handleDateFormat(data.get(i).getCompletionTime()));
                counter++;
            }
            row++;
        }

        // 填充没有数据的分类
        // 最后一行
        int lastIndex = sheet.getLastRowNum() + 1;
        for (int i = currentType++; i < pType.size(); i = currentType++) {
            HSSFRow lastRow = sheet.createRow(lastIndex++);
            handleSubTitle(currentType,fileName, type, workbook, lastRow);
        }

        // 合并单元格
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 16));
        sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, 1));


        sheet.setColumnWidth(1,6000);
        sheet.setColumnWidth(5,6000);
        for(int i = 2;i<heards.length;i++){
            if(i==5)continue;
            sheet.setColumnWidth(i,4000);
        }

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

    /**
     * 处理子标题行
     *
     * @param currentType 当前项目类型
     * @param fileName    文件名，即Sheet名，用于获取Sheet单元格
     * @param type        项目类型数据
     * @param workbook    workBook工作蒲
     * @param row         行
     */
    private void handleSubTitle(int currentType,String fileName, Map<String, String> type, HSSFWorkbook workbook, HSSFRow row) {
        for (int t = 0; t < 17; t++) {
            String temp = type.get(String.valueOf(currentType));
            if(BeanUtils.isEmpty(temp)){
               return;
            }
            String[] typeData = temp.split("[：]");
            if (t == 0) {
                BizUtils.handelCell(workbook,fileName, row.createCell(t), BizUtils.converttoChinaNumber(currentType));
            } else if (t == 1) {
                BizUtils.handelCell(workbook,fileName, row.createCell(t), typeData[0]);
            } else if (t == 14) {
                BizUtils.handelCell(workbook,fileName, row.createCell(t), typeData[1]);
            } else {
                BizUtils.handelCell(workbook,fileName, row.createCell(t), "");
            }
        }
    }

}
