package com.seer.teach.pay.app.merchant.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.seer.teach.mall.api.MallOrderApi;
import com.seer.teach.mall.api.resp.OrderChildDTO;
import com.seer.teach.mall.api.resp.OrderDTO;
import com.seer.teach.mall.api.resp.OrderItemDTO;
import com.seer.teach.pay.app.merchant.service.IMerchantEarningsService;
import com.seer.teach.pay.entity.PayMerchantRevenueDetailEntity;
import com.seer.teach.pay.entity.PayOrderEntity;
import com.seer.teach.pay.entity.RefundOrderEntity;
import com.seer.teach.pay.enums.MerchantRevenueWithdrawStatusEnum;
import com.seer.teach.pay.service.IPayMerchantAccountService;
import com.seer.teach.pay.service.IPayMerchantRevenueDetailService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
@RequiredArgsConstructor
public class MerchantEarningsServiceImpl implements IMerchantEarningsService {
    
    private static final String TRANSACTION_STATUS_PAID = "PAID";
    private static final String TRANSACTION_STATUS_REFUNDED = "REFUNDED";

    private final MallOrderApi mallOrderApi;

    private final IPayMerchantAccountService payMerchantAccountService;

    private final IPayMerchantRevenueDetailService payMerchantRevenueDetailService;

    @Value("${zs.pay.merchant-selle.to-frozen-balance: false}")
    private boolean addToFrozenBalance ;

    @Override
    public void settleMerchantEarnings(PayOrderEntity payOrder) {
        OrderDTO order = mallOrderApi.getOrder(Integer.parseInt(payOrder.getMerchantOrderId()));
        if (Objects.isNull(order)) {
            log.info("订单[{}]不存在", payOrder.getMerchantOrderId());
            return;
        }
        if (log.isDebugEnabled()) {
            log.debug("查询的订单结果： {}", JSONUtil.toJsonStr(order));
        }
        log.info("订单[{}]开始结算，addToFrozenBalance: {}", payOrder.getMerchantOrderId(), addToFrozenBalance);
        List<OrderChildDTO> orderChildren = order.getOrderChildren();
        if (CollUtil.isNotEmpty(orderChildren)) {
            // 收集所有需要增加余额的商户和金额
            Map<Long, BigDecimal> merchantEarningsMap = new HashMap<>();
            List<PayMerchantRevenueDetailEntity> detailList = new ArrayList<>();

            for (OrderChildDTO orderChild : orderChildren) {
                log.info("子订单[{}]开始结算", orderChild.getChildOrderSn());
                Long merchantUserId = orderChild.getMerchantUserId();

                merchantEarningsMap.merge(merchantUserId, orderChild.getActualPrice(), BigDecimal::add);

                List<OrderItemDTO> orderItems = orderChild.getOrderItems();
                if (CollUtil.isEmpty(orderItems)) {
                    continue;
                }
                for (OrderItemDTO orderItem : orderItems) {
                    PayMerchantRevenueDetailEntity payMerchantRevenueDetail = buildPayMerchantRevenueDetailEntity(payOrder, orderChild, orderItem);
                    detailList.add(payMerchantRevenueDetail);
                }
            }

            boolean increaseResult;
            if (addToFrozenBalance) {
                // 批量处理商户收益增加（只增加总金额和冻结金额）
                increaseResult = payMerchantAccountService.batchIncreaseMerchantFrozenFunds(merchantEarningsMap);

                log.info("批量增加商户冻结收益结果：{}", increaseResult);
            } else {
                // 直接增加商户可用余额
                increaseResult = true;
                for (Map.Entry<Long, BigDecimal> entry : merchantEarningsMap.entrySet()) {
                    Long merchantId = entry.getKey();
                    BigDecimal amount = entry.getValue();
                    boolean result = payMerchantAccountService.increaseBalance(merchantId, amount);
                    if (!result) {
                        log.error("增加商户[{}]可用余额失败，金额: {}", merchantId, amount);
                        increaseResult = false;
                    }
                }
                // 标记为已结算
                detailList.forEach(detail -> detail.setSettlementStatus(PayMerchantRevenueDetailEntity.SETTLEMENT_STATUS_SETTLED));
                log.info("批量增加商户可用余额结果：{}", increaseResult);
            }

            if (increaseResult) {
                payMerchantRevenueDetailService.saveBatch(detailList);
                log.info("商户收益结算成功，订单号: {}", payOrder.getMerchantOrderSn());
            } else {
                log.error("商户收益结算失败，订单号: {}", payOrder.getMerchantOrderSn());
            }
        }
    }

    @Override
    public void refundMerchantEarnings(RefundOrderEntity refundOrder) {
        // 查询相关的支付订单
        log.info("开始处理商家收益退款，退款订单号：{}，deductFromFrozenBalance: {}", refundOrder.getRefundSn(), addToFrozenBalance);

        // 根据退款订单更新商家收益明细状态
        List<PayMerchantRevenueDetailEntity> revenueDetails = payMerchantRevenueDetailService.listByPayOrderSn(refundOrder.getPayOrderSn());
        if (CollUtil.isEmpty(revenueDetails)) {
            log.warn("未找到与支付订单号 {} 相关的商家收益明细", refundOrder.getPayOrderSn());
            return;
        }

        List<PayMerchantRevenueDetailEntity> updatedDetails = new ArrayList<>();
        // 收集所有需要扣除余额的商户和金额
        Map<Long, BigDecimal> merchantRefundMap = new HashMap<>();

        for (PayMerchantRevenueDetailEntity detail : revenueDetails) {
            // 更新交易状态为已退款
            detail.setTransactionStatus(TRANSACTION_STATUS_REFUNDED);
            detail.setRefundAmount(detail.getActualRevenue());
            detail.setRefundTime(refundOrder.getSuccessTime());

            // 累加商户退款金额
            merchantRefundMap.merge(detail.getMerchantUserId(), detail.getActualRevenue(), BigDecimal::add);

            updatedDetails.add(detail);
        }

        boolean deductResult;
        if (addToFrozenBalance) {
            // 批量处理商户收益扣除（从冻结金额中扣除）
            deductResult = payMerchantAccountService.batchDecreaseFrozenBalance(merchantRefundMap);
            log.info("批量扣减商户冻结收益结果：{}", deductResult);
        } else {
            // 直接从商户可用余额中扣除
            deductResult = true;
            for (Map.Entry<Long, BigDecimal> entry : merchantRefundMap.entrySet()) {
                Long merchantId = entry.getKey();
                BigDecimal amount = entry.getValue();
                boolean result = payMerchantAccountService.decreaseBalance(merchantId, amount);
                if (!result) {
                    log.error("扣减商户[{}]可用余额失败，金额: {}", merchantId, amount);
                    deductResult = false;
                }
            }
            log.info("批量扣减商户可用余额结果：{}", deductResult);
        }

        if (deductResult) {
            // 批量更新商家收益明细
            boolean updateResult = payMerchantRevenueDetailService.updateBatchById(updatedDetails);
            log.info("更新商家收益明细结果：{}", updateResult);
        } else {
            log.error("商户收益退款处理失败，退款订单号: {}", refundOrder.getRefundSn());
        }
    }

    private static PayMerchantRevenueDetailEntity buildPayMerchantRevenueDetailEntity(PayOrderEntity payOrder, OrderChildDTO orderChild, OrderItemDTO orderItem) {
        PayMerchantRevenueDetailEntity payMerchantRevenueDetail = new PayMerchantRevenueDetailEntity();
        payMerchantRevenueDetail.setOrderId(orderItem.getOrderId());
        payMerchantRevenueDetail.setChildOrderId(orderChild.getId());
        payMerchantRevenueDetail.setChildOrderSn(orderChild.getChildOrderSn());
        payMerchantRevenueDetail.setSkuId(orderItem.getSkuId());
        payMerchantRevenueDetail.setUserId(orderChild.getUserId());
        payMerchantRevenueDetail.setMerchantUserId(orderChild.getMerchantUserId());
        payMerchantRevenueDetail.setPayChannelCode(payOrder.getChannelCode());
        payMerchantRevenueDetail.setTransactionTime(payOrder.getSuccessTime());
        payMerchantRevenueDetail.setQuantity(orderItem.getNumber());
        payMerchantRevenueDetail.setUnitPrice(orderItem.getCoin());
        payMerchantRevenueDetail.setExchangeRatio(payOrder.getExchangeRatio());
        payMerchantRevenueDetail.setActualRevenue(orderItem.getPrice());
        payMerchantRevenueDetail.setTransactionStatus(TRANSACTION_STATUS_PAID);
        payMerchantRevenueDetail.setSettlementStatus(PayMerchantRevenueDetailEntity.SETTLEMENT_STATUS_UNSETTLED);
        payMerchantRevenueDetail.setWithdrawStatus(MerchantRevenueWithdrawStatusEnum.NOT_WITHDRAWN.getCode());
        payMerchantRevenueDetail.setPayOrderSn(payOrder.getOrderSn());
        return payMerchantRevenueDetail;
    }
}