package com.ruoyi.bst.reconciliationDate.service.impl;

import java.time.LocalDate;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.bst.bonus.service.BonusDashboard;
import com.ruoyi.bst.bonusRefund.service.BonusRefundDashboard;
import com.ruoyi.bst.channel.domain.vo.ChannelNameVO;
import com.ruoyi.bst.pay.domain.PayQuery;
import com.ruoyi.bst.pay.domain.enums.PayBstType;
import com.ruoyi.bst.pay.domain.enums.PayStatus;
import com.ruoyi.bst.pay.service.PayDashboard;
import com.ruoyi.bst.reconciliationDate.domain.ReconciliationDate;
import com.ruoyi.bst.reconciliationDate.domain.ReconciliationDateQuery;
import com.ruoyi.bst.reconciliationDate.domain.ReconciliationDateVO;
import com.ruoyi.bst.reconciliationDate.mapper.ReconciliationDateMapper;
import com.ruoyi.bst.reconciliationDate.service.ReconciliationDateService;
import com.ruoyi.bst.reconciliationDate.utils.ReconciliationDateUtil;
import com.ruoyi.bst.refund.domain.RefundQuery;
import com.ruoyi.bst.refund.service.RefundDashboard;
import com.ruoyi.common.domain.vo.StringDecimalVO;
import com.ruoyi.common.utils.MathUtils;
import com.ruoyi.common.utils.collection.CollectionUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 渠道对账Service业务层处理
 *
 * @author ruoyi
 * @date 2025-04-23
 */
@Service
@Slf4j
public class ReconciliationDateServiceImpl implements ReconciliationDateService
{
    @Autowired
    private ReconciliationDateMapper reconciliationDateMapper;

    @Autowired
    private PayDashboard payDashboard;

    @Autowired
    private RefundDashboard refundDashboard;

    @Autowired
    private BonusDashboard bonusDashboard;

    @Autowired
    private BonusRefundDashboard bonusRefundDashboard;

    /**
     * 查询渠道对账
     *
     * @param id 渠道对账主键
     * @return 渠道对账
     */
    @Override
    public ReconciliationDateVO selectReconciliationDateById(Long id)
    {
        return reconciliationDateMapper.selectReconciliationDateById(id);
    }

    /**
     * 查询渠道对账列表
     *
     * @param reconciliationDate 渠道对账
     * @return 渠道对账
     */
    @Override
    public List<ReconciliationDateVO> selectReconciliationDateList(ReconciliationDateQuery reconciliationDate)
    {
        return reconciliationDateMapper.selectReconciliationDateList(reconciliationDate);
    }

    /**
     * 新增渠道对账
     *
     * @param reconciliationDate 渠道对账
     * @return 结果
     */
    @Override
    public int insertReconciliationDate(ReconciliationDate reconciliationDate)
    {
        return reconciliationDateMapper.insertReconciliationDate(reconciliationDate);
    }

    /**
     * 修改渠道对账
     *
     * @param reconciliationDate 渠道对账
     * @return 结果
     */
    @Override
    public int updateReconciliationDate(ReconciliationDate reconciliationDate)
    {
        return reconciliationDateMapper.updateReconciliationDate(reconciliationDate);
    }

    /**
     * 批量删除渠道对账
     *
     * @param ids 需要删除的渠道对账主键
     * @return 结果
     */
    @Override
    public int deleteReconciliationDateByIds(Long[] ids)
    {
        return reconciliationDateMapper.deleteReconciliationDateByIds(ids);
    }

    /**
     * 删除渠道对账信息
     *
     * @param id 渠道对账主键
     * @return 结果
     */
    @Override
    public int deleteReconciliationDateById(Long id)
    {
        return reconciliationDateMapper.deleteReconciliationDateById(id);
    }

    @Override
    public int insertReconciliationDate(LocalDate date, ChannelNameVO channel, Long areaId) {
        if (date == null || channel == null || channel.getChannelId() == null) {
            return 0;
        }
        ReconciliationDate po = new ReconciliationDate();
        po.setDate(date);
        po.setChannelId(channel.getChannelId());
        po.setChannelName(channel.getName());
        po.setAreaId(areaId);

        // 查询支付
        PayQuery payQuery = new PayQuery();
        payQuery.setPayDate(date);
        payQuery.setChannelId(channel.getChannelId());
        payQuery.setAreaId(areaId);
        payQuery.setStatusList(PayStatus.payedList());

        // 渠道成本
        po.setChannelCost(payDashboard.selectSumOfChannelCost(payQuery));

        // 各个业务支付金额
        List<StringDecimalVO> payedAmountList = payDashboard.selectSumOfPayedAmountGroupByBstType(payQuery);
        po.setOrderPayAmount(payedAmountList.stream()
            .filter(item -> item.getKey().equals(PayBstType.ORDER_RIDE.getType()))
            .findFirst().orElse(new StringDecimalVO()).getValue());
        po.setVipPayAmount(payedAmountList.stream()
            .filter(item -> item.getKey().equals(PayBstType.VIP_ORDER.getType()))
            .findFirst().orElse(new StringDecimalVO()).getValue());
        po.setDepositPayAmount(payedAmountList.stream()
            .filter(item -> item.getKey().equals(PayBstType.ORDER.getType()))
            .findFirst().orElse(new StringDecimalVO()).getValue());


        // 各个业务退款金额
        RefundQuery refundQuery = new RefundQuery();
        refundQuery.setCreateDate(date);
        refundQuery.setChannelId(channel.getChannelId());
        refundQuery.setPayAreaId(areaId);

        List<StringDecimalVO> refundAmountList = refundDashboard.selectSumOfAmountGroupByBstType(refundQuery);
        po.setOrderRefundAmount(refundAmountList.stream()
            .filter(item -> item.getKey().equals(PayBstType.ORDER_RIDE.getType()))
            .findFirst().orElse(new StringDecimalVO()).getValue());
        po.setVipRefundAmount(refundAmountList.stream()
            .filter(item -> item.getKey().equals(PayBstType.VIP_ORDER.getType()))
            .findFirst().orElse(new StringDecimalVO()).getValue());
        po.setDepositRefundAmount(refundAmountList.stream()
            .filter(item -> item.getKey().equals(PayBstType.ORDER.getType()))
            .findFirst().orElse(new StringDecimalVO()).getValue());

        // 各个业务实收
        po.setOrderActualAmount(MathUtils.subtractDecimal(po.getOrderPayAmount(), po.getOrderRefundAmount()));
        po.setVipActualAmount(MathUtils.subtractDecimal(po.getVipPayAmount(), po.getVipRefundAmount()));
        po.setDepositActualAmount(MathUtils.subtractDecimal(po.getDepositPayAmount(), po.getDepositRefundAmount()));

        // 支付总金额
        po.setPayAmount(CollectionUtils.sumDecimal(payedAmountList, StringDecimalVO::getValue));
        // 退款总金额
        po.setRefundAmount(CollectionUtils.sumDecimal(refundAmountList, StringDecimalVO::getValue));
        // 实收总金额
        po.setActualAmount(MathUtils.subtractDecimal(po.getPayAmount(), po.getRefundAmount()));

        if (ReconciliationDateUtil.isEmpty(po)) {
            log.error("渠道对账数据为空，date={}, channel={}, areaId={}", date, channel, areaId);
            return 0;
        }

        return this.insertReconciliationDate(po);
    }

    @Override
    public List<ReconciliationDateVO> selectReconciliationDateListGroupBy(ReconciliationDateQuery query, String groupBy) {
        return reconciliationDateMapper.selectReconciliationDateListGroupBy(query, groupBy);
    }

}
