package com.jeequan.jeepay.thirdparty.channel.ryxpay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchApplyment;
import com.jeequan.jeepay.core.entity.PayOrder;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.applyment.RyxpayApplymentInfo;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.rqrs.AbstractRS;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelJsapiMsg;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.model.rqrs.payorder.UnifiedOrderRQ;
import com.jeequan.jeepay.db.entity.RegionCodePayRyx;
import com.jeequan.jeepay.service.impl.RegionCodePayRyxService;
import com.jeequan.jeepay.thirdparty.channel.AbstractPaymentService;
import com.jeequan.jeepay.thirdparty.channel.ryxpay.model.PayRespEntity;
import com.jeequan.jeepay.thirdparty.util.PaywayUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Arrays;

/**
 * 瑞银信支付
 *
 * @author xiaoyu
 *
 * @date 2022/7/8 11:24
 */
@Slf4j
@Service
public class RyxpayPaymentService extends AbstractPaymentService {

    @Autowired
    private RegionCodePayRyxService regionCodePayRyxService;

    /**
     * 瑞银信花呗分期参数支持选项
     */
    public static final int[] ALI_HB_FQ_NUM_ARR = {3,6,12};

    @Override
    public String getIfCode() {
        return CS.IF_CODE.RYXPAY;
    }

    @Override
    public boolean isSupport(String wayCode) {
        return false;
    }


    @Override
    public String preCheck(UnifiedOrderRQ rq, PayOrder payOrder) {
        return PaywayUtil.getRealPaywayService(this, payOrder.getWayCode()).preCheck(rq, payOrder);
    }

    @Override
    public AbstractRS pay(UnifiedOrderRQ rq, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
        try {
            return PaywayUtil.getRealPaywayService(this, payOrder.getWayCode()).pay(rq, payOrder, mchAppConfigContext);
        }catch (Exception e){
            upException(payOrder.getPayOrderId(),e);
            throw e;
        }
    }

    public void preCheckAli(UnifiedOrderRQ rq) {
        Integer hbFqNum = rq.getHbFqNum();
        if(hbFqNum != null){
            boolean isCheck = Arrays.stream(ALI_HB_FQ_NUM_ARR).anyMatch(num -> num == hbFqNum);
            if(!isCheck){
                throw new BizException("支付宝支付花呗分期参数有误，仅可支持数值为"+ StringUtils.join(ALI_HB_FQ_NUM_ARR,",") +"期");
            }
            Integer hbFqPercent = rq.getHbFqPercent();
            if(hbFqPercent != null && hbFqPercent != 0){
                throw new BizException("花呗分期商家承担手续费比例目前只支持用户承担手续费");
            }
            rq.setHbFqPercent(0);
        }
    }

    /**
     * 通用返回参数处理
     * @param response
     * @param res
     * @param wayCodeType
     */
    public void initCommonResult(PayRespEntity response, ChannelRetMsg res,String wayCodeType) {
        res.setChannelState(ChannelRetMsg.ChannelState.WAITING);
        res.setNeedQuery(true);
        res.setChannelBizData(response.getData());
        res.setChannelErrCode(response.getRespCode());
        res.setChannelErrMsg(response.getRespMsg());
        String respType = response.getRespType();
        if(RyxpayKit.RESP_BIZ_FAIL.equals(respType)){
            res.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
            res.setNeedQuery(false);
        }else{
            JSONObject bizData = response.getData();
            String smzfMsgId = response.getSmzfMsgId();
            String channelMsgId = response.getChannelMsgId();
            String buyerId = bizData.getString("buyerId");
            String channelTradeNo = bizData.getString("channelTradeNo");
            String payType = bizData.getString("payType");
            if(StringUtils.isNotEmpty(payType)){
                switch (payType){
                    case "1":
                        res.setDrType(CS.DrType.DEBIT.getType());
                        break;
                    case "2":
                        res.setDrType(CS.DrType.CREDIT.getType());
                        break;
                    default:
                        res.setDrType(CS.DrType.OTHER.getType());
                        break;
                }
            }else{
                res.setDrType(CS.DrType.OTHER.getType());
            }
            ChannelJsapiMsg jsapiMsg = new ChannelJsapiMsg();
            res.setChannelUserId(buyerId);
            res.setChannelOrderId(smzfMsgId);
            res.setPlatformMchOrderNo(channelMsgId);
            res.setPlatformOrderNo(channelTradeNo);
            if(StringUtils.isNotEmpty(channelTradeNo)){
                channelTradeNo = channelTradeNo.substring(2);
                jsapiMsg.setTradeNo(channelTradeNo);
            }
            String wxjsapiStr = bizData.getString("wxjsapiStr");
            if(StringUtils.isNotEmpty(wxjsapiStr)){
                jsapiMsg = JSON.parseObject(wxjsapiStr,ChannelJsapiMsg.class);
            }
            jsapiMsg.setRedirectUrl(bizData.getString("redirectUrl"));
            res.setJsapiMsg(jsapiMsg);
        }
    }

    /**
     * 加载商户扩展信息
     * @param bizData
     * @param mchAppConfigContext
     */
    public void loadMchExtInfo(JSONObject bizData,MchAppConfigContext mchAppConfigContext){
        MchApplyment mchApplyment = mchAppConfigContext.getMchApplyment();
        RyxpayApplymentInfo applymentInfo = JSON.parseObject(mchApplyment.getApplyDetailInfo(), RyxpayApplymentInfo.class);
        JSONArray areaName = applymentInfo.getAreaName();
        RegionCodePayRyx byAreaName = regionCodePayRyxService.getByAreaName(areaName.getString(0), areaName.getString(1), areaName.getString(2));
        Assert.notNull(byAreaName, "获取瑞银信地区信息异常");
        bizData.put("areaInfo",byAreaName.getAreaCode());
    }
}
