<?php

namespace app\mobile\middleware;


use app\mobile\logic\BaseLogic;
use app\model\AccountModel;
use app\model\AccountTokenModel;
use app\model\CommonModel;
use think\exception\ValidateException;
use think\facade\Config;
use think\facade\Validate;
use think\Response;
use app\model\AccountLogModel;

//中间件
class mobileMiddleware
{

    //白名单
    private $white_list = ['login'];

    //请求入口
    public function handle($request, \Closure $next)
    {

        //请求的唯一标识
        $request->request_id = date('YmdHis') . mt_rand(100000, 999999);

        //接收参数
        $param = $request->post();

        //记录日志
        AccountLogModel::add($request->request_id, $param);

        //判断白名单
        if (!in_array(request()->pathinfo(), $this->white_list)) {

            try {

                $val = Validate::rule(['token' => 'require']);

                if (!$val->check($param)) throw new ValidateException($val->getError());

                //获取用户信息
                $account = $this->verifyMobileToken($param['token']);
                BaseLogic::setUserInfo($account['aid'], $account['aname'], $account['company_id'], $account['card_id']);

                $request->aid = $account['aid'];
                $request->aname = $account['aname'];
                $request->company_id = $account['company_id'];
                $request->card_id = $account['card_id'];
            } catch (ValidateException $validateException) {
                return json_show(CommonModel::$error_token, $validateException->getError());
            }
        }

        return $next($request);

    }


    //请求结束的回调(如果返回数据用的是app_show/error_show,即直接echo,则不会触发该方法)
    public function end(Response $response)
    {
        //只做记录,不做输出
        AccountLogModel::where('request_id', request()->request_id)->save([
            'response' => $response->getContent(),
            'uid' => request()->uid ?? 0,
            'uname' => request()->uname ?? '',
            'updatetime' => date('Y-m-d H:i:s')
        ]);
    }

    //校验手机端token
    private function verifyMobileToken(string $token = '')
    {
        $has = AccountTokenModel::where(['token' => $token])->findOrEmpty();
        if ($has->isEmpty()) throw new ValidateException('token不存在');

        if (strtotime($has->expiretime) <= time()) throw new ValidateException('token已失效');

        $account = AccountModel::where(['id' => $has->accountid, 'is_del' => CommonModel::$del_normal])
            ->field('id,status,username,salt,company_id,card_id')
            ->findOrEmpty();
        if ($account->isEmpty()) throw new ValidateException('未找到账户');

        if ($account->status != AccountModel::$status_activated) throw new ValidateException('账户不在激活状态,无法使用');

        $token_str = base64_decode($token);

        $account_str = substr($token_str, 0, -10);
        if ($account_str == $account->username . $account->salt) {
            AccountTokenModel::where(['token' => $token])
                ->save(['expiretime' => date('Y-m-d H:i:s', time() + Config::get('common.expire'))]);
            return ['aid' => $account->id, 'aname' => $account->username, 'company_id' => $account->company_id, 'card_id' => $account->card_id];
        } else throw new ValidateException('账户token无效');

    }

}