<?php

namespace app\extra\wechat;

/**
 * 微信接口调度服务
 * @package app\extra\wechat
 * @method \WeChat\Oauth WeChatOauth() static 微信网页授权
 */
class WechatService
{


    /**
     * 静态初始化对象
     * @param string $name
     * @param array $arguments
     * @return mixed
     * @throws \think\admin\Exception
     */
    public static function __callStatic(string $name, array $arguments)
    {
        [$type, $base, $class] = static::parseName($name);
        if ("{$type}{$base}" !== $name) {
            throw new \Exception("抱歉，实例 {$name} 不符合规则！");
        }
        if (class_exists($class)) {
            return new $class(static::getConfig());
        } else {
            throw new \Exception("抱歉，接口模式无法实例 {$class} 对象！");
        }
    }

    /**
     * 解析调用对象名称
     * @param string $name
     * @return array
     */
    private static function parseName(string $name): array
    {
        foreach (['WeChat', 'WeMini', 'WeOpen', 'WePayV3', 'WePay', 'ThinkService'] as $type) {
            if (strpos($name, $type) === 0) {
                [, $base] = explode($type, $name);
                return [$type, $base, "\\{$type}\\{$base}"];
            }
        }
        return ['-', '-', $name];
    }

    /**
     * 获取当前微信APPID
     * @return string
     */
    public static function getAppid(): string
    {
        return sConf('wechat.appid');
    }

    /**
     * 获取接口授权模式
     * @return string
     */
    public static function getType(): string
    {
        $type = strtolower(sConf('wechat.type'));
        if (in_array($type, ['api', 'thr'])) return $type;
        throw new \Exception('请在后台配置微信对接授权模式');
    }
    /**
     * 获取公众号配置参数
     * @return array
     */
    public static function getConfig(): array
    {
        return [
            'appid'          => static::getAppid(),
            'token'          => sConf('wechat.token'),
            'appsecret'      => sConf('wechat.secret'),
            'encodingaeskey' => sConf('wechat.aeskey'),
            'mch_id'         => sConf('wechat.mch_id'),
            'mch_key'        => sConf('wechat.mch_key')
        ];
    }

    /**
     * 通过网页授权获取粉丝信息
     * @param string $source 回跳URL地址
     * @param integer $isfull 获取资料模式
     * @param boolean $redirect 是否直接跳转
     * @return array
     */
    public static function getWebOauthInfo(string $source, int $isfull = 0, bool $redirect = true): array
    {
        try {
            $appid = static::getAppid();
            $openid = request()->session()->get("{$appid}_openid");
            $userinfo = request()->session()->get("{$appid}_fansinfo");
            if ((empty($isfull) && !empty($openid)) || (!empty($isfull) && !empty($openid) && !empty($userinfo))) {
                return ['openid' => $openid,"url" => "", 'fansinfo' => $userinfo];
            }
            // 解析 GET 参数
            $queryString = parse_url($source, PHP_URL_QUERY);
            // 初始化参数数组
            $params = [];
            // 只有当有查询字符串时才解析
            if ($queryString !== null && $queryString !== '') {
                parse_str($queryString, $params);
            }
//        parse_str(parse_url($source, PHP_URL_QUERY), $params);
            $getVars = [
                'code'  => $params['code'] ?? input('code', ''),
                'rcode' => $params['rcode'] ?? input('rcode', ''),
                'state' => $params['state'] ?? input('state', ''),
            ];
            $wechat = static::WeChatOauth();
            if ($getVars['state'] !== $appid || empty($getVars['code'])) {
                $params['rcode'] = enbase64url($source);
                $location = strstr("{$source}?", '?', true) . '?' . http_build_query($params);
                $oauthurl = $wechat->getOauthRedirect($location, $appid, $isfull ? 'snsapi_userinfo' : 'snsapi_base');
                return ['openid' => "","url" => $oauthurl ,"fansinfo" => ""];
            } elseif (($token = $wechat->getOauthAccessToken($getVars['code'])) && isset($token['openid'])) {
                request()->session()->set("{$appid}_openid", $openid = $token['openid']);
                if ($isfull && isset($token['access_token'])) {
                    $userinfo = $wechat->getUserInfo($token['access_token'], $openid);
                    request()->session()->set("{$appid}_fansinfo", $userinfo);
                }
                return ['openid' => $openid, 'url' => '', 'fansinfo' => ""];
            }
            if ($getVars['rcode']) {
                $location = debase64url($getVars['rcode']);
                return ['openid' => "","url" => $location ,"fansinfo" => ""];
            } elseif ((empty($isfull) && !empty($openid)) || (!empty($isfull) && !empty($openid) && !empty($userinfo))) {
                return ['openid' => $openid, 'url' => '', 'fansinfo' => $userinfo];
            } else {
                throw new \Exception('Query params [rcode] not find.');
            }
        } catch (\Throwable $th) {
            echo $th->getMessage();
        }
    }
//
//    /**
//     * 获取微信网页JSSDK签名参数
//     * @param null|string $location 签名地址
//     * @return array
//     * @throws \WeChat\Exceptions\InvalidResponseException
//     * @throws \WeChat\Exceptions\LocalCacheException
//     * @throws \think\admin\Exception
//     */
//    public static function getWebJssdkSign(?string $location = null): array
//    {
//        $location = $location ?: Library::$sapp->request->url(true);
//        if (static::getType() === 'api') {
//            return static::WeChatScript()->getJsSign($location);
//        } else {
//            return static::ThinkServiceConfig()->jsSign($location);
//        }
//    }


}