<?php

namespace Modules\Channel\Http\Controllers;

use Catch\Base\CatchController;
use EasyWeChat\OpenPlatform\Application;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Modules\Channel\Models\WechatAuthorizationInfo;
use Modules\Channel\Services\WechatOpenPlatform\WechatOpenPlatformService;
use Modules\Common\Errors\Errors;
use Modules\Common\Exceptions\CommonBusinessException;
use Modules\User\Http\Controllers\UserTrait;
use Symfony\Component\Cache\Adapter\RedisAdapter;

class WechatOpenPlatformController extends CatchController
{
    use UserTrait;
    use ValidatesRequests;

    /**
     * 三方授权跳转页
     * @param Request $request
     * @return string
     * @throws \EasyWeChat\Kernel\Exceptions\HttpException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \Illuminate\Validation\ValidationException
     * @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
     */
    public function preauth(Request $request) {
        $this->validate($request, [
            'user_id' => 'required'
        ]);
        $currentUser = $this->getCurrentUser();
        $componentInfo = WechatOpenPlatformService::getComponentInfoByCompanyUid($currentUser->id);
        $app = WechatOpenPlatformService::buildApplication($componentInfo);
        $user_id = $request->input('user_id');
        $url = $app->createPreAuthorizationUrl(sprintf('%s/api/channel/openPlatform/auth/%s/%s',config('app.url'), $componentInfo->app_id, $user_id), []);
        return $url;
    }

    /**
     * 三方授权回调
     * @param Request $request
     * @param $component_appid
     * @param $user_id
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Foundation\Application
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
     * @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
     * @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
     * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
     */
    public function auth(Request $request, $component_appid, $user_id) {
        $auth_code = $request->input('auth_code');
        $auth_user = DB::table('users')
            ->where([
                'id' => $user_id, 'deleted_at' => 0, 'status' => 1
            ])
            ->where('pid', '<>', 0)
            ->select('pid', 'id')->first();
        if(!$auth_user) {
            CommonBusinessException::throwError(Errors::OPENPLATFORM_OPTIMIZER_INFO_ERROR);
        }
        $componentInfo = WechatOpenPlatformService::getComponentInfoByAppid($component_appid);
        $app = WechatOpenPlatformService::buildApplication($componentInfo);
        $client = $app->getClient();
        $response = $client->postJson('/cgi-bin/component/api_query_auth', [
            'component_appid' => $component_appid,
            'authorization_code' => $auth_code
        ]);
        $parsedContent = \json_decode($response->getContent(), true);
        $authorizer_appid = $parsedContent['authorization_info']['authorizer_appid'];
        $authorizer_refresh_token = $parsedContent['authorization_info']['authorizer_refresh_token'];

        $response = $client->postJson('/cgi-bin/component/api_get_authorizer_info', [
            'component_appid' => $component_appid,
            'authorizer_appid' => $authorizer_appid
        ]);
        $parsedContent = \json_decode($response->getContent(), true);

        WechatAuthorizationInfo::updateOrCreate([
            'authorizer_appid' => $authorizer_appid,
            'component_appid' => $component_appid,
            'user_id' => $user_id,
            'puser_id' => $auth_user->pid,
        ], [
            'authorizer_refresh_token' => $authorizer_refresh_token,
            'nick_name' => $parsedContent['authorizer_info']['nick_name'],
        ]);

        return view('wechat.openPlatform.authSuccess')->with('url', sprintf('%s/#/user/advertiser',config('app.url')));
    }

    /**
     * 处理授权事件
     * @param Request $request
     * @param $component_appid
     */
    public function authorCommand(Request $request, $component_appid) {
        $componentInfo = WechatOpenPlatformService::getComponentInfoByAppid($component_appid);
        $app = WechatOpenPlatformService::buildApplication($componentInfo);

        $server = $app->getServer();

        $server->handleAuthorized(function($message, \Closure $next) {
            myLog('authorCommand')->info('handleAuthorized', ['message' => $message]);
            return $next($message);
        });
        $server->handleUnauthorized(function($message, \Closure $next) {
            WechatOpenPlatformService::handleUnauthorized($message);
            return $next($message);
        });

        return $server->serve();
    }

    public function infoCommand(Request $request, $authorizer_appid, $component_appid) {

        $componentInfo = WechatOpenPlatformService::getComponentInfoByAppid($component_appid);
        $app = WechatOpenPlatformService::buildApplication($componentInfo);
        myLog("wx-xiaoxi")->info('-------开始处理---'.get_date());
        $server = $app->getServer();
        $message = $server->getDecryptedMessage();
        myLog("wx-xiaoxi")->info([
            'authorizer_appid' => $authorizer_appid,
            'component_appid' => $component_appid,
            'param' => $request->all(),
            'msg' => $message,
        ]);
        $refreshToken = WechatOpenPlatformService::getRefreshToken($authorizer_appid,$component_appid);
        $server = $app->getOfficialAccountWithRefreshToken($authorizer_appid, $refreshToken)->getServer();
        $server->addMessageListener('text', function($message) {
            myLog("wx-xiaoxi")->info('----文本消息---');
            if ($message->Content == "pk"){
                return  $message->FromUserName;
            }
        });

        $server->addEventListener('subscribe', function() {  });
        myLog("wx-xiaoxi")->info('-------结束处理---'.get_date());
        return $server->serve();
    }
}
