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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.jeequan.jeepay.core.entity.MchApplyment;
import com.jeequan.jeepay.core.entity.MchSubInfo;
import com.jeequan.jeepay.core.interfaces.paychannel.IIsvmchWxConfigService;
import com.jeequan.jeepay.core.model.applyment.ApplymentSignInfo;
import com.jeequan.jeepay.core.model.applyment.PaywayFee;
import com.jeequan.jeepay.core.model.params.ruipay.RyxpayIsvParams;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.MchSubInfoEntity;
import com.jeequan.jeepay.service.impl.MchSubInfoService;
import com.jeequan.jeepay.thirdparty.channel.IsvFactory;
import com.jeequan.jeepay.thirdparty.channel.ryxpay.model.ReqMethod;
import com.jeequan.jeepay.thirdparty.channel.ryxpay.model.RyxAccessResp;
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.util.List;

@Service
@Slf4j
public class RyxpayIsvmchWxConfigService implements IIsvmchWxConfigService {

    @Autowired
    private MchSubInfoService mchSubInfoService;

    @Override
    public ChannelRetMsg configPayBaseUrl(String configBaseUrl, String isvNo, String mchNo, String mchAppId, String ifCode) {
        return null;
    }

    @Override
    public ChannelRetMsg applyModifyMchRate(List<PaywayFee> paywayFeeList, String isvNo, String mchNo, String mchAppId, String ifCode) {
        return null;
    }

    @Override
    public String queryConfiguredInfo(String isvNo, String mchNo, String mchAppId, String ifCode) {
        return null;
    }

    @Override
    public ChannelRetMsg configBindAppId(String configAppId, String isvNo, String mchNo, String mchAppId, String ifCode) {
        return null;
    }

    @Override
    public ChannelRetMsg configSubscribeAppId(String configAppId, String isvNo, String mchNo, String mchAppId, String ifCode) {
        return ChannelRetMsg.confirmSuccess(null);
    }

    @Override
    public ChannelRetMsg applyModifyMchShortName(String mchShortName, String isvNo, String mchNo, String mchAppId, String ifCode) {
        return ChannelRetMsg.confirmSuccess(null);
    }

    @Override
    public ChannelRetMsg applyModifyMchAppPublicKey(String appPublicKey, String isvNo, String mchNo, String mchAppId, String ifCode) {
        return ChannelRetMsg.confirmSuccess(null);
    }

    @Override
    public ApplymentSignInfo wxOpenSignInfo(MchApplyment mchApplyment) {

        ApplymentSignInfo result = new ApplymentSignInfo();

        JSONObject suJson = JSON.parseObject(mchApplyment.getSuccResParameter());
        // 获取到 服务商配置信息
        ConfigContextQueryService configContextQueryService = SpringBeansUtil.getBean(ConfigContextQueryService.class);
        RyxpayIsvParams isvParams = (RyxpayIsvParams) configContextQueryService.queryIsvParams(mchApplyment);

        // 微信开通意愿二维码地址
        result.setSignUrl(isvParams.getWxUrl());
        result.setImgType(ApplymentSignInfo.IMG_TYPE_QRCONTENT);

        // 同步后子商户信息还是为空，则抛出异常
        if (StringUtils.isEmpty(mchApplyment.getChannelMchNo())) {
            result.setErrInfo("随行付商户号为空");
            return result;
        }
        LambdaQueryChainWrapper<MchSubInfoEntity> wxSubInfoQuery = mchSubInfoService.lambdaQuery()
                .eq(MchSubInfoEntity::getMchApplyId, mchApplyment.getApplyId())
                .eq(MchSubInfoEntity::getChannelMchNo, mchApplyment.getChannelMchNo())
                .eq(MchSubInfoEntity::getMainUse, 1)
                .eq(MchSubInfoEntity::getSubMchType, "WX");
        MchSubInfoEntity wx = wxSubInfoQuery.one();

        if (wx == null) {
            IsvFactory.getIsvMchApplymentService(JeepayKit.getIfCodeOrigin(mchApplyment.getIfCode()))
                    .subMchColl(mchApplyment);

            wx = wxSubInfoQuery.one();
        }

        if (wx == null) {
            result.setState("未报备");
            result.setErrInfo("[未获取到子商户信息]");
            return result;
        } else if ("0".equals(wx.getStatus())) {
            result.setChannelSubMchId(wx.getSubMchId());
        } else {
            result.setState("未报备");
            result.setErrInfo("[" + wx.getRemark() + "]");
            return result;
        }

        // 请求参数
        JSONObject bizContent = new JSONObject();
        bizContent.put("merInId", JSON.parseObject(mchApplyment.getSuccResParameter()).getString("merInId"));

        // 发送请求
        RyxAccessResp response = RyxpayKit.auditReqApi(ReqMethod.Method.MERCHANT_QUERY, isvParams, bizContent, null);
        String code = response.getCode();
        String msg = response.getMsg();
        if (!RyxpayKit.AUDIT_SUCCESS_CODE.equals(code)) {

            result.setState("04");
            result.setErrInfo(code + "[" + msg + "]");

            return result;
        }

        JSONObject wxCertificationInfo = response.getResult().getJSONObject("wxCertificationInfo");
        String wxAuthorizationStatusName = wxCertificationInfo.getString("wxAuthorizationStatusName");

        LambdaUpdateChainWrapper<MchSubInfoEntity> stateUpdate = mchSubInfoService.lambdaUpdate()
                .eq(MchSubInfoEntity::getMchApplyId, mchApplyment.getApplyId())
                .eq(MchSubInfoEntity::getMainUse, 1)
                .eq(MchSubInfoEntity::getSubMchType, "WX");
        if ("已授权".equals(wxAuthorizationStatusName)) {
            result.setState("已授权");
            stateUpdate.set(MchSubInfoEntity::getAuthStatus, MchSubInfo.AUTH_STATUS_AUTHORIZED).update();
        } else {
            result.setState("未授权");
            stateUpdate.set(MchSubInfoEntity::getAuthStatus, MchSubInfo.AUTH_STATUS_UNAUTHORIZED).update();
        }

        return result;
    }

}
