package com.jeequan.jeepay.pay.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.components.mq.model.PayOrderMarketMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.paychannel.ITransferService;
import com.jeequan.jeepay.core.model.applyment.ApplymentBasicInfo;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.params.yspay.YspayIsvParams;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.model.rqrs.transfer.TransferOrderRQ;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.BankBranchAlipay;
import com.jeequan.jeepay.db.entity.MchApplyment;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.db.entity.TransferOrderEntity;
import com.jeequan.jeepay.model.MarketRed;
import com.jeequan.jeepay.service.impl.*;
import com.jeequan.jeepay.thirdparty.channel.yspay.model.ReqMethod;
import com.jeequan.jeepay.thirdparty.channel.yspay.utils.YspayKit;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
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.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.stream.Collectors;

/**
 * TODO
 * 订单营销活动相关处理
 * @author crystal
 * @date 2024/1/29 16:00
 */
@Service
@Slf4j
public class PayOrderMarketReissueService {

    @Autowired
    private PayUserService payUserService;

    @Autowired
    private RedPacketAccountService redPacketAccountService;

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private TransferOrderService transferOrderService;

    @Autowired
    private IMQSender imqSender;

    @Autowired
    private ConfigContextQueryService configContextQueryService;

    @Autowired
    private MchApplymentService mchApplymentService;

    @Autowired
    private BankBranchAlipayService bankBranchAlipayService;


    public void reissue(PayOrder payOrder) {
        payUserService.initResult(payOrder);
        marketReissue(payOrder);
    }

    /**
     * 营销红包补贴
     * @param payOrder
     */
    public void marketReissue(PayOrder payOrder) {
        Boolean isOpen = sysConfigService.getDbMarketPlatRedPacket();
        //如果平台开启了红包配置
        if(isOpen){
            MarketRed marketRed = redPacketAccountService.redAccount(payOrder);
            if(marketRed != null) {
                //商户需要收到的金额
                BigDecimal mchMarketAmt = new BigDecimal(payOrder.getAmount()).multiply(marketRed.getMarketScale());
                //商户实际收到的金额
                BigDecimal mchRealMarketAmt = new BigDecimal(marketRed.getFindAmt()).subtract(new BigDecimal(marketRed.getExtDivAmt()));
                //如果实际收到的金额小于预计收到的金额 则需要额外的补贴
                if(mchRealMarketAmt.compareTo(mchMarketAmt) < 0){
                    BigDecimal perkAmt = mchMarketAmt.subtract(mchRealMarketAmt);
                    TransferOrderEntity transferOrder = initSaveMarketCashFee(payOrder, perkAmt, "营销红包活动补贴");
                    //订单生成的
                    if(transferOrder != null && TransferOrderEntity.STATE_INIT == transferOrder.getState()){
                        imqSender.send(PayOrderMarketMQ.build(transferOrder.getTransferId(),PayOrderMarketMQ.RED_TYPE),10);
                    }
                }
            }
        }
    }

    /**
     * 营销活动手续费补贴
     * @param payOrder
     * @param mchAppConfigContext
     */
    public void marketCashFeeReissue(PayOrder payOrder, MchAppConfigContext mchAppConfigContext) {
        Boolean isOpen = sysConfigService.getDbMarketPlatRedPacket();
        if(isOpen && payOrder != null &&  CS.IF_CODE.YSPAY.equals(payOrder.getIfCode())){
            //查询是否是D0分账
            YspayIsvParams yspayIsvParams = (YspayIsvParams)configContextQueryService.queryIsvParams(mchAppConfigContext.getMchApplyment());
            JSONObject bizData = new JSONObject();
            bizData.put("mercId",payOrder.getChannelMchNo());
            bizData.put("orderId",payOrder.getPayOrderId());
            try {
                JSONObject result = YspayKit.reqV3(ReqMethod.Method.QUERY_D0_DIVISION_SETTLE,yspayIsvParams, bizData);
                //表示当前订单已经做了D0分账 计算手续费金额
                JSONArray stlRecordList = result.getJSONArray("stlRecordList");
                List<JSONObject> resultList = stlRecordList.stream().map(obj -> (JSONObject) obj).filter(item -> payOrder.getChannelMchNo().equals(item.getString("settleMercId"))).collect(Collectors.toList());
                if(!resultList.isEmpty()){
                    JSONObject item = resultList.get(0);
                    //DO 结算手续费 这部分资金将直接补贴给商户
                    BigDecimal settleFee = item.getBigDecimal("settleFee") == null ? BigDecimal.ZERO : item.getBigDecimal("settleFee");
                    settleFee = settleFee.multiply(BigDecimal.valueOf(100));
                    if(settleFee.compareTo(BigDecimal.ZERO) > 0){
                        TransferOrderEntity transferOrder = initSaveMarketCashFee(payOrder,settleFee,"D0提现手续补贴");
                        //订单生成的
                        if(transferOrder != null && TransferOrderEntity.STATE_INIT == transferOrder.getState()){
                            imqSender.send(PayOrderMarketMQ.build(transferOrder.getTransferId(),PayOrderMarketMQ.CASH_FEE_TYPE),5);
                        }
                    }
                }
            }catch (Exception e){
                log.info("异常错误，订单号：{}，错误信息：{}",payOrder.getPayOrderId(),e.getMessage());
            }
        }
    }

    /**
     * 初始化营销活动提现手续费奖励红包
     * @param payOrder
     * @param transferAmt
     * @return
     */
    public TransferOrderEntity initSaveMarketCashFee(PayOrder payOrder, BigDecimal transferAmt, String remark) {
        BigDecimal rate = new BigDecimal("0.001");
        TransferOrderEntity transferOrder = new TransferOrderEntity();
        transferOrder.setTransferId(SeqKit.genTransferId());
        transferOrder.setMchNo(payOrder.getMchNo());
        transferOrder.setIsvNo(payOrder.getIsvNo());
        transferOrder.setAgentNo(payOrder.getAgentNo());
        transferOrder.setAppId(payOrder.getAppId());
        transferOrder.setMchName(payOrder.getMchName());
        transferOrder.setMchType(payOrder.getMchType());
        transferOrder.setMchOrderNo(SeqKit.genMhoOrderId());
        transferOrder.setIfCode(CS.IF_CODE.SYBPAY);
        transferOrder.setAmount(transferAmt.longValue());
        transferOrder.setCurrency("cny");
        transferOrder.setState(TransferOrderEntity.STATE_INIT);
        transferOrder.setMchExtNo(payOrder.getMchExtNo());
        //固定写死到银行卡
        transferOrder.setEntryType(TransferOrderEntity.ENTRY_BANK_CARD);
        transferOrder.setMchFeeRate(rate.multiply(BigDecimal.valueOf(100)) + "%");
        transferOrder.setMchOrderFeeAmount(transferAmt.multiply(rate).setScale(0, RoundingMode.HALF_EVEN).longValue());
        transferOrder.setTransferDesc(remark);
        JSONObject channelExtra = new JSONObject(8);
        channelExtra.put("settleType",MchApplyment.SETT_ACCOUNT_TYPE_PERSONAL);
        //获取商户的信息
        MchApplyment applyment = mchApplymentService.getById(payOrder.getMchExtNo());
        if(applyment == null){
            transferOrder.setState(TransferOrderEntity.STATE_FAIL);
            transferOrder.setTransferDesc("商户信息未获取到");
        }else{
            ApplymentBasicInfo detailJson = JSONObject.parseObject(applyment.getApplyDetailInfo(),ApplymentBasicInfo.getImplInfoClass(payOrder.getIfCode()));
            if(detailJson == null){
                transferOrder.setState(TransferOrderEntity.STATE_FAIL);
                transferOrder.setTransferDesc("商户信息未获取异常");
            }else{
                String bankBranchNo = detailJson.bankBranchNo();
                //获取关联的支付宝支行联行号
                BankBranchAlipay branch = bankBranchAlipayService.getById(bankBranchNo);
                if(branch == null){
                    transferOrder.setState(TransferOrderEntity.STATE_FAIL);
                    transferOrder.setTransferDesc("商户绑定的结算卡支行信息异常");
                }else{
                    // B:对公 C:对私
                    String settAccountType = detailJson.getSettAccountType();
                    if(StringUtils.isNotEmpty(settAccountType)){
                        channelExtra.put("settleType",settAccountType);
                    }
                    String settAccountNo = detailJson.getSettAccountNo();
                    String settAccountName = detailJson.bankAccountName();
                    transferOrder.setAccountNo(settAccountNo);
                    transferOrder.setAccountName(settAccountName);
                    transferOrder.setBankName(branch.getBankName());
                    channelExtra.put("branchName",branch.getBranchName());
                    channelExtra.put("provinceName",branch.getProvinceName());
                    channelExtra.put("cityName",branch.getCityName());
                }
            }
        }
        transferOrder.setChannelExtra(channelExtra.toString());
        transferOrder.setFlowNo(payOrder.getPayOrderId());
        transferOrderService.save(transferOrder);
        return transferOrder;
    }

    /**
     *接收到订单营销转账通知
     * @param transferId
     * @param type
     */
    public void transferReissue(String transferId, byte type) {
        TransferOrderEntity transferOrder = transferOrderService.getById(transferId);
        if(transferOrder == null || TransferOrderEntity.STATE_SUCCESS == transferOrder.getState() || TransferOrderEntity.STATE_CLOSED == transferOrder.getState()){
            return;
        }
        ITransferService transferService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(transferOrder.getIfCode()) + "TransferService", ITransferService.class);
        if(transferService == null){
            throw new BizException("无此转账通道接口");
        }
        TransferOrderRQ rq = new TransferOrderRQ();
        try {
            transferService.preCheck(rq,transferOrder);
            ChannelRetMsg transfer = transferService.transfer(rq, transferOrder);
            if(ChannelRetMsg.ChannelState.CONFIRM_SUCCESS == transfer.getChannelState()) {
                transferOrderService.updateIng2Success(transferId,transfer.getChannelOrderId());
            }else if(ChannelRetMsg.ChannelState.WAITING == transfer.getChannelState()) {
                transferOrderService.updateInit2Ing(transferId);
            }else if(ChannelRetMsg.ChannelState.CONFIRM_FAIL == transfer.getChannelState()) {
                transferOrderService.updateIng2Fail(transferId,transfer.getChannelOrderId(),transfer.getChannelErrCode(),transfer.getChannelErrMsg());
            }
        }catch (Exception e){
            transferOrderService.updateIng2Fail(transferId,null,null,e.getMessage());
        }
    }
}
