package com.ruoyi.logistics.service.impl;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.datascope.annotation.DataScope;
import com.ruoyi.logistics.callback.SfFeePushCallback;
import com.ruoyi.logistics.domain.BizFinancialAdjustmentRecord;
import com.ruoyi.logistics.domain.SysDeptRate;
import com.ruoyi.logistics.mapper.BizFinancialAdjustmentRecordMapper;
import com.ruoyi.logistics.mapper.BizWaybillOrderMapper;
import com.ruoyi.logistics.mapper.SysDeptRateMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.logistics.mapper.RptFinancialMonthSummaryMapper;
import com.ruoyi.logistics.domain.RptFinancialMonthSummary;
import com.ruoyi.logistics.service.IRptFinancialMonthSummaryService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 财务月度汇总Service业务层处理
 * 
 * @author RuiJing
 * @date 2026-01-29
 */
@Service
public class RptFinancialMonthSummaryServiceImpl implements IRptFinancialMonthSummaryService
{
    private static final Logger logger = LoggerFactory.getLogger(RptFinancialMonthSummaryServiceImpl.class);
    @Autowired
    private RptFinancialMonthSummaryMapper rptFinancialMonthSummaryMapper;
    @Autowired
    private SysDeptRateMapper sysDeptRateMapper;
    @Autowired
    private BizWaybillOrderMapper bizWaybillOrderMapper;
    /**
     * 查询财务月度汇总
     * 
     * @param summaryId 财务月度汇总主键
     * @return 财务月度汇总
     */
    @Override
    public RptFinancialMonthSummary selectRptFinancialMonthSummaryBySummaryId(Long summaryId)
    {
        return rptFinancialMonthSummaryMapper.selectRptFinancialMonthSummaryBySummaryId(summaryId);
    }

    /**
     * 查询财务月度汇总列表
     * 
     * @param rptFinancialMonthSummary 财务月度汇总
     * @return 财务月度汇总
     */
    @Override
    @DataScope(deptAlias = "d")
    public List<RptFinancialMonthSummary> selectRptFinancialMonthSummaryList(RptFinancialMonthSummary rptFinancialMonthSummary)
    {
        return rptFinancialMonthSummaryMapper.selectRptFinancialMonthSummaryList(rptFinancialMonthSummary);
    }


    @Override
    public int insertRptFinancialMonthSummary(RptFinancialMonthSummary rptFinancialMonthSummary)
    {

        return rptFinancialMonthSummaryMapper.insertRptFinancialMonthSummary(rptFinancialMonthSummary);

    }

    /**
     * 修改财务月度汇总
     * 
     * @param rptFinancialMonthSummary 财务月度汇总
     * @return 结果
     */
    @Override
    public int updateRptFinancialMonthSummary(RptFinancialMonthSummary rptFinancialMonthSummary)
    {
        rptFinancialMonthSummary.setUpdateTime(DateUtils.getNowDate());
        return rptFinancialMonthSummaryMapper.updateRptFinancialMonthSummary(rptFinancialMonthSummary);
    }

    /**
     * 批量删除财务月度汇总
     * 
     * @param summaryIds 需要删除的财务月度汇总主键
     * @return 结果
     */
    @Override
    public int deleteRptFinancialMonthSummaryBySummaryIds(Long[] summaryIds)
    {
        return rptFinancialMonthSummaryMapper.deleteRptFinancialMonthSummaryBySummaryIds(summaryIds);
    }

    /**
     * 删除财务月度汇总信息
     * 
     * @param summaryId 财务月度汇总主键
     * @return 结果
     */
    @Override
    public int deleteRptFinancialMonthSummaryBySummaryId(Long summaryId)
    {
        return rptFinancialMonthSummaryMapper.deleteRptFinancialMonthSummaryBySummaryId(summaryId);
    }



    /**
     这个专门为上个月没有发生已签收供应商进行数据记录

     直接将所有供应商生成插入
     */
    @Override
    public void creatMontSummaryZero(Map param) {
        List<Map<String,Object>> monthSummaryList=rptFinancialMonthSummaryMapper.selectAllDeptMonthSummaryList(param);
        if (CollectionUtils.isNotEmpty(monthSummaryList)) {
            rptFinancialMonthSummaryMapper.insertBachRptFinancialMonthSummary(monthSummaryList);
        }
    }


    /**
     * 新增财务月度汇总   这个方法针对  月度账单任务  和 重新计算
     * 1.定时任务执行所有供应商生成财务月度汇总    传值汇总月份  monthCode
     * 2.重新计算   传值部门id    deptId
     *  部门Id和 账单月份必传其一  分别代表以上两种情况
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int creatMontSummary( Map param) {
        LocalDate today = LocalDate.now();
        LocalDate lastMonth = today.minusMonths(1);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM");
        // 格式化上个月日期为字符串
        String defaultMonth = lastMonth.format(formatter);

        Object deptIdObj = param.get("deptId");
        String deptId = (deptIdObj == null) ? null : deptIdObj.toString();
        Object monthCodeObj = param.get("monthCode");
        String monthCode = (monthCodeObj == null) ? null : monthCodeObj.toString();
        if (monthCode == null) {
            monthCode = defaultMonth;
        }
        //按照传值条件查询统计账单情况  默认给时间 是因为生成月份 供应商是要去生成哪个以及重新计算
        param.put("monthCode",monthCode);
        param.put("deptId",deptId);

        if(StringUtils.isNotBlank(deptId)){
            if(!verification(param.get("monthCode").toString(),deptId)){
                logger.info("该供应商月份内已对账之后状态  无法重新计算或定时重新生成月度账单 - 供应商id: {}, 月度: {}",deptId,monthCode);
                return 0;
            }
        }


        /*计算区间金额
        * 月份
        * 供应商id
        * */
        List<Map<String,Object>> monthSummaryGroupProductList=rptFinancialMonthSummaryMapper.selectMonthSummaryGroupProductList(param);
        for (Map<String, Object> map : monthSummaryGroupProductList) {
             // 拿到当前供应商 配置的 物流公司  产品类型  ,以下四个参数不能为空  为空跳过循环 执行下一条数据
            String payableAmount = Objects.toString(map.get("payable_amount"), "");
            String orderType = Objects.toString(map.get("order_type"), "");
            String productCode = Objects.toString(map.get("product_code"), "");
            String currentDeptId = Objects.toString(map.get("dept_id"), "");
            if (StringUtils.isAnyBlank(payableAmount, orderType, productCode, currentDeptId)) {
                continue;
            }

            // 校验当前部门和月份是否已经存在账单且状态为已对账
           if(!verification(monthCode,currentDeptId)){
               logger.info("该供应商月份内已对账之后状态  或已调账    无法重新生成月度账单 - 供应商id: {}, 月度: {}",currentDeptId,monthCode);
               continue;
           }
            //拿到当前供应商 配置的 物流公司  产品类型  区间内的 折扣值
            Map rateParam= new HashMap();
            rateParam.put("payableAmount",payableAmount);
            rateParam.put("companyType",orderType);
            rateParam.put("productCode",productCode);
            rateParam.put("deptId",currentDeptId);
            rateParam.put("monthCode",monthCode);
            List<Map<String,Object>> list= sysDeptRateMapper.findSysDeptRateList(rateParam);
            //还要查一下该供应商 物流公司  产品类型 下的配置  按照结束区间倒叙  或者只取一条
            List<Map<String,Object>> listRate= sysDeptRateMapper.findSysDeptRateListByDept(rateParam);
            //先看看这个供应商这个物流公司 这个产品类型 有没有配置折扣
            if(listRate.size()!=0){
                //再看区间内有没有
                if(list.size()==1){
                    rateParam.put("rate",list.get(0).get("rate"));
                    bizWaybillOrderMapper.updateRateByMonthAndDept(rateParam);
                }
                //区间没有  那就拿查到的产品类型 最大的一条
                else{
                    rateParam.put("rate",listRate.get(0).get("rate"));
                    bizWaybillOrderMapper.updateRateByMonthAndDept(rateParam);
                }
            }
            else{
             //这个供应商该产品下  没配置
                logger.info("该供应商未配置该产品折扣信息 - 供应商id: {}, 物流公司: {}, 产品类型: {}",currentDeptId,orderType.equals("1")?"京东":"顺丰",productCode);
                rateParam.put("rate",10.00);
                bizWaybillOrderMapper.updateRateByMonthAndDept(rateParam);
            }
        }
        List<Map<String,Object>> monthSummaryList=rptFinancialMonthSummaryMapper.selectMonthSummaryList(param);
        if (CollectionUtils.isNotEmpty(monthSummaryList)) {
            rptFinancialMonthSummaryMapper.insertBachRptFinancialMonthSummary(monthSummaryList);
        }
            return 1;

    }



    /*校验供应商该月份内是否可以重新计算
    已对账 已开票 回传商城  不能重新计算 false
    待对账    可以重新计算     true
     */
    @Autowired
    private BizFinancialAdjustmentRecordMapper bizFinancialAdjustmentRecordMapper;
    public boolean verification(String monthCode,String deptId){
        if (StringUtils.isBlank(monthCode) || StringUtils.isBlank(deptId)) {
            return false;
        }
        try {
            RptFinancialMonthSummary summary = new RptFinancialMonthSummary();
            summary.setDeptId(Long.valueOf(deptId));
            summary.setSummaryMonth(monthCode);
            List<RptFinancialMonthSummary> listMonth=rptFinancialMonthSummaryMapper.selectRptFinancialMonthSummaryList(summary);
            //还要检查下   这个供应商  这个月份  有没有调账记录  去调账记录表中查询
            if(listMonth.size()>=1){
                if("1".equals(listMonth.get(0).getStatus())){
                    BizFinancialAdjustmentRecord bizFinancialAdjustmentRecord= new BizFinancialAdjustmentRecord();
                    bizFinancialAdjustmentRecord.setDeptId(Long.valueOf(deptId));
                    bizFinancialAdjustmentRecord.setSummaryMonth(monthCode);
                    int adjustmentTotal= bizFinancialAdjustmentRecordMapper.selectBizFinancialAdjustmentRecordListNoPermission(bizFinancialAdjustmentRecord).size();
                    if (adjustmentTotal>0){
                        return false;
                    }
                    return true;
                }
                return false;
             }
            return true;
        } catch (Exception e) {
            logger.error("校验状态异常", e);
            return false;
        }
    }




    @Override
    public int creatMontSummaryAccountAdjustment( Map param) {
        LocalDate today = LocalDate.now();
        LocalDate lastMonth = today.minusMonths(1);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM");
        // 格式化上个月日期为字符串
        String formattedDate = lastMonth.format(formatter);
        //按照传值条件查询统计账单情况
        param.put("monthCode",StringUtils.isNotBlank(param.get("monthCode").toString())?param.get("monthCode").toString():formattedDate);
        param.put("deptId", StringUtils.isNotBlank(param.get("deptId").toString())?param.get("deptId").toString():null);
        List<Map<String,Object>> monthSummaryList=rptFinancialMonthSummaryMapper.selectMonthSummaryList(param);
        if(monthSummaryList.size()==0){
            return 0;
        }
        return rptFinancialMonthSummaryMapper.insertBachRptFinancialMonthSummary(monthSummaryList);
    }


    @Override
    public List<RptFinancialMonthSummary> selectRptFinancialMonthSummaryListToCheck(RptFinancialMonthSummary rptFinancialMonthSummary) {
        return rptFinancialMonthSummaryMapper.selectRptFinancialMonthSummaryListToCheck(rptFinancialMonthSummary);
    }

    @Override
    public int updateRptFinancialMonthSummaryByInvoice(RptFinancialMonthSummary rptFinancialMonthSummary) {
        rptFinancialMonthSummary.setUpdateTime(DateUtils.getNowDate());
        return rptFinancialMonthSummaryMapper.updateRptFinancialMonthSummaryByInvoice(rptFinancialMonthSummary);
    }
}
