/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package com.unis.financialSupervision.modular.fsEnterpriseBalanceStatistic.service.impl;

import cn.afterturn.easypoi.cache.manager.POICacheManager;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.unis.common.exception.CommonException;
import com.unis.common.util.CommonDownloadUtil;
import com.unis.common.util.CommonResponseUtil;
import com.unis.financialSupervision.modular.fsEnterpriseBalanceStatistic.entity.FsEnterpriseBalanceStatistic;
import com.unis.financialSupervision.modular.fsEnterpriseBalanceStatistic.entity.VO.CostBalanceVO;
import com.unis.financialSupervision.modular.fsEnterpriseBalanceStatistic.entity.VO.FsEnterpriseBalanceStatisticVO;
import com.unis.financialSupervision.modular.fsEnterpriseBalanceStatistic.entity.VO.UnitAndOrgTreeVO;
import com.unis.financialSupervision.modular.fsEnterpriseBalanceStatistic.mapper.FsEnterpriseBalanceStatisticMapper;
import com.unis.financialSupervision.modular.fsEnterpriseBalanceStatistic.param.CostBalanceParam;
import com.unis.financialSupervision.modular.fsEnterpriseBalanceStatistic.param.FsEnterpriseBalanceStatisticPageParam;
import com.unis.financialSupervision.modular.fsEnterpriseBalanceStatistic.param.FsEnterpriseBalanceStatisticWarinPageParam;
import com.unis.financialSupervision.modular.fsEnterpriseBalanceStatistic.service.FsEnterpriseBalanceStatisticService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.List;

/**
 * 财务监管-企业收支结余统计表Service接口实现类
 *
 * @author TS
 * @date  2024/06/26 11:23
 **/
@Service
public class FsEnterpriseBalanceStatisticServiceImpl extends ServiceImpl<FsEnterpriseBalanceStatisticMapper, FsEnterpriseBalanceStatistic> implements FsEnterpriseBalanceStatisticService {
    @Resource
    private FsEnterpriseBalanceStatisticMapper fsEnterpriseBalanceStatisticMapper;

    /**
     * *● 财务监管-企业收支结余统计表
     * *     ○ 频率：一天执行一次。
     * *     ○ 功能：统计当月储备规模，无储备规模数据则不进行统计
     *
     * @author TS
     * @date 2024/06/26 11:23
     */
    @Override
    public void taskAction() {
        Integer  year = DateUtil.thisYear(); //本年
        Integer  month = DateUtil.thisMonth()+1; //本月
        //得到本月储备规模数据
        List<FsEnterpriseBalanceStatistic> balanceStatisticList = fsEnterpriseBalanceStatisticMapper.getReserveScaleList(year,month);
        if (balanceStatisticList.size() <=0){ //无数据
            return;
        }
        for (FsEnterpriseBalanceStatistic balanceStatistic:balanceStatisticList) {
            Integer orgId = balanceStatistic.getOrgId();
            Integer grainVarietyId = balanceStatistic.getGrainVarietyId();


            //保管费只进行本年累计，如果月份为0，则不获取上月累计数据
            BigDecimal storageCostAccrued = BigDecimal.ZERO;
            BigDecimal storageCostExpenditure = BigDecimal.ZERO;
            BigDecimal storageCostBalance = BigDecimal.ZERO;
            Integer storageCostOverdraftMonth = 0; //保管费超支月数
            //轮换费只进行本年累计，如果月份为0，则不获取上月累计数据
            BigDecimal rotationCostAccrued = BigDecimal.ZERO;
            BigDecimal rotationCostExpenditure = BigDecimal.ZERO;
            BigDecimal rotationCostBalance = BigDecimal.ZERO;
            Integer rotationCostOverdraftMonth = 0; //轮换费超支月数
            if (month != 1){
                //查询上月数据
                QueryWrapper<FsEnterpriseBalanceStatistic> preQueryWrapper = new QueryWrapper<>();
                preQueryWrapper.lambda()
                        .eq(FsEnterpriseBalanceStatistic::getOrgId,orgId)
                        .eq(FsEnterpriseBalanceStatistic::getPlanYear,year)
                        .eq(FsEnterpriseBalanceStatistic::getMonth,month-1)
                        .eq(FsEnterpriseBalanceStatistic::getGrainVarietyId,grainVarietyId);
                FsEnterpriseBalanceStatistic balanceStatistic_pre = super.getOne(preQueryWrapper,false);
                if (balanceStatistic_pre !=null){
                    //保管费相关
                    storageCostAccrued = balanceStatistic_pre.getStorageCostAccrued();
                    storageCostExpenditure = balanceStatistic_pre.getStorageCostExpenditure();
                    storageCostOverdraftMonth = balanceStatistic_pre.getStorageCostOverdraftMonth();
                    //轮换费相关
                    rotationCostAccrued = balanceStatistic_pre.getRotationCostAccrued();
                    rotationCostExpenditure = balanceStatistic_pre.getRotationCostExpenditure();
                    rotationCostOverdraftMonth = balanceStatistic_pre.getRotationCostOverdraftMonth();

                }
                //获取本月保管费用相关数据
                FsEnterpriseBalanceStatistic storageCost = fsEnterpriseBalanceStatisticMapper.getStorageCostAccrued(orgId,grainVarietyId);
                if (storageCost != null){
                    storageCostAccrued = NumberUtil.add(storageCostAccrued,storageCost.getStorageCostAccrued());
                    storageCostExpenditure = NumberUtil.add(storageCostExpenditure,storageCost.getStorageCostExpenditure());
                    storageCostBalance = NumberUtil.sub(storageCostAccrued,storageCostExpenditure); //负数为超支
                    balanceStatistic.setStorageCostOverdraftWarning(1); //未超支
                    if (NumberUtil.compare(storageCostBalance.doubleValue(),0.0) <0){
                        storageCostOverdraftMonth +=1; //
                        balanceStatistic.setStorageCostOverdraftWarning(2); //超支
                    }
                    balanceStatistic.setStorageCostAccrued(storageCostAccrued);
                    balanceStatistic.setStorageCostExpenditure(storageCostExpenditure);
                    balanceStatistic.setStorageCostBalance(storageCostBalance);
                    balanceStatistic.setRotationCostOverdraftMonth(storageCostOverdraftMonth);
                }
                //得到轮换计划数据，及本月轮换出库，入库轮换金额
                FsEnterpriseBalanceStatistic rotationPlan = fsEnterpriseBalanceStatisticMapper.getRotationPlan(orgId,grainVarietyId,year,month);
                if (rotationPlan != null){
                    balanceStatistic.setRotationPlanQuantity(rotationPlan.getRotationPlanQuantity()); //轮换计划数量
                    balanceStatistic.setRotationCompletionRate(rotationPlan.getRotationCompletionRate()); //轮换完成率
                    balanceStatistic.setRotationCostStandard(rotationPlan.getRotationCostStandard()); //轮换费用标准
                    rotationCostAccrued = NumberUtil.add(rotationCostAccrued,rotationPlan.getRotationCostAccrued());
                    rotationCostExpenditure = NumberUtil.add(rotationCostExpenditure,rotationPlan.getRotationCostExpenditure());
                    rotationCostBalance = NumberUtil.sub(rotationCostAccrued,rotationCostExpenditure); //负数为超支
                    balanceStatistic.setRotationCostOverdraftWarning(1); //未 超支
                    if (NumberUtil.compare(rotationCostBalance.doubleValue(),0.0) <0){
                        rotationCostOverdraftMonth +=1; //
                        balanceStatistic.setRotationCostOverdraftWarning(2); //超支
                    }
                    balanceStatistic.setRotationCostAccrued(rotationCostAccrued);
                    balanceStatistic.setRotationCostExpenditure(rotationCostExpenditure);
                    balanceStatistic.setRotationCostBalance(rotationCostBalance);
                    balanceStatistic.setRotationCostOverdraftMonth(rotationCostOverdraftMonth);

                }
            }
            //进行保存,查询是 否 存在查询条件的数据
            QueryWrapper<FsEnterpriseBalanceStatistic> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(FsEnterpriseBalanceStatistic::getOrgId,orgId)
                    .eq(FsEnterpriseBalanceStatistic::getPlanYear,year)
                    .eq(FsEnterpriseBalanceStatistic::getMonth,month)
                    .eq(FsEnterpriseBalanceStatistic::getGrainVarietyId,grainVarietyId);
            FsEnterpriseBalanceStatistic balanceStatistic_old = super.getOne(queryWrapper,false);
            if (balanceStatistic_old != null){
                balanceStatistic.setId(balanceStatistic_old.getId());
            }
            this.saveOrUpdate(balanceStatistic);
        }

    }

    /**
     * 获取财务监管-企业收支结余统计表查询
     *
     * @param fsEnterpriseBalanceStatisticPageParam
     * @return
     */
    @Override
    public List<FsEnterpriseBalanceStatisticVO> getList(FsEnterpriseBalanceStatisticPageParam fsEnterpriseBalanceStatisticPageParam) {
        return fsEnterpriseBalanceStatisticMapper.getList(fsEnterpriseBalanceStatisticPageParam);
    }

    /**
     * 获取企业和库区树
     *
     * @return
     */
    @Override
    public UnitAndOrgTreeVO getUnitAndOgrTree() {
        //得到第一个
        UnitAndOrgTreeVO  root = fsEnterpriseBalanceStatisticMapper.getRootTree();
        if (root != null){
            //得到企业信息
            List<UnitAndOrgTreeVO>  unitList = fsEnterpriseBalanceStatisticMapper.getUnitList();
            if (unitList.size() >0) {
                for (UnitAndOrgTreeVO unitVo : unitList) {
                    //企业对应的库区信息
                    List<UnitAndOrgTreeVO>  orgList = fsEnterpriseBalanceStatisticMapper.getOrgList(unitVo.getId());
                    unitVo.setChild(orgList);
                }
                root.setChild(unitList);
            }
        }
        return root;
    }

    /**
     * 获取财务监管-企业收支结余统计风险预警自定义分页
     *
     * @param pageParam
     * @return
     */
    @Override
    public IPage<FsEnterpriseBalanceStatisticVO> findWarPage(FsEnterpriseBalanceStatisticWarinPageParam pageParam) {
            //条形查询器
            QueryWrapper<FsEnterpriseBalanceStatisticVO> queryWrapper = new QueryWrapper<>();
            //分页相关
            if(StringUtils.isNotBlank(pageParam.getUnitName())){
                queryWrapper.like("c.dwmc",pageParam.getUnitName() );
            }
            if(StringUtils.isNotBlank(pageParam.getOrgName())){
                queryWrapper.like("b.org_name",pageParam.getOrgName() );
            }
            if(StringUtils.isNotBlank(pageParam.getOrgId())){
                queryWrapper.eq("b.org_id",pageParam.getOrgId() );
            }
            if(StringUtils.isNotBlank(pageParam.getUnitId())){
                queryWrapper.eq("b.unit_info_id",pageParam.getUnitId() );
            }
            Page<FsEnterpriseBalanceStatisticVO> p =new Page<>(pageParam.getCurrent(),pageParam.getSize());
            IPage<FsEnterpriseBalanceStatisticVO> page = fsEnterpriseBalanceStatisticMapper.selectMyMapsPage(p,queryWrapper);
            return page;
    }

    /**
     * 获取财务监管-企业收支结余统计图表
     *
     * @param costBalanceParam
     * @return
     */
    @Override
    public List<CostBalanceVO> getCostBalanceList(CostBalanceParam costBalanceParam) {
        return fsEnterpriseBalanceStatisticMapper.getCostBalanceList(costBalanceParam);
    }

    /**
     * 省级粮油费用补贴收支结余情况表导出
     *
     * @param fsEnterpriseBalanceStatisticPageParam
     * @param response
     */
    @Override
    public void exportData(FsEnterpriseBalanceStatisticPageParam fsEnterpriseBalanceStatisticPageParam, HttpServletResponse response) throws IOException {
        File destTemplateFile = null;
            File tempFile = null;
            try {
                List<FsEnterpriseBalanceStatisticVO>  list = fsEnterpriseBalanceStatisticMapper.getList(fsEnterpriseBalanceStatisticPageParam);
                if(ObjectUtil.isEmpty(list)) {
                    throw new CommonException("无数据可导出");
                }
                //得到合计
                FsEnterpriseBalanceStatisticVO  total = new FsEnterpriseBalanceStatisticVO();
                {
                    total.setGrainVarietyName("合计");
                    total.setReservePlanQuantity(NumberUtil.toBigDecimal(0));
                    total.setRotationPlanQuantity(NumberUtil.toBigDecimal(0));
                    total.setStorageCostAccrued(NumberUtil.toBigDecimal(0));
                    total.setStorageCostExpenditure(NumberUtil.toBigDecimal(0));
                    total.setStorageCostBalance(NumberUtil.toBigDecimal(0));
                    total.setRotationCostAccrued(NumberUtil.toBigDecimal(0));
                    total.setRotationCostExpenditure(NumberUtil.toBigDecimal(0));
                    total.setRotationCostBalance(NumberUtil.toBigDecimal(0));

                    for (int i = 0; i <list.size() ; i++) {
                        FsEnterpriseBalanceStatisticVO vo = list.get(i);
                        total.setReservePlanQuantity(NumberUtil.add(total.getReservePlanQuantity(),vo.getReservePlanQuantity()));

                        total.setRotationPlanQuantity(NumberUtil.add(total.getRotationPlanQuantity(),vo.getRotationPlanQuantity()));

                        total.setStorageCostAccrued(NumberUtil.add(total.getStorageCostAccrued(),vo.getStorageCostAccrued()));
                        total.setStorageCostExpenditure(NumberUtil.add(total.getStorageCostExpenditure(),vo.getStorageCostExpenditure()));
                        total.setStorageCostBalance(NumberUtil.add(total.getStorageCostBalance(),vo.getStorageCostBalance()));

                        total.setRotationCostAccrued(NumberUtil.add(total.getRotationCostAccrued(),vo.getRotationCostAccrued()));
                        total.setRotationCostExpenditure(NumberUtil.add(total.getRotationCostExpenditure(),vo.getRotationCostExpenditure()));
                        total.setRotationCostBalance(NumberUtil.add(total.getRotationCostBalance(),vo.getRotationCostBalance()));

                    }
                }
                list.add(total);

                // 读取模板流
                InputStream inputStream = POICacheManager.getFile("fsEnterpriseBalanceStatistiExportTemplate.xlsx");
                // 创建一个临时模板
                destTemplateFile = FileUtil.writeFromStream(inputStream, FileUtil.file(FileUtil.getTmpDir() +
                        File.separator + "fsEnterpriseBalanceStatistiExportTemplate.xlsx"));

                String fileName = "省级粮油费用补贴收支结余情况表.xlsx";
                // 创建临时文件
                tempFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);

                // 写excel
                ExcelWriter excelWriter = EasyExcel.write(tempFile.getPath(), FsEnterpriseBalanceStatisticVO.class)
                        .withTemplate(destTemplateFile)
                        .build();
                WriteSheet writeSheet = EasyExcel.writerSheet().build();
                excelWriter.fill(list.get(0), writeSheet);
                excelWriter.fill(list,writeSheet);


                excelWriter.finish();

                CommonDownloadUtil.download(tempFile, response);
            } catch (Exception e) {
                log.error(">>> 导出异常：", e);
                CommonResponseUtil.renderError(response, e.getMessage());
            } finally {
                FileUtil.del(tempFile);
            }
    }

}


