package cn.superdesk.uniorder.service.accounting.unified.operator.Impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.superdesk.uniorder.common.enums.accounting.operator.*;
import cn.superdesk.uniorder.common.enums.thirdpart.jd.SysQuartzScheduleTaskStatementOfAccountRunStateEnum;
import cn.superdesk.uniorder.common.excel.biz.CustomSheetWriteHandler;
import cn.superdesk.uniorder.common.excel.biz.CustomSheetWriteNameHandler;
import cn.superdesk.uniorder.common.excel.biz.CustomWorkbookWriteHandler;
import cn.superdesk.uniorder.common.sequence.GenRandomHelper;
import cn.superdesk.uniorder.dao.entity.accounting.unified.operator.AccountingUnifiedOperator;
import cn.superdesk.uniorder.dao.entity.accounting.unified.operator.AccountingUnifiedOperatorWithBLOBs;
import cn.superdesk.uniorder.dao.entity.operationCenter.UnifiedCustomerInvoiceTitle;
import cn.superdesk.uniorder.dao.entity.sys.notify.SysNotify;
import cn.superdesk.uniorder.dao.entity.unified.settlement.UnifiedSettlementProgramme;
import cn.superdesk.uniorder.dao.mapper.accounting.unified.operator.AccountingUnifiedOperatorMapper;
import cn.superdesk.uniorder.dao.mapper.accounting.unified.operator.AccountingUnifiedOperatorMapperEx;
import cn.superdesk.uniorder.dao.mapper.operationCenter.UnifiedBillStartMapper;
import cn.superdesk.uniorder.dao.mapper.unified.settlement.UnifiedSettlementProgrammeMapper;
import cn.superdesk.uniorder.dao.mapper.unified.settlement.UnifiedSettlementProgrammeRangeRuleMapperEx;
import cn.superdesk.uniorder.dto._constant.ResourceConstant;
import cn.superdesk.uniorder.dto.param.accounting.unified.operator.AccountingUnifiedOperatorQueryParam;
import cn.superdesk.uniorder.dto.vo.accounting.unified.operator.*;
import cn.superdesk.uniorder.dto.vo.accounting.unified.operator.excel.GoodsVo;
import cn.superdesk.uniorder.dto.vo.unified.settlement.RangeRuleVo;
import cn.superdesk.uniorder.notify.NotifyUtils;
import cn.superdesk.uniorder.service.accounting.unified.operator.AccountingUnifiedOperatorService;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.fastjson2.JSON;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.io.File;
import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
@RequiredArgsConstructor
public class AccountingUnifiedOperatorServiceImpl implements AccountingUnifiedOperatorService {
    private final AccountingUnifiedOperatorMapperEx accountingUnifiedOperatorMapperEx;

    private final AccountingUnifiedOperatorMapper accountingUnifiedOperatorMapper;

    private final UnifiedBillStartMapper unifiedBillStartMapper;

    private final UnifiedSettlementProgrammeMapper unifiedSettlementProgrammeMapper;

    private final ResourceConstant excelExportConstant;

    private final UnifiedSettlementProgrammeRangeRuleMapperEx unifiedSettlementProgrammeRangeRuleMapperEx;

    private static final String EXPORT_ACCOUNTING_OPERATION_TEMPLATE = "AccountingOperatorExportTemplate.xls";
    private static final String EXPORT_ACCOUNTING_OP_TEMPLATE = "AccountingOpExportTemplate.xls";
    private static final String EXPORT_ACCOUNTING_OP_SUPPLIER_TEMPLATE = "AccountingOpSupplierExportTemplate.xls";

    @Override
    public int insertSelective(AccountingUnifiedOperator accountingUnifiedOperator) {
        return accountingUnifiedOperatorMapper.insertSelective((AccountingUnifiedOperatorWithBLOBs) accountingUnifiedOperator);
    }

    @Override
    public int updateByPrimaryKeySelective(AccountingUnifiedOperator accountingUnifiedOperator) {
        return accountingUnifiedOperatorMapper.updateByPrimaryKeySelective((AccountingUnifiedOperatorWithBLOBs) accountingUnifiedOperator);
    }

    @Override
    public void deleteObj(Long id) {
        accountingUnifiedOperatorMapper.deleteByPrimaryKey(id);
    }

    @Override
    public AccountingUnifiedOperator findById(Long id) {
        return accountingUnifiedOperatorMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<AccountingUnifiedOperator> findAll(Map<String, Object> queryMap) {
        return null;
    }

    @Override
    public PageInfo<AccountingUnifiedOperator> findByPaging(Map<String, Object> params, Integer pageNo, Integer pageSize) {
        return null;
    }

    @Override
    public List<AccountingUnifiedOperatorVo> getAccountingList(AccountingUnifiedOperatorQueryParam param) {
        List<AccountingUnifiedOperatorVo> list = accountingUnifiedOperatorMapperEx.getAccountingList(param);
        for(AccountingUnifiedOperatorVo vo : list){
            vo.setAccountingStatusDesc(AccountingOrderOperatorAccountStatusEnum.getDescByKey(vo.getAccountingStatus()));
            vo.setEmailStatusDesc(AccountingEmailStatusEnum.getDescByKey(vo.getEmailStatus()));
        }
        return list;
    }

    @Override
    public AccountingBillBaseVo getBaseBillInfo(Long billId) {
        return accountingUnifiedOperatorMapperEx.getBaseBillInfo(billId);
    }

    @Override
    public SysNotify exportList(AccountingUnifiedOperatorQueryParam param) {
        List<AccountingUnifiedOperatorVo> list = getAccountingList(param);


        String excelExportPathRoot = excelExportConstant.getPathRoot();// /data
        String excelExportOrderPathTemplate = excelExportConstant.getPathTemplate();// /template
        String excelExportOrderPathStorage = excelExportConstant.getPathStorage(); // /_storage
        String relativePath = File.separator + "excel" + File.separator + "accounting" + File.separator + "unified" + File.separator+ "operator" + File.separator;
        String templateRelativePath = excelExportPathRoot + excelExportOrderPathTemplate + relativePath;// /data/template/excel/accounting/unified/operator/
        String templateFullPath = templateRelativePath + EXPORT_ACCOUNTING_OPERATION_TEMPLATE;// /data/template/excel/accounting/unified/operator/AccountingOperatorExportTemplate.xls
        String targetFullPath = excelExportPathRoot + excelExportOrderPathStorage;



        String strTime = DateUtil.format(new Date(), "yyyyMMddHHmmss");

        String targetFileName = "账单管理_导出列表_" + strTime + GenRandomHelper.genRandomNum(4) +".xlsx";
        String targetWriteFileFullPath = targetFullPath + relativePath + targetFileName;

        FileUtil.touch(targetWriteFileFullPath);

        ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(targetWriteFileFullPath);

        ExcelWriter excelWriter = null;
        WriteSheet writeSheet0 = EasyExcel.writerSheet(0, "账单管理").build();
        excelWriter = excelWriterBuilder.withTemplate(templateFullPath).build();

        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.FALSE).build();
        excelWriter.fill(new FillWrapper("detail", list), fillConfig, writeSheet0);

        excelWriter.finish();

        return NotifyUtils.createSysNotify(targetFileName, relativePath + targetFileName, SysQuartzScheduleTaskStatementOfAccountRunStateEnum.成功);
    }

    @Override
    public SysNotify exportAccountList(AccountingUnifiedOperatorQueryParam param) {
        String excelExportPathRoot = excelExportConstant.getPathRoot();
        String excelExportOrderPathTemplate = excelExportConstant.getPathTemplate();
        String excelExportOrderPathStorage = excelExportConstant.getPathStorage();
        String relativePath = File.separator + "excel" + File.separator + "accounting" + File.separator + "unified" + File.separator+ "operator" + File.separator;
        String templateRelativePath = excelExportPathRoot + excelExportOrderPathTemplate + relativePath;
        String templateFullPath = templateRelativePath + EXPORT_ACCOUNTING_OP_TEMPLATE;
        String targetFullPath = excelExportPathRoot + excelExportOrderPathStorage;



        String strTime = DateUtil.format(new Date(), "yyyyMMddHHmmss");

        String targetFileName = "账单管理_导出账单_" + strTime + GenRandomHelper.genRandomNum(4) +".xlsx";
        String targetWriteFileFullPath = targetFullPath + relativePath + targetFileName;

        FileUtil.touch(targetWriteFileFullPath);

        BillVo billVo = getBillVoByAccountingBill(param.getId());


        ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(targetWriteFileFullPath);
        ExcelWriter excelWriter = excelWriterBuilder.withTemplate(templateFullPath).registerWriteHandler(new CustomWorkbookWriteHandler()).build();
        WriteSheet writeSheet0 = null;
        WriteSheet writeSheet1 = null;
        WriteSheet writeSheet2 = null;
        WriteSheet writeSheet3 = null;
        if(SettlementRuleEnum.结算金额.getKey().equals(billVo.getSettlementRule())){
            writeSheet0 = EasyExcel.writerSheet(0, "账单1").registerWriteHandler(new CustomSheetWriteNameHandler()).build();
            writeSheet1 = EasyExcel.writerSheet(1, "账单2").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet2 = EasyExcel.writerSheet(2, "账单3").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet3 = EasyExcel.writerSheet(3, "账单4").registerWriteHandler(new CustomSheetWriteHandler()).build();
        }else if(SettlementRuleEnum.结算金额_合作分润_服务费.getKey().equals(billVo.getSettlementRule())){
            writeSheet0 = EasyExcel.writerSheet(0, "账单1").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet1 = EasyExcel.writerSheet(1, "账单2").registerWriteHandler(new CustomSheetWriteNameHandler()).build();
            writeSheet2 = EasyExcel.writerSheet(2, "账单3").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet3 = EasyExcel.writerSheet(3, "账单4").registerWriteHandler(new CustomSheetWriteHandler()).build();
        }else if(SettlementRuleEnum.结算金额_合作分润.getKey().equals(billVo.getSettlementRule())){
            writeSheet0 = EasyExcel.writerSheet(0, "账单1").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet1 = EasyExcel.writerSheet(1, "账单2").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet2 = EasyExcel.writerSheet(2, "账单3").registerWriteHandler(new CustomSheetWriteNameHandler()).build();
            writeSheet3 = EasyExcel.writerSheet(3, "账单4").registerWriteHandler(new CustomSheetWriteHandler()).build();
        }else if(SettlementRuleEnum.结算金额_服务费.getKey().equals(billVo.getSettlementRule())){
            writeSheet0 = EasyExcel.writerSheet(0, "账单1").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet1 = EasyExcel.writerSheet(1, "账单2").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet2 = EasyExcel.writerSheet(2, "账单3").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet3 = EasyExcel.writerSheet(3, "账单4").registerWriteHandler(new CustomSheetWriteNameHandler()).build();
        }else{
            log.info("异常,结算规则超出所定义的范围内");
        }

        WriteSheet writeSheet4 = new WriteSheet();
        writeSheet4.setSheetNo(4);
        writeSheet4.setSheetName("商品明细");
        WriteTable writeTable4 = new WriteTable();
        writeTable4.setTableNo(1);
        writeTable4.setHead(heads(billVo,goodsTitles1()));

        WriteSheet writeSheet5 = new WriteSheet();
        writeSheet5.setSheetNo(5);
        writeSheet5.setSheetName("流水明细");
        WriteTable writeTable5 = new WriteTable();
        writeTable5.setTableNo(1);
        writeTable5.setHead(heads(billVo,waterTitles()));

        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.FALSE).build();
        excelWriter.fill(billVo, fillConfig, writeSheet0);
        excelWriter.fill(billVo, fillConfig, writeSheet1);
        excelWriter.fill(billVo, fillConfig, writeSheet2);
        excelWriter.fill(billVo, fillConfig, writeSheet3);
        excelWriter.write(dataList(billVo.getGoodsList(),billVo,goodsFiled1()), writeSheet4,writeTable4);
        excelWriter.write(dataList(billVo.getWaterList(),billVo,waterFiled()), writeSheet5,writeTable5);
        excelWriter.finish();

        return NotifyUtils.createSysNotify(targetFileName, relativePath + targetFileName, SysQuartzScheduleTaskStatementOfAccountRunStateEnum.成功);
    }

    @Override
    public SysNotify exportAccountSupplierList(AccountingUnifiedOperatorQueryParam param) {
//        String excelExportPathRoot = excelExportConstant.getPathRoot();
//        String excelExportOrderPathTemplate = excelExportConstant.getPathTemplate();
//        String excelExportOrderPathStorage = excelExportConstant.getPathStorage();
        String relativePath = File.separator + "excel" + File.separator + "accounting" + File.separator + "unified" + File.separator+ "operator" + File.separator;
//        String templateRelativePath = excelExportPathRoot + excelExportOrderPathTemplate + relativePath;
//        String templateFullPath = templateRelativePath + EXPORT_ACCOUNTING_OP_SUPPLIER_TEMPLATE;
//        String targetFullPath = excelExportPathRoot + excelExportOrderPathStorage;

        String strTime = DateUtil.format(new Date(), "yyyyMMddHHmmss");
        String targetFileName = "账单管理_导出账单(含供应商成本)_" + strTime + GenRandomHelper.genRandomNum(4) +".xlsx";
//        String targetWriteFileFullPath = targetFullPath + relativePath + targetFileName;

        String targetWriteFileFullPath = "D:\\template\\excel\\"+targetFileName;
        String templateFullPath = "D:\\template\\tmp\\" +EXPORT_ACCOUNTING_OP_SUPPLIER_TEMPLATE;

        FileUtil.touch(targetWriteFileFullPath);

//        ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(targetWriteFileFullPath,Map.class);

        BillVo billVo = getBillVoByAccountingBill(param.getId());


        ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(targetWriteFileFullPath);
        ExcelWriter excelWriter = excelWriterBuilder.withTemplate(templateFullPath).registerWriteHandler(new CustomWorkbookWriteHandler()).build();
        WriteSheet writeSheet0 = null;
        WriteSheet writeSheet1 = null;
        WriteSheet writeSheet2 = null;
        WriteSheet writeSheet3 = null;
        if(SettlementRuleEnum.结算金额.getKey().equals(billVo.getSettlementRule())){
            writeSheet0 = EasyExcel.writerSheet(0, "账单1").registerWriteHandler(new CustomSheetWriteNameHandler()).build();
            writeSheet1 = EasyExcel.writerSheet(1, "账单2").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet2 = EasyExcel.writerSheet(2, "账单3").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet3 = EasyExcel.writerSheet(3, "账单4").registerWriteHandler(new CustomSheetWriteHandler()).build();
        }else if(SettlementRuleEnum.结算金额_合作分润_服务费.getKey().equals(billVo.getSettlementRule())){
            writeSheet0 = EasyExcel.writerSheet(0, "账单1").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet1 = EasyExcel.writerSheet(1, "账单2").registerWriteHandler(new CustomSheetWriteNameHandler()).build();
            writeSheet2 = EasyExcel.writerSheet(2, "账单3").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet3 = EasyExcel.writerSheet(3, "账单4").registerWriteHandler(new CustomSheetWriteHandler()).build();
        }else if(SettlementRuleEnum.结算金额_合作分润.getKey().equals(billVo.getSettlementRule())){
            writeSheet0 = EasyExcel.writerSheet(0, "账单1").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet1 = EasyExcel.writerSheet(1, "账单2").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet2 = EasyExcel.writerSheet(2, "账单3").registerWriteHandler(new CustomSheetWriteNameHandler()).build();
            writeSheet3 = EasyExcel.writerSheet(3, "账单4").registerWriteHandler(new CustomSheetWriteHandler()).build();
        }else if(SettlementRuleEnum.结算金额_服务费.getKey().equals(billVo.getSettlementRule())){
            writeSheet0 = EasyExcel.writerSheet(0, "账单1").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet1 = EasyExcel.writerSheet(1, "账单2").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet2 = EasyExcel.writerSheet(2, "账单3").registerWriteHandler(new CustomSheetWriteHandler()).build();
            writeSheet3 = EasyExcel.writerSheet(3, "账单4").registerWriteHandler(new CustomSheetWriteNameHandler()).build();
        }else{
            log.info("异常,结算规则超出所定义的范围内");
        }

        WriteSheet writeSheet4 = new WriteSheet();
        writeSheet4.setSheetNo(4);
        writeSheet4.setSheetName("商品明细");
        WriteTable writeTable4 = new WriteTable();
        writeTable4.setTableNo(1);
        writeTable4.setHead(heads(billVo,goodsTitles()));

        WriteSheet writeSheet5 = new WriteSheet();
        writeSheet5.setSheetNo(5);
        writeSheet5.setSheetName("流水明细");
        WriteTable writeTable5 = new WriteTable();
        writeTable5.setTableNo(1);
        writeTable5.setHead(heads(billVo,waterTitles()));

        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.FALSE).build();
        excelWriter.fill(billVo, fillConfig, writeSheet0);
        excelWriter.fill(billVo, fillConfig, writeSheet1);
        excelWriter.fill(billVo, fillConfig, writeSheet2);
        excelWriter.fill(billVo, fillConfig, writeSheet3);
        excelWriter.write(dataList(billVo.getGoodsList(),billVo,goodsFiled()), writeSheet4,writeTable4);
        excelWriter.write(dataList(billVo.getWaterList(),billVo,waterFiled()), writeSheet5,writeTable5);
        excelWriter.finish();

        return NotifyUtils.createSysNotify(targetFileName, relativePath + targetFileName, SysQuartzScheduleTaskStatementOfAccountRunStateEnum.成功);
    }

     // -------------------------------从数据库中获取数据   开始--------------------------

    /**
     * 导出单个账单所需要用到的基础信息
     * @param id
     * @return
     */
    private BillVo getBillVoByAccountingBill(Long id){
        BillVo billVo = new BillVo();
        //账单信息
        AccountingBillVo accountingBillVo = getBillVo(id);
        if(null != accountingBillVo && null != accountingBillVo.getAVo()){
            BeanUtils.copyProperties(accountingBillVo.getAVo(),billVo);
        }
        if(null != accountingBillVo && null != accountingBillVo.getOVo()){
            BeanUtils.copyProperties(accountingBillVo.getOVo(),billVo);
        }
        if(null != accountingBillVo && null != accountingBillVo.getSVo()){
            SettlementProgrammeVo programmeVo = accountingBillVo.getSVo();
            BeanUtils.copyProperties(programmeVo,billVo);
            billVo.setProgrammeId(programmeVo.getId());
            Map<String,Object> params = new HashMap<>();
            params.put("programmeId",billVo.getProgrammeId());
            params.put("type", SettlementRangeRuleTypeEnum.部分按原供应商名称导出.getKey());
            List<RangeRuleVo> rangeRuleVoList = unifiedSettlementProgrammeRangeRuleMapperEx.getByType(params);
            if(CollectionUtils.isNotEmpty(rangeRuleVoList)){
                billVo.setRangeRuleVoList(rangeRuleVoList);
            }
        }
        //商品明细
        billVo.setGoodsList(goodsData());
        //流水明细
        billVo.setWaterList(waterData());
        return billVo;
    }

    /**
     * 获取对账单对应的商品明细  目前是造的假数据，实际上数据是从数据库查询的
     * @return
     */
    private List<GoodsVo> goodsData(){
        List<GoodsVo> list = new ArrayList<>();
        GoodsVo vo = new GoodsVo();
        vo.setId("1588358");
        vo.setOrderNumber("ME20230302142813644010");
        vo.setBizPlatfrom("福利商城");
        vo.setOperatorName("湘江商管");
        vo.setOrgName("长沙华融湘江银行");
        vo.setVirtName("华融湘江银行");
        vo.setCreatedBy("1");
        vo.setCreatedName("张三");
        vo.setCreatedMobile("18612345678");
        vo.setOrderType("福利商城");
        vo.setBusinessType("订单");
        vo.setOrderTime("2021-12-28 12:00:00");
        vo.setOperateTime("2021-12-28 12:00:00");
        vo.setDeliveryTime("2021-12-28 12:00:00");
        vo.setFinishTime("2021-12-28 12:00:00");
        vo.setGoodsType("商品");
        vo.setGoodsId("1");
        vo.setGoodsName("新希望 雪兰高原牧场纯牛奶 3.3g乳蛋白 心花怒FUN限定高原牧场  200g*12盒*4箱");
        vo.setGoodsCode("1");
        vo.setGoodsSpecs("SD03571916");
        vo.setFirstClassify("食品饮料");
        vo.setSecondClassify("饮料冲调");
        vo.setThreeClassify("牛奶乳品");
        vo.setGoodsQuantity("1");
        vo.setGoodsUnit("箱");
        vo.setGoodsPrice(new BigDecimal("100.00"));
        vo.setGoodsSumPrice(new BigDecimal("100.00"));
        vo.setGoodsSalePrice(new BigDecimal("100.00"));
        vo.setGoodsSumSalePrice(new BigDecimal("100.00"));
        vo.setGoodsCostPrice(new BigDecimal("100.00"));
        vo.setGoodsSumCostPrice(new BigDecimal("100.00"));
        vo.setDiscountPrice(new BigDecimal("100.00"));
        vo.setSettlementPrice(new BigDecimal("100.00"));
        vo.setTransactionStatus("已完成");
        vo.setOrderStatus("交易完成");
        vo.setAfterSaleType("1");
        vo.setPayWay("组合支付");
        vo.setAddress("湖南长沙市芙蓉区湘湖街道车站北路246号滨湖嘉园");
        vo.setExpressCompany("申通");
        vo.setExpressNo("773196694831457");
        vo.setSupplierName("A供应商");
        vo.setCostPrice(new BigDecimal("80.00"));
        vo.setSumCostPrice(new BigDecimal("80.00"));
        vo.setUpdatedTime("2021-12-28 12:00:00");
        list.add(vo);
        return list;
    }

    /**
     * 获取对账单对应的商品明细  目前是造的假数据，实际上数据是从数据库查询的
     * @return
     */
    private List<GoodsVo> waterData(){
        List<GoodsVo> list = new ArrayList<>();
        GoodsVo vo = new GoodsVo();
        vo.setId("1621921");
        vo.setOrderNumber("ME20230302142813644010");
        vo.setBizPlatfrom("福利商城");
        vo.setOperatorName("湘江商管");
        vo.setOrgName("长沙华融湘江银行");
        vo.setVirtName("华融湘江银行");
        vo.setCreatedBy("1");
        vo.setCreatedName("张三");
        vo.setCreatedMobile("18612345678");
        vo.setOrderType("福利商城");
        vo.setBusinessType("订单");
        vo.setOrderTime("2021-12-28 12:00:00");
        vo.setOperateTime("2021-12-28 12:00:00");
        vo.setFinishTime("2021-12-28 12:00:00");
        vo.setGoodsType("商品");
        vo.setGoodsId("1000");
        vo.setGoodsName("新希望 雪兰高原牧场纯牛奶 3.3g乳蛋白 心花怒FUN限定高原牧场  200g*12盒*4箱");
        vo.setOrderPrice(new BigDecimal("50.00"));
        vo.setIsJoinSettlement("结算");
        vo.setTransactionStatus("已完成");
        vo.setPayWay("余额支付");
        vo.setIntegralType("123");
        vo.setIntegralBatch("456");
        vo.setSupplierName("A供应商");
        vo.setUpdatedTime("2021-12-28 12:00:00");
        list.add(vo);
        return list;
    }

    // -------------------------------从数据库中获取数据   结束--------------------------



    // -------------------------------导出数据做优化     开始---------------------------


    /**
     * 导出账单-商品明细导出的标题
     * @return
     */
    private String [] goodsTitles1(){
        String [] titles = {"ID","订单编号","三方单号","业务平台","运营商","项目名称","企业名称"
                ,"下单人id","下单人姓名","下单人手机号码","订单类型","业务类型","订单时间"
                ,"支付/退款时间","发货时间","完成时间","商品类型","商品id","商品名称"
                ,"商品编码","商品规格","一级分类","二级分类","三级分类","商品数量"
                ,"商品单位","商品原单价","商品原总价","商品销售单价","商品销售总价"
                ,"商品成本单价","商品成本总价","优惠金额","订单金额","结算金额","交易状态",
                "订单状态","售后类型","支付方式","收货地址","快递公司","快递单号"
                ,"退单原单号","供应商名称","更新时间"};
        return titles;
    }


    /**
     * 导出账单-商品明细导出的字段
     * @return
     */
    private String [] goodsFiled1(){
        String [] fileds = {"id","orderNumber","thirdNo","bizPlatfrom","operatorName","orgName","virtName"
                ,"createdBy","createdName","createdMobile","orderType","businessType"
                ,"orderTime","operateTime","deliveryTime","finishTime","goodsType","goodsId"
                ,"goodsName","goodsCode","goodsSpecs","firstClassify","secondClassify"
                ,"threeClassify","goodsQuantity","goodsUnit","goodsPrice","goodsSumPrice"
                ,"goodsSalePrice","goodsSumSalePrice","goodsCostPrice","goodsSumCostPrice"
                ,"discountPrice","orderPrice","settlementPrice","transactionStatus","orderStatus"
                ,"afterSaleType","payWay","address","expressCompany","expressNo"
                ,"chargebackNo","supplierName","updatedTime"};
        return fileds;
    }

    /**
     * 导出账单(含供应商)-商品明细导出的标题
     * @return
     */
    private String [] goodsTitles(){
        String [] titles = {"ID","订单编号","三方单号","业务平台","运营商","项目名称","企业名称"
                ,"下单人id","下单人姓名","下单人手机号码","订单类型","业务类型","订单时间"
                ,"支付/退款时间","发货时间","完成时间","商品类型","商品id","商品名称"
                ,"商品编码","商品规格","一级分类","二级分类","三级分类","商品数量"
                ,"商品单位","商品原单价","商品原总价","商品销售单价","商品销售总价"
                ,"商品成本单价","商品成本总价","优惠金额","订单金额","结算金额","交易状态",
                "订单状态","售后类型","支付方式","收货地址","快递公司","快递单号"
                ,"退单原单号","供应商名称","成本单价","成本总价","更新时间"};
        return titles;
    }


    /**
     * 导出账单(含供应商)-商品明细导出的字段
     * @return
     */
    private String [] goodsFiled(){
        String [] fileds = {"id","orderNumber","thirdNo","bizPlatfrom","operatorName","orgName","virtName"
                ,"createdBy","createdName","createdMobile","orderType","businessType"
                ,"orderTime","operateTime","deliveryTime","finishTime","goodsType","goodsId"
                ,"goodsName","goodsCode","goodsSpecs","firstClassify","secondClassify"
                ,"threeClassify","goodsQuantity","goodsUnit","goodsPrice","goodsSumPrice"
                ,"goodsSalePrice","goodsSumSalePrice","goodsCostPrice","goodsSumCostPrice"
                ,"discountPrice","orderPrice","settlementPrice","transactionStatus","orderStatus"
                ,"afterSaleType","payWay","address","expressCompany","expressNo"
                ,"chargebackNo","supplierName","costPrice","sumCostPrice","updatedTime"};
        return fileds;
    }


    /**
     * 流水导出的标题
     * @return
     */
    private String [] waterTitles(){
        String [] titles = {"ID","订单编号","业务平台","运营商","项目名称","企业名称"
                ,"下单人id","下单人姓名","下单人手机号码","订单类型","业务类型"
                ,"订单时间","支付/退款时间","完成时间","商品类型","商品id"
                ,"商品名称","订单金额（用户实际支付/退款金额）","是否参与结算"
                ,"交易状态","支付方式","积分类型","积分批次","退单原单号"
                ,"供应商名称","更新时间"
        };
        return titles;
    }

    /**
     * 流水导出的字段
     * @return
     */
    private String [] waterFiled(){
        String [] fileds = {"id","orderNumber","bizPlatfrom","operatorName","orgName","virtName"
                ,"createdBy","createdName","createdMobile","orderType","businessType"
                ,"orderTime","operateTime","finishTime","goodsType","goodsId"
                ,"goodsName","orderPrice","isJoinSettlement","transactionStatus"
                ,"payWay","integralType","integralBatch"
                ,"chargebackNo","supplierName","updatedTime"};
        return fileds;
    }

    /**
     * 导出的代码中标题需要以这种格式进行传递，因此做了封装
     * @param billVo 基础数据
     * @param titles 所有标题
     * @return 最终封装好导出所需格式的标题
     */
    private List<List<String>> heads(BillVo billVo,String [] titles){
        List<List<String>> headList = new ArrayList<>();
        List<String> list = getTitles(billVo,titles);
        for(String title : list){
            headList.add(Lists.newArrayList(title));
        }
        return headList;
    }

    private Map<String,List<String>> getNotRange(BillVo billVo){
        Map<String,List<String>> map = new HashMap<>();
        List<RangeRuleVo> rangeRuleVoList = billVo.getRangeRuleVoList();
        if(CollectionUtils.isEmpty(rangeRuleVoList)){
            return map;
        }
        for(RangeRuleVo ruleVo : rangeRuleVoList){
            if(SettlementRangeWayEnum.指定供应商.getKey().equals(ruleVo.getWay())){
                List<String> strings = new ArrayList<>(Arrays.asList(ruleVo.getNotJoiningRange().split(",")));
                map.put("supplierNames",strings);
            }else if(SettlementRangeWayEnum.指定订单类型.getKey().equals(ruleVo.getWay())){
                List<String> strings = new ArrayList<>(Arrays.asList(ruleVo.getNotJoiningRange().split(",")));
                map.put("orderTypes",strings);
            }
        }
        return map;
    }


    /**
     * 导出的列表相应的做控制及数据控制
     * @param list
     * @param billVo
     * @param field
     * @return
     */
    private List<List<Object>> dataList(List<GoodsVo> list,BillVo billVo,String [] field){
        List<List<Object>> dataList = new ArrayList<>();
        String exportField = billVo.getExportField();
        if(StringUtils.isEmpty(exportField)){
            return dataList;
        }
        SettlementExportFieldVo fieldVo = JSON.parseObject(exportField, SettlementExportFieldVo.class);
        if(null == fieldVo){
            return dataList;
        }

        Map<String,List<String>> notRangeMap = new HashMap<>();
        if(SupnameDisplayRuleEnum.部分按原供应商名称导出.getKey().equals(billVo.getSupnameDisplayRule())){
            notRangeMap = getNotRange(billVo);
        }

        for(GoodsVo vo : list){
            List<Object> row = new ArrayList<>();
            JSONObject obj = JSONObject.fromObject(vo);
            for (int j = 0; j < field.length; j++) {
                Object param = "";
                if (StringUtils.isEmpty(field[j])) {
                    param = "";
                } else {
                    param = obj.get(field[j]);
                    //改变供应商值
                    if("supplierName".equals(field[j]) && SupnameDisplayRuleEnum.全部按自定义供应商名称导出.getKey().equals(billVo.getSupnameDisplayRule())){
                        param = billVo.getCustomSupplierName();
                    }else if("supplierName".equals(field[j]) && SupnameDisplayRuleEnum.部分按原供应商名称导出.getKey().equals(billVo.getSupnameDisplayRule())){
                        //获取订单类型的值，获取供应商的值 和不包含范围表中关联的数据进行判断   unified_settlement_programme_range_rule
                        //判断该供应商是否在  排除范围内，在的话，则不改变这部分的供应商名称，其余的改变
                        if(checkNotRange(notRangeMap,"supplierNames",vo.getSupplierName()+"("+vo.getBizPlatfrom()+")")){
                            param = billVo.getCustomSupplierName();
                        }
                        if(checkNotRange(notRangeMap,"orderTypes",vo.getOrderType())){
                            //判断该订单类型是否在  排除范围内，在的话，则不改变这部分的供应商名称，其余的改变
                            param = billVo.getCustomSupplierName();
                        }
                    }
                }
                if(checkFildValue(field[j],fieldVo)){
                    row.add(param);
                }
            }
            dataList.add(row);
        }
        return dataList;
    }

    /**
     *
     * @param notRangeMap  数据库查询到的不包含的范围
     * @param filed 不包含范围的类型字段名   是供应商(supplierNames)还是订单类型(orderTypes)
     * @param value  原先的值
     * @return false=不用换成自定义的值，true=需要换成自定义的值
     */
    private boolean checkNotRange(Map<String,List<String>> notRangeMap,String filed,Object value){
        if(null != notRangeMap && notRangeMap.containsKey(filed) && null != notRangeMap.get(filed)){
            List<String> fileds = notRangeMap.get(filed);
            if(CollectionUtils.isNotEmpty(fileds) && fileds.contains(value)){
                return false;//不改变供应商名称
            }
        }
        return true;
    }

    /**
     * 获取导出的标题  主要是对需要控制的字段做相应的处理
     * @param billVo 基础数据
     * @param titles 所有标题
     * @return 最终展示的标题
     */
    private List<String> getTitles(BillVo billVo,String [] titles){
        List<String> list = new ArrayList<>();
        String exportField = billVo.getExportField();
        if(StringUtils.isEmpty(exportField)){
            return list;
        }
        SettlementExportFieldVo fieldVo = JSON.parseObject(exportField, SettlementExportFieldVo.class);
        if(null == fieldVo){
            return list;
        }
        for(int i=0 ; i < titles.length; i++){
            String title = titles[i];
            boolean bool = checkFildHide(title,fieldVo);
            if(bool){
                list.add(title);
            }
        }
        return list;
    }

    /**
     * 检验是否需要展示这个值
     * @param fild
     * @param fieldVo
     * @return
     */
    private boolean checkFildValue(String fild,SettlementExportFieldVo fieldVo){
        if("orgName".equals(fild)){
            if(fieldVo.getOrg_name().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        if("virtName".equals(fild)){
            if(fieldVo.getVirt_name().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        if("supplierName".equals(fild)){
            if(fieldVo.getSupplier_name().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        if("thirdNo".equals(fild)){
            if(fieldVo.getThird_no().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        if("goodsCostPrice".equals(fild)){
            if(fieldVo.getAgreement_cost().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        if("goodsSumCostPrice".equals(fild)){
            if(fieldVo.getAgreement_cost().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        if("integralType".equals(fild)){
            if(fieldVo.getIntegral().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        if("integralBatch".equals(fild)){
            if(fieldVo.getIntegral().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        return true;
    }

    /**
     * 检验是否需要展示这个标题
     * @param title
     * @param fieldVo
     * @return
     */
    private boolean checkFildHide(String title,SettlementExportFieldVo fieldVo){
        if("项目名称".equals(title)){
            if(fieldVo.getOrg_name().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        if("企业名称".equals(title)){
            if(fieldVo.getVirt_name().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        if("供应商名称".equals(title)){
            if(fieldVo.getSupplier_name().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        if("三方单号".equals(title)){
            if(fieldVo.getThird_no().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        if("商品成本单价".equals(title)){
            if(fieldVo.getAgreement_cost().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        if("商品成本总价".equals(title)){
            if(fieldVo.getAgreement_cost().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        if("积分类型".equals(title)){
            if(fieldVo.getIntegral().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        if("积分批次".equals(title)){
            if(fieldVo.getIntegral().equals(1)){
                return true;
            }else{
                return false;
            }
        }
        return true;
    }

    // -------------------------------导出数据做优化     开始---------------------------


    @Override
    public AccountingBillVo getBillVo(Long id) {
        return getAccountBillById(id);
    }

    private AccountingBillVo getAccountBillById(Long id){
        AccountingUnifiedOperatorQueryParam param = new AccountingUnifiedOperatorQueryParam();
        param.setId(id);
        List<AccountingUnifiedOperatorVo> list = getAccountingList(param);
        if(CollectionUtils.isEmpty(list)){
            return null;
        }
        AccountingBillVo billVo = new AccountingBillVo();
        AccountingUnifiedOperatorVo accountInfoVo = list.get(0);
        billVo.setAVo(accountInfoVo);
        if(null != accountInfoVo && null != accountInfoVo.getInvoiceTitleId()){
            UnifiedCustomerInvoiceTitle billStart = unifiedBillStartMapper.selectByPrimaryKey(accountInfoVo.getInvoiceTitleId());
            if(null != billStart){
                PurchaserVo purchaserVo = new PurchaserVo();
                BeanUtils.copyProperties(billStart,purchaserVo);
                billVo.setOVo(purchaserVo);
            }
        }
        if(null != accountInfoVo && null != accountInfoVo.getSettlementPlanId()){
            UnifiedSettlementProgramme settlementProgramme = unifiedSettlementProgrammeMapper.selectByPrimaryKey(accountInfoVo.getSettlementPlanId());
            if(null != settlementProgramme){
                SettlementProgrammeVo programmeVo = new SettlementProgrammeVo();
                BeanUtils.copyProperties(settlementProgramme,programmeVo);
                programmeVo.setCustomerName(accountInfoVo.getCustomerName());
                programmeVo.setExportBillName(settlementProgramme.getBillName());
                billVo.setSVo(programmeVo);
            }
        }
        return billVo;
    }
}
