<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台（PHP版）
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码，建议反馈是我们前进的动力
// | 开源版本可自由商用，可去除界面版权logo
// | gitee下载：https://gitee.com/likeshop_gitee/likeadmin
// | github下载：https://github.com/likeshop-github/likeadmin
// | 访问官网：https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\service\wechat;


use app\common\enum\notice\NoticeEnum;
use app\common\logic\NoticeLogic;
use app\common\model\notice\NoticeSetting;
use EasyWeChat\Kernel\Exceptions\Exception;
use EasyWeChat\OfficialAccount\Application;
use think\facade\Log;


/**
 * 公众号相关
 * Class WeChatOaService
 * @package app\common\service\wechat
 */
class WeChatOaService
{

    protected $app;

    protected $config;


    public function __construct()
    {
        $this->config = $this->getConfig();
        $this->app = new Application($this->config);
    }


    /**
     * @notes easywechat服务端
     * @return \EasyWeChat\Kernel\Contracts\Server|\EasyWeChat\OfficialAccount\Server
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \ReflectionException
     * @throws \Throwable
     * @author 段誉
     * @date 2023/2/27 14:22
     */
    public function getServer()
    {
        return $this->app->getServer();
    }


    /**
     * @notes 配置
     * @return array
     * @throws Exception
     * @author 段誉
     * @date 2023/2/27 12:03
     */
    protected function getConfig()
    {
        $config = WeChatConfigService::getOaConfig();
        if (empty($config['app_id']) || empty($config['secret'])) {
            throw new Exception('请先设置公众号配置');
        }
        return $config;
    }


    /**
     * @notes 公众号-根据code获取微信信息
     * @param string $code
     * @return mixed
     * @throws Exception
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @author 段誉
     * @date 2023/2/27 11:04
     */
    public function getOaResByCode(string $code)
    {
        $response = $this->app->getOAuth()
            ->scopes(['snsapi_userinfo'])
            ->userFromCode($code)
            ->getRaw();

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

        return $response;
    }


    /**
     * @notes 公众号跳转url
     * @param string $url
     * @return mixed
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @author 段誉
     * @date 2023/2/27 10:35
     */
    public function getCodeUrl(string $url)
    {
        return $this->app->getOAuth()
            ->scopes(['snsapi_userinfo'])
            ->redirect($url);
    }


    /**
     * @notes 创建公众号菜单
     * @param array $buttons
     * @param array $matchRule
     * @return \EasyWeChat\Kernel\HttpClient\Response|\Symfony\Contracts\HttpClient\ResponseInterface
     * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
     * @author 段誉
     * @date 2023/2/27 12:07
     */
    public function createMenu(array $buttons, array $matchRule = [])
    {
        if (!empty($matchRule)) {
            return $this->app->getClient()->postJson('cgi-bin/menu/addconditional', [
                'button' => $buttons,
                'matchrule' => $matchRule,
            ]);
        }

        return $this->app->getClient()->postJson('cgi-bin/menu/create', ['button' => $buttons]);
    }


    /**
     * @notes 获取jssdkConfig
     * @param $url
     * @param $jsApiList
     * @param array $openTagList
     * @param false $debug
     * @return mixed[]
     * @throws \EasyWeChat\Kernel\Exceptions\HttpException
     * @throws \Psr\SimpleCache\InvalidArgumentException
     * @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
     * @throws \Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface
     * @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
     * @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
     * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
     * @author 段誉
     * @date 2023/3/1 11:46
     */
    public function getJsConfig($url, $jsApiList, $openTagList = [], $debug = false)
    {
        return $this->app->getUtils()->buildJsSdkConfig($url, $jsApiList, $openTagList, $debug);
    }


    public function contentFormat($noticeSetting, $params)
    {
        $content = $noticeSetting['oa_notice']['content'];
        foreach($params['params'] as $k => $v) {
            $search = '${' . $k . '}';
            $content = str_replace($search, $v, $content);
        }
        return $content;
    }
    public function getTemplateMessageParams($noticeSetting, $params)
    {
        $arr = [];
        $content = $noticeSetting['oa_notice']['content'];
        foreach ($params['params'] as $item => $val) {
            $search = '${' . $item . '}';
            if(strpos($content, $search) !== false && !in_array($item, $arr)) {
                $arr[] = $item;
            }
        }
        $arr2 = [];
        if (!empty($arr)) {
            foreach ($arr as $v) {
                $key = strpos($content, $v);
                $arr2[$key] = $v;
            }
        }
        ksort($arr2);
        $arr3 = array_values($arr2);
        $arr4 = [];
        foreach ($arr3 as $v2) {
            if(isset($params['params'][$v2])) {
                $arr4[$v2]['value'] = $params['params'][$v2] . "";
            }
        }
        return $arr4;
    }
    public function sendTemplateMessage(array $params)
    {
        try {
            // 通知设置
            $noticeSetting = NoticeSetting::where('scene_id', $params['scene_id'])->findOrEmpty()->toArray();
            Log::info('WeChatOa-sendTemplateMessage:'.json_encode([$noticeSetting,$params,$this->getTemplateMessageParams($noticeSetting, $params)]));
            // 发送
            $wx_data = [
                'touser' => $params['params']['openid'],
                'template_id' => $noticeSetting['oa_notice']['template_id'],
                'url' => (isset($params['url']) && !empty($params['url']))?$params['url']:'',
                'data' => $this->getTemplateMessageParams($noticeSetting, $params)
            ];
            // 可跳小程序
            if(isset($params['page']) && !empty($params['page'])) {
                $wx_data["miniprogram"]=[
                                            "appid" => 'wx8e44db3741ea212c',
                                            "pagepath" => $params['page']
                ];
            }
            $result = $this->app->getClient()->postJson('cgi-bin/message/template/send', $wx_data);
            if (intval($result["errcode"]) > 0) {
                throw new \Exception('微信通知发送失败:'.$result["errmsg"]);
            }
            // 替换通知模板参数
            $content = $this->contentFormat($noticeSetting, $params);
            // 添加通知记录
            NoticeLogic::addNotice($params, $noticeSetting, NoticeEnum::OA, $content);
            return true;
        } catch (\Exception $e) {
            Log::info('WeChatOa-sendTemplateMessage:'.$e->getMessage());
            throw new \Exception($e->getMessage());
        }
    }

    public function getUserInfo($openid)
    {
        $response =$this->app->getClient()->get("/cgi-bin/user/info?openid={$openid}&lang=zh_CN");
        return $response->toArray();
    }
}