<?php
/**
 *  ╔═══════════════════════════════════════════════════╗
 *  ║                                                   ║
 *  ║     ██╗  ██╗   █████╗    ██████╗                  ║
 *  ║     ██║  ██║  ██╔══██╗  ██╔═══██╗                 ║
 *  ║     ███████║  ███████║  ██║   ██║                 ║
 *  ║     ██╔══██║  ██╔══██║  ██║   ██║                 ║
 *  ║     ██║  ██║  ██║  ██║  ╚██████╔╝   SNS           ║
 *  ║                                                   ║    
 *  ║                                                   ║    
 *  ║     © 2023 HaoSNS™ All Rights Reserved            ║
 *  ║     官方网站: https://www.haosns.com                *
 *  ║     本代码由赣州乐易网络科技有限公司®提供             *
 *  ║                                                    *
 *  ║   未经授权禁止复制、传播或用于其他商业目的            *
 *  ║                                                   ║
 *  ╚═══════════════════════════════════════════════════╝
 */

namespace app\common\service;

use app\common\exception\WechatException;
use app\common\logic\BaseLogic;
use EasyWeChat\{
    Factory,
    Kernel\Http\StreamResponse,
    Kernel\Exceptions\Exception,

};


/**
 * 微信功能类
 * Class WeChatService
 * @package app\common\service
 */
class WeChatService extends BaseLogic
{
    /**
     * @notes 公众号-根据code获取微信信息
     * @param array $params
     * @return array
     * @throws Exception
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Overtrue\Socialite\Exceptions\AuthorizeFailedException
     */
    public static function getOaResByCode(array $params)
    {
        $config = WeChatConfigService::getOaConfig();
        $app = Factory::officialAccount($config);

        $response = $app->oauth
            ->scopes(['snsapi_userinfo'])
            ->userFromCode($params['code'])
            ->getRaw();

        if (!isset($response['openid']) || empty($response['openid'])) {
            throw new Exception('获取openID失败');
        }
        return $response;
    }


    /**
     * @notes 小程序-根据code获取微信信息
     * @param $post
     * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
     * @throws Exception
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     */
    public static function getMnpResByCode($post)
    {
        $config = WeChatConfigService::getMnpConfig();

        $app = Factory::miniProgram($config);
        $response = $app->auth->session($post['code']);
        if (!isset($response['openid']) || empty($response['openid'])) {
            throw new Exception('获取openID失败');
        }
        return $response;
    }

    /**
     * @notes 公众号跳转url
     * @param $url
     * @return string
     */
    public static function getCodeUrl($url)
    {

        $config = WeChatConfigService::getOaConfig();
        $app = Factory::officialAccount($config);
        $response = $app
            ->oauth
            ->scopes(['snsapi_userinfo'])
            ->redirect($url);

        return $response;
    }

    /**
     * @notes 生成小程序码，使用wxacode.getUnlimited接口
     * @param array $param $param 参数配置 page:页面路径；scene：页面参数；saveDir：保存路径；fileName：文件名
     * @param string $type 返回类型：resource时返回资源类型,file保存并返回文件,base64返回base64
     * @return mixed|string
     */
    public static function makeMpQrCode(array $param, string $type = 'resource')
    {
        try {

            $page = $param['page'] ?? '';
            $scene = $param['scene'] ?? 'null';
            $saveDir = $param['save_dir'] ?? 'uploads/qr_code/user_share/';
            $fileName = $param['file_name'] ?? time() . '.png';

            $config = WeChatConfigService::getMnpConfig();

            $app = Factory::miniProgram($config);
            $response = $app->app_code->getUnlimit($scene, [
                'page'          => $page,
//                'env_version'   => 'trial' //要打开的小程序版本。正式版为 release，体验版为 trial，开发版为 develop
            ]);

            if (is_array($response) && isset($response['errcode'])) {
                //开启错误提示，小程序未发布和页面不存在，返回提示
                if (41030 === $response['errcode']) {
                    throw new Exception('所传page页面不存在，或者小程序没有发布');
                }

                throw new Exception($response['errmsg']);
            }

            $contents = $response->getBody()->getContents();
            switch ($type){
                case 'file':
                    if ($response instanceof StreamResponse) {
                        $fileName = $response->saveAs($saveDir, $fileName);
                        $contents = $saveDir . $fileName;
                    }
                    break;
                case 'base64':
                    $mpBase64 = chunk_split(base64_encode($contents));
                    $contents = 'data:image/png;base64,' . $mpBase64;
            }

            self::$returnData = $contents;
            return true;

        } catch (Exception $e) {
            self::$returnData = $e->getMessage();
            return false;

        }

    }

}