package com.jeequan.jeepay.mgr.service;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jeequan.jeepay.components.mq.model.PayOrderDivisionMQ;
import com.jeequan.jeepay.components.mq.model.ZftSettOrderMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.interfaces.IConfigContextQueryService;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.mchconfig.MchDivisionConfig;
import com.jeequan.jeepay.core.model.params.zftpay.ZftpayIsvParams;
import com.jeequan.jeepay.core.model.params.zftpay.ZftpayIsvsubMchParams;
import com.jeequan.jeepay.db.entity.OrderProfitSettRecord;
import com.jeequan.jeepay.db.entity.PayAlizftSettRecord;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.service.impl.MchConfigService;
import com.jeequan.jeepay.service.impl.OrderProfitSettRecordService;
import com.jeequan.jeepay.service.impl.PayAlizftSettRecordService;
import com.jeequan.jeepay.service.impl.PayOrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/***
* 订单处理通用逻辑
*
* @author terrfly
* 
* @date 2021/8/22 16:50
*/
@Service
@Slf4j
public class PayOrderProcessService {


    @Autowired private PayOrderService payOrderService;
    @Autowired private PayAlizftSettRecordService recordService;
    @Autowired private IConfigContextQueryService configContextQueryService;
    @Autowired private OrderProfitSettRecordService orderProfitSettRecordService;
    @Autowired private MchConfigService mchConfigService;
    @Autowired private IMQSender mqSender;

    /** 明确成功的处理逻辑（除更新订单其他业务） **/
    public void confirmSuccess(String payOrderId, MchAppConfigContext mchAppConfigContext){

        PayOrder dbPayOrder = payOrderService.getById(payOrderId);

        // 设置订单状态
        dbPayOrder.setState(PayOrder.STATE_SUCCESS);

        // 订单结算
        this.settPayOrder(dbPayOrder, mchAppConfigContext);

        // 计算订单的分润记录 ( 若异常 不影响订单后续逻辑，  service内的事务)
        try {
            boolean isRunTask = orderProfitSettRecordService.insertProfitByPayOrder(dbPayOrder.getPayOrderId(), OrderProfitSettRecord.CAL_TYPE_PAY_ORDER);
            if(isRunTask){ // 实时结算
                orderProfitSettRecordService.profit2BalanceAmount(dbPayOrder.getPayOrderId(), OrderProfitSettRecord.CAL_TYPE_PAY_ORDER);
            }
        }catch (Exception e){
            log.error("计算分润错误, payOrderId={}" , dbPayOrder.getPayOrderId(),  e);
        }

        // 自动分账 处理逻辑， 不影响主订单任务
        this.updatePayOrderAutoDivision(dbPayOrder);
    }

    private void settPayOrder(PayOrder payOrder, MchAppConfigContext mchAppConfigContext) {
        // 如果为直付通订单，执行结算
        if (CS.IF_CODE.ZFTPAY.equals(payOrder.getIfCode()) && mchAppConfigContext != null) {

            // 直付通服务商配置
            ZftpayIsvParams isvParams = (ZftpayIsvParams) configContextQueryService.queryIsvParams(mchAppConfigContext.getMchApplyment().getIsvNo(), CS.IF_CODE.ZFTPAY);

            // 直付通二级商户配置
            ZftpayIsvsubMchParams isvsubMchParams = (ZftpayIsvsubMchParams) configContextQueryService.queryIsvsubMchParams(mchAppConfigContext.getMchNo(), mchAppConfigContext.getAppId(), CS.IF_CODE.ZFTPAY);

            // 支付成功时间： 如果订单不存在那么取当前时间
            Date payOrderSuccessTime = payOrder.getSuccessTime() == null ? new Date() : payOrder.getSuccessTime();

            // 创建直付通结算记录
            PayAlizftSettRecord record = recordService.initWaitRecord(payOrder, isvParams, isvsubMchParams.getSmid(), payOrderSuccessTime);
            if (StringUtils.isNotEmpty(record.getSettleNo())) {
                // 发送mq延迟
                mqSender.send(ZftSettOrderMQ.build(record.getSettleNo()), Math.toIntExact(record.getSettTime() == null ? 30 : DateUtil.between(new Date(), record.getSettTime(), DateUnit.SECOND)));
            }
        }
    }


    /** 更新订单自动分账业务 **/
    private void updatePayOrderAutoDivision(PayOrder payOrder){

        try {
            //默认不分账  || 其他非【自动分账】逻辑时， 不处理
            if(payOrder == null || payOrder.getDivisionMode() == null || payOrder.getDivisionMode() != PayOrder.DIVISION_MODE_AUTO){
                return ;
            }

            //更新订单表分账状态为： 等待分账任务处理
            boolean updDivisionState = payOrderService.update(new LambdaUpdateWrapper<PayOrder>()
                    .set(PayOrder::getDivisionState, PayOrder.DIVISION_STATE_WAIT_TASK)
                    .eq(PayOrder::getPayOrderId, payOrder.getPayOrderId())
                    .eq(PayOrder::getDivisionState, PayOrder.DIVISION_STATE_UNHAPPEN)
            );

            if(updDivisionState){
                //推送到分账MQ

                // 分账执行 延迟时间, 默认： 2分钟后执行。
                Integer delay = 120;

                // 商户开启了全局自动分账 && 分账规则已配置
                MchDivisionConfig mchDivisionConfig = mchConfigService.queryMchDivisionConfigByDefault(payOrder.getMchNo());
                if(mchDivisionConfig != null && mchDivisionConfig.getOverrideAutoFlag() == CS.YES
                && mchDivisionConfig.getAutoDivisionRules() != null && mchDivisionConfig.getAutoDivisionRules().getDelayTime() != null){
                    delay = mchDivisionConfig.getAutoDivisionRules().getDelayTime();
                }

                mqSender.send(PayOrderDivisionMQ.build(payOrder.getPayOrderId(), CS.YES, null, false, false), delay); //xx s后执行
            }

        } catch (Exception e) {
            log.error("订单[{}]自动分账逻辑异常：", payOrder.getPayOrderId(), e);
        }
    }

}
