package com.jeequan.jeepay.thirdparty.oauth2;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.paychannel.IChannelUserService;
import com.jeequan.jeepay.core.model.QRCodeParams;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.oauth2.WxpayOauth2Params;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelUserInfoMsg;
import com.jeequan.jeepay.thirdparty.model.WxServiceWrapper;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
import com.jeequan.jeepay.thirdparty.util.WxLiteCodeUtils;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/*
* 微信支付 获取微信openID实现类
*
* @author terrfly
*
* @date 2021/6/8 17:22
*/
@Service
@Slf4j
public class WxpayChannelUserService implements IChannelUserService {

    @Autowired private ConfigContextQueryService configContextQueryService;

    /** 默认官方跳转地址 **/
    private static final String DEFAULT_OAUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize";

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

    @Override
    public ChannelUserInfoMsg buildUserRedirectUrl(String callbackUrlEncode, MchAppConfigContext mchAppConfigContext) {

        String appId = null;
        String oauth2Url = "";


        // 特约商户
        if(mchAppConfigContext.isIsvsubMch()){

            // 查询商户 配置 的oauth2配置 ( 支付参数配置 )    selectOauth2InfoId: 配置的oauth2参数
            String ifCode = configContextQueryService.queryIfCodeByPageType(mchAppConfigContext, QRCodeParams.PAGE_TYPE_WECHAT_H5);
            String selectOauth2InfoId = configContextQueryService.queryAgentOrIsvSelectOauth2InfoId(mchAppConfigContext.getMchApplyment(), ifCode);


            WxpayOauth2Params isvParams = (WxpayOauth2Params) configContextQueryService.
                    queryIsvOauth2ParamsByAutoSelectOauth2InfoId(mchAppConfigContext.getMchApplyment().getIsvNo(), getIfCode(), selectOauth2InfoId);

            if(isvParams == null) {
                throw new BizException("服务商微信oauth2参数没有配置！");
            }

            appId = isvParams.getAppId();
            oauth2Url = isvParams.getOauth2Url();
        }else{
            //获取商户配置信息
            WxpayOauth2Params normalMchParams = (WxpayOauth2Params)configContextQueryService.queryNormalOauth2Params(mchAppConfigContext.getMchNo(), mchAppConfigContext.getAppId(), CS.IF_CODE.WXPAY);
            if(normalMchParams == null) {
                throw new BizException("商户微信支付接口没有配置！");
            }
            appId = normalMchParams.getAppId();
            oauth2Url = normalMchParams.getOauth2Url();
        }

        if(StringUtils.isBlank(oauth2Url)){
            oauth2Url = DEFAULT_OAUTH_URL;
        }
        String wxUserRedirectUrl = String.format(oauth2Url + "?appid=%s&scope=snsapi_base&state=&redirect_uri=%s&response_type=code#wechat_redirect", appId, callbackUrlEncode);
        log.info("wxUserRedirectUrl={}", wxUserRedirectUrl);
        return ChannelUserInfoMsg.gen(wxUserRedirectUrl, appId);
    }

    @Override
    public String getChannelUserId(String pageType, JSONObject reqParams, MchAppConfigContext mchAppConfigContext, String ifCode) {
        String code = reqParams.getString("code");

        Byte isUseSubmchAccount = reqParams.getByte("isUseSubmchAccount");
        if(isUseSubmchAccount == null){
            isUseSubmchAccount = CS.NO; // 默认使用 服务商账号
        }

        try {

//            ifCode = configContextQueryService.queryIfCodeByPageType(mchAppConfigContext, pageType);
            WxServiceWrapper wxServiceWrapper = configContextQueryService.getWxServiceWrapperByAutoOauth2(mchAppConfigContext, ifCode);

            // 小程序
            if(QRCodeParams.PAGE_TYPE_WECHAT_LITE.equals(pageType)){

                // 获取商户自己的小程序 openId
                if(isUseSubmchAccount == CS.YES){
                    return getOpenIdByIsvSubmchAccount(code, mchAppConfigContext);
                }

                // 使用新的调用方式
                return WxLiteCodeUtils.code2OpenId(wxServiceWrapper.getWxMaService(), code).getOpenid();

                /*WxMaJscode2SessionResult sessionInfo = wxServiceWrapper.getWxMaService().getUserService().getSessionInfo(code);

                JSONObject result = new JSONObject();
                result.put("openid", sessionInfo.getOpenid());
                result.put("unionid", sessionInfo.getUnionid());
                return result.toJSONString();*/

            }else{ // 公众号

                return wxServiceWrapper.getWxMpService().getOAuth2Service().getAccessToken(code).getOpenId();

                /*WxOAuth2AccessToken accessToken = wxServiceWrapper.getWxMpService().getOAuth2Service().getAccessToken(code);

                JSONObject result = new JSONObject();
                result.put("openid", accessToken.getOpenId());
                result.put("unionid", accessToken.getUnionId());
                return result.toJSONString();*/
            }

        } catch (WxErrorException e) {
            log.error("微信公众号获取openID异常", e);
            return null;
        }
    }


    /** 获取商户自己的小程序 openId  **/
    private String getOpenIdByIsvSubmchAccount(String code, MchAppConfigContext mchAppConfigContext) throws WxErrorException {

        WxpayOauth2Params oauth2Params = (WxpayOauth2Params) configContextQueryService.queryNormalOauth2Params(mchAppConfigContext.getMchNo(), mchAppConfigContext.getAppId(), CS.IF_CODE.WXPAY);

        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
        config.setAppid(oauth2Params.getLiteAppId());
        config.setSecret(oauth2Params.getLiteAppSecret());
        WxMaService wxMaService = new WxMaServiceImpl();
        wxMaService.setWxMaConfig(config);

        // 使用新的调用方式
        return WxLiteCodeUtils.code2OpenId(wxMaService, code).getOpenid();
    }

}
