<?php
// +----------------------------------------------------------------------
// | [ WE CAN DO IT MORE SIMPLE  ]
// +----------------------------------------------------------------------
// | Copyright (c) 2018-2020 rights reserved.
// +----------------------------------------------------------------------
// | 
// +----------------------------------------------------------------------
// | Date: 2020-08-30 14:59
// +----------------------------------------------------------------------
namespace app\system\middleware;

use app\model\system\Admin as AdminModel;
use app\Request;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\JWT;
use library\exceptions\AuthException;
use library\interfaces\MiddlewareInterface;
use think\facade\Cache;
use think\facade\Config;

class AdminAuthTokenMiddleware implements MiddlewareInterface
{
    public function handle(Request $request, \Closure $next)
    {
        $authInfo = null;
        $token = trim($request->header(Config::get('cookie.system_token_name','')));
        $adminInfo = $this->adminParseToken($token);
        $request->adminInfo = $adminInfo;
        return $next($request);
    }



    /**
     * 获取Admin授权信息
     * @param $token
     * @param int $expires
     * @param string $prefix
     * @return array
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public static function adminParseToken($token): array
    {
        $redis = Cache::store('redis');
        if (!$token || !$redis->has($token) || !($cacheToken = $redis->get($token)))
            throw new AuthException('登录过期了，请重新登录', -9);
        try {
            [$adminInfo, $type] = AdminModel::parseToken($cacheToken['token']);
            Cache::store('redis')->set($token, $cacheToken, $cacheToken['exp']);
        } catch (ExpiredException $e) {
            list($headb64, $bodyb64, $cryptob64) = explode('.', $cacheToken['token']);
            $payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64));
            $type = $payload->jti->type;
            $adminInfo = AdminModel::where('id', $payload->jti->id)->find();
            if (!$adminInfo) {
                $redis->delete($token);
                throw new AuthException('登录过期了，请重新登录', -9);
            }
            $redis->set($cacheToken['token'], $cacheToken, $cacheToken['exp']);
        } catch (\Throwable $e) {
            $redis->delete($token);
            throw new AuthException('登录过期了，请重新登录', -9);
        } catch (\Throwable $e) {
            throw new AuthException('登录过期了，请重新登录', -9);
        }
        if (!isset($adminInfo) || !$adminInfo || !$adminInfo->id) {
             $redis->delete($token);
            throw new AuthException('登录过期了，请重新登录', -9);
        }
        return $adminInfo->toArray();
    }
}