<?php
namespace app\common\middleware;
use think\facade\View;
use think\facade\Session;
use think\facade\Cache;
use think\facade\Cookie;
use GatewayClient\Gateway;
use think\facade\Db;
use app\common\variable\MsgCode;
use app\common\model\ApiLog;
use app\common\model\User as UserModel;
use app\common\model\UserTimer as UserTimerModel;


class VerificationWeb
{
    public function handle($request, \Closure $next)
    {
        if (!Session::has('User.id')) {
            $cacheUserInfo=Cookie::get('cacheUserInfo');
            if ($cacheUserInfo) {
                $UserInfo=Cache::get($cacheUserInfo);
                Session::set('User',$UserInfo);
            }
        }
        $subDomain=request()->subDomain();
        if($subDomain)
            $this->sub_website($subDomain,$request);
        $authRet=$this->auth($request);
        if (true!==$authRet['status']) {
            switch ($authRet['code']) {
                case MsgCode::$login:
                    if (request()->isAjax()) {
                        return $this->ajaxReturn($authRet['msg'],$authRet['code']);
                    }else{
                        if (request()->controller()!='Login') {
                            Session::set('redirect_remember', true);
                            return redirect('/login')->remember();
                        }
                    }
                    break;
                
                default:
                    if(request()->isAjax()){
                        return $this->ajaxReturn($authRet['msg'],$authRet['code']);
                    }else{
                        if (request()->action()!='maintenance') {
                            return redirect('/system/maintenance?msg='.$authRet['msg']);
                        }
                    }
                    break;
            }
        }
        if (request()->controller()=='Login'&&request()->action()!='captcha') {
            if (Session::has('User.id')) {
                if (!request()->isAjax()) {
                    if (Session::has('redirect_remember')){
                        Session::delete('redirect_remember');
                        return redirect()->restore();
                    }
                    return redirect('/user');
                }
            }
        }
	    return $next($request);
    }
    protected function sub_website($alias,$request)
    {
        $SubWebsiteData=Cache::get('SubWebsiteData');
        if (!empty($SubWebsiteData[$alias])) {
            $Find=$SubWebsiteData[$alias];
            if ($Find['type']) {
                $request->sub_industry=$Find['alias_id'];
            }else{
                if (!empty($Find['alias_str'][0]))
                    $request->sub_province=$Find['alias_str'][0];
                if (!empty($Find['alias_str'][1]))
                    $request->sub_city=$Find['alias_str'][1];
                if (!empty($Find['alias_str'][2]))
                    $request->sub_area=$Find['alias_str'][2];
            }
            View::assign('sub_title',$Find['title']);
        }
    }
    protected function auth($request)
    {
        $modul=app('http')->getName();
        $controller=request()->controller();
        $action=request()->action();
        /*获取当前应用*/
        $AppInfo=Cache::get('client.app.'.$modul);
        if (!$AppInfo) 
            return ['status'=>false,'msg'=>'应用不存在','code'=>MsgCode::$apiError];
        /*判断当前应用状态*/
        if (!$AppInfo['app_status'])
            return ['status'=>false,'msg'=>$AppInfo['app_status_msg'],'code'=>MsgCode::$apiError];
        /*获取当前应用下的所有接口*/
        $ApiData=Cache::get('client.api.'.$modul);
        if (!$ApiData) 
            return ['status'=>false,'msg'=>'接口不存在','code'=>MsgCode::$apiError];
        /*判断当前接口是否存在*/
        if (empty($ApiData[$controller.'/'.$action]))
            return ['status'=>false,'msg'=>'接口不存在','code'=>MsgCode::$apiError];
        /*判断当前接口状态*/
        $ApiInfo=$ApiData[$controller.'/'.$action];
        if (!$ApiInfo['api_status'])
            return ['status'=>false,'msg'=>$ApiInfo['api_status_msg'],'code'=>MsgCode::$apiError];
        /*判断当前接口是否需要登录*/
        $uid=0;
        if (Session::has('User.id'))
            $uid=Session::get('User.id');
        if ($ApiInfo['api_is_login']){
            if (!Session::has('User.id'))
                return ['status'=>false,'msg'=>'请先登录','code'=>MsgCode::$login];

            $UserModel=UserModel::where(['id'=>$uid])->field('status,disable_msg')->find();
            if(!$UserModel->status){
                $this->outLogin();
                return ['status'=>false,'msg'=>$UserModel->disable_msg,'code'=>MsgCode::$apiError];
            }
        }
        if (config('basic.api_xycms_concurrent_sum')&&ApiLog::where(['ip'=>request()->ip()])->whereTime('create_time','between',[time()-3,time()+1])->count()>config('basic.api_xycms_concurrent_sum'))
            return ['status'=>false,'msg'=>'访问过于频繁','code'=>MsgCode::$apiError];
        /*记录访问日志*/
        $api_log=new ApiLog;
        $api_log->title     = $ApiInfo['api_name'];
        $api_log->uid       = $uid;
        $api_log->app       = $ApiInfo['app_id'];
        $api_log->api       = $ApiInfo['api_id'];
        $api_log->route     = request()->url();
        $api_log->mca       = $modul.'/'.$controller.'/'.$action;
        $api_log->param     = json_encode(request()->param(),JSON_UNESCAPED_UNICODE);
        $api_log->ip        = request()->ip();
        $api_log->systype   = substr(request()->header('user-agent'),0,200);
        $api_log->save();
        if($uid){
            $UserTimer = UserTimerModel::where(['uid'=>$uid])->find();
            if($UserTimer){
                $UserTimer->online_time=time();
                $UserTimer->online_ip=request()->ip();
                $UserTimer->online_devices=substr(request()->header('user-agent'),0,200);
                $UserTimer->save();
            }
        }
        View::assign('appInfo',$AppInfo);
        View::assign('apiInfo',$ApiInfo);
        if($ApiInfo['api_is_web_name']){
            if (empty($ApiInfo['seo_title'])) {
                View::assign('webtitle',$ApiInfo['api_name'].' - '.config('web.name'));
            }else{
                View::assign('webtitle',$ApiInfo['seo_title'].' - '.config('web.name'));
            }
        }else{
            if (empty($ApiInfo['seo_title'])) {
                View::assign('webtitle',$ApiInfo['api_name']);
            }else{
                View::assign('webtitle',$ApiInfo['seo_title']);
            }
        }
        if (!empty($ApiInfo['seo_keywords']))
            View::assign('keywords',$ApiInfo['seo_keywords']);
        if (!empty($ApiInfo['seo_description']))
            View::assign('description',$ApiInfo['seo_description']);
        unset($AppInfo['app_key_secret']);
        $request->AppInfo=$AppInfo;
        $request->ApiInfo=$ApiInfo;
        return ['status'=>true];
    }
    /**
     * [ajaxReturn 返回json]
     * @param  integer $code [description]
     * @param  [type]  $data [description]
     * @return [type]        [description]
     */
    protected function ajaxReturn($msg='Success',$code=0){
        if (!$code)$code=MsgCode::$success;
        return json(['code'=>$code,'msg'=>$msg]);
    }
    /**
     * [outLogin 注销登录]
     * @return [type] [description]
     */
    public function outLogin()
    {
        $UserInfo=Session::get('User');
        if ($UserInfo) {
            Session::delete('User');
            $cacheUserInfo=Cookie::get('cacheUserInfo');
            if ($cacheUserInfo)
                Cache::delete($cacheUserInfo);
            $MessageKey=Cache::get('Message::'.$UserInfo['id']);
            if ($MessageKey) {
                Cache::delete('Message::'.$UserInfo['id']);
                Cache::delete('Message::'.$MessageKey);
            }
            if (!empty($UserInfo['client_id'])) {
                Gateway::$registerAddress = config('gateway_worker.registerAddress');
                Gateway::sendToGroup('Pc:uid-'.$UserInfo['id'],socketMsg('outLogin'));
                Gateway::ungroup('Pc:uid-'.$UserInfo['id']);
                foreach ($UserInfo['client_id'] as $k => $client_id) {
                    Gateway::joinGroup($client_id, 'Pc:role-company');
                    Gateway::joinGroup($client_id, 'Pc:role-personal');
                }
            }
        }
    }
}