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

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.artfess.base.feign.UCFeignService;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.query.*;
import com.artfess.base.util.BeanUtils;
import com.artfess.cqxy.contract.manager.AdministrativePaymentManager;
import com.artfess.cqxy.contract.model.AdministrativePayment;
import com.artfess.cqxy.ledger.dao.PayLedgerDao;
import com.artfess.cqxy.ledger.manager.PayLedgerManager;
import com.artfess.cqxy.ledger.vo.PayLedgerNewVo;
import com.artfess.cqxy.ledger.vo.PayLedgerVo;
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.ProjectPersonnelManager;
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.metadata.IPage;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * @author 黎沐华
 * @date 2022/6/2 10:14
 */
@Service
public class PayLedgerManagerImpl extends BaseManagerImpl<PayLedgerDao, PayLedgerVo> implements PayLedgerManager {

    @Autowired
    private SysDictionaryManager sdm;
    @Autowired
    private ProjectPersonnelManager projectPersonnelManager;

    @Autowired
    private UCFeignService ucFeignService;

    @Autowired
    private ProjectManagementDao projectManagementDao;

    @Autowired
    private ProgressManageManager progressManager;

    @Autowired
    private AdministrativePaymentManager administrativePaymentManager;

    @Override
    public PageList<PayLedgerVo> queryByPage(QueryFilter<PayLedgerVo> queryFilter) {
        queryFilter.withSorter(new FieldSort("pm.PROJECT_TYPE_", Direction.ASC));
        queryFilter.withSorter(new FieldSort("pr.PROJECT_ID_", Direction.ASC));
        queryFilter.withSorter(new FieldSort("pr.REGISTER_DATE_", Direction.DESC));
        if(BizUtils.isProjectIdFields(queryFilter.getQuerys())){
            List<String> projectList = BizUtils.handProjectAuthByUser(ucFeignService, projectPersonnelManager, projectManagementDao);
            if(null!=projectList&&projectList.size()>0){
                queryFilter.addFilter("pr.PROJECT_ID_", projectList, QueryOP.IN);
            }
        }
        // 数据
        QueryWrapper<PayLedgerVo> wrapper = (QueryWrapper<PayLedgerVo>) convert2Wrapper(queryFilter, PayLedgerVo.class);
        wrapper.eq("pr.IS_DELE_", "0").eq("pm.IS_DELE_", "0");
        IPage<PayLedgerVo> result = baseMapper.queryByPage(convert2IPage(queryFilter.getPageBean()), wrapper);
        List<PayLedgerVo> data = result.getRecords();
        // 字典
        List<DictModel> purpose = sdm.queryDictListItemsByCode("jdgl-yt");

        // 处理数据
        for (PayLedgerVo ele : data) {
            if (ObjectUtils.isNotEmpty(ele.getPurpose())) {
                ele.setPurpose(BizUtils.getDicValueByCode(purpose, ele.getPurpose()));
            }
            if (ObjectUtils.isNotEmpty(ele.getPayeeAmountTotal())) {
                ele.setPayeeAmountTotal(ele.getPayeeAmountTotal().stripTrailingZeros());
            }
            if (ObjectUtils.isNotEmpty(ele.getAmountAppropriated())) {
                ele.setAmountAppropriated(ele.getAmountAppropriated().add(ele.getPayeeAmountTotal()).stripTrailingZeros());
            }else {
                ele.setAmountAppropriated(BigDecimal.ZERO.add(ele.getPayeeAmountTotal()).stripTrailingZeros());
            }
            // 累计支付比例=累计支付金额÷合同金额×100%，最高为100%，如果大于说明数据不对，就先显示100%
            try {
                BigDecimal ratio = ele.getAmountAppropriated()
                        .divide(new BigDecimal(ele.getContractAmount()), 4, RoundingMode.HALF_EVEN).multiply(BigDecimal.valueOf(100));
                if (ratio.compareTo(BigDecimal.valueOf(100)) > 0) {
                    ratio = BigDecimal.valueOf(100);
                }
                if(ratio.compareTo(BigDecimal.ZERO)==0){
                    ele.setPayRatio("-");
                }else {
                    ele.setPayRatio(ratio.stripTrailingZeros().toPlainString() + "%");
                }

            } catch (Exception e) {
                ele.setPayRatio("-");
            }
        }
        result.setRecords(data);

        return new PageList<>(result);
    }


    @Override
    public void exportDataToExcel(QueryFilter<PayLedgerVo> queryFilter, HttpServletResponse response) throws IOException {

        List<PayLedgerVo> data = queryByPage(queryFilter).getRows();
        if (null == data || data.size() == 0) {
            throw new RuntimeException("没有要导出的的数据！");
        }

        String fileName = data.stream().collect(Collectors.groupingBy(PayLedgerVo::getProjectName)).keySet().toArray()[0] + "项目支付台账";

        // EasyPoi 导出参数、样式、表格格式设置
        ExportParams exportParams = BizUtils.getExportParams(fileName);
        fileName += ".xlsx";

        List<PayLedgerNewVo> dataNew = new ArrayList<>();
        data.forEach(s->{
            dataNew.add(PayLedgerNewVo.convertToPayLedgerNewVo(s));
        });
        // 导出下载excel文件
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, PayLedgerNewVo.class, dataNew);
        Sheet sheetAt = workbook.getSheetAt(0);
        for(int i = 0;i<9;i++){
            sheetAt.setColumnWidth(i,5000);
        }

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

    @Override
    public BigDecimal totalPayByYear(Integer year) {
        Assert.notNull(year, "统计年份不能为空!");
        BigDecimal result = BigDecimal.ZERO;
        /**
         * 年度总支付 (万元)年度总支付计算公式：根据时间条件查询支付表进行支付求和+根据时间条件查询行政缴费表中费用求和
         */
        // 拉取项目支付表和行政缴费表数据

        List<AdministrativePayment> paymentList = administrativePaymentManager.list(new QueryWrapper<AdministrativePayment>().eq("PAYS_YEAR_", year));

        //根据时间条件查询支付表进行支付求和
        Map<String, Object> map1 = progressManager.getMap(new QueryWrapper<ProgressManage>()
                .select("SUM(PAYEE_AMOUNT_TOTAL_) as price").eq(year!=0,"YEAR_", year)
                .eq("IS_DELE_","0"));
        if(BeanUtils.isNotEmpty(map1)){
            Object price = map1.get("price");
            if(BeanUtils.isNotEmpty(price)){
                result = result.add((BigDecimal)price);
            }
        }
        //根据时间条件查询行政缴费表中费用求和
        Map<String, Object> map2 = administrativePaymentManager.getMap(new QueryWrapper<AdministrativePayment>()
                .select("SUM(PAYS_VALUE_) as price")
                .eq(year!=0,"PAYS_YEAR_", year).eq("IS_DELE_","0"));
        if(BeanUtils.isNotEmpty(map2)){
            Object price = map2.get("price");
            if(BeanUtils.isNotEmpty(price)){
                result = result.add((BigDecimal)price);
            }
        }
        return result.setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros();
    }

}
