<?php
namespace app\index\controller;
use think\facade\View;
use think\facade\Session;
use think\facade\Cache;
use think\facade\Cookie;
use think\facade\Db;
use think\helper\Str;
use app\common\QrcodeUtil;
use app\common\variable\MsgCode;
use think\exception\ValidateException;
use app\common\validate\Login as LoginValidate;
use app\common\model\User as UserModel;
use app\common\model\UserVip as UserVipModel;
use app\common\model\UserDevices as UserDevicesModel;
use app\common\model\UserInfo as UserInfoModel;
use app\common\model\UserTimer as UserTimerModel;
use app\common\model\UserLoginLog as UserLoginLogModel;
use app\common\model\UserWx as UserWxModel;
use app\common\controller\Captcha as CaptchaController;
use sendSms\SendSms;
use app\common\UploadFile;
class Login extends Base
{
    public function index()
    {
    	if (request()->isAjax()) {
            $D=request()->post();
            $is_imgcode=intval(Cookie::get('is_imgcode'),0);
            if ($is_imgcode && $is_imgcode>=config('captcha.error_sum')){
                if (!CaptchaController::captcha_check($D))
                    return $this->ajaxReturn('验证码错误',MsgCode::$captcha);
            }
            $errorCode=MsgCode::$error;
            $is_imgcode=$is_imgcode+1;
            if ($is_imgcode && $is_imgcode>=config('captcha.error_sum'))$errorCode=MsgCode::$captcha;
            /**
             * 用户验证
             */
            try {
                validate(LoginValidate::class)->scene('login')->check($D);
            } catch (ValidateException $e) {
                Cookie::set('is_imgcode',$is_imgcode);
                return $this->ajaxReturn($e->getError(),$errorCode);
            }
            $where[$D['is_username_type']]=$D['username'];
            $UserPassword=UserModel::getUserPassword($where);
            /*验证密码*/
            if (!$UserPassword){
                Cookie::set('is_imgcode',$is_imgcode);
                return $this->ajaxReturn('用户不存在',$errorCode);
            }
        	if (UserModel::getPassword($UserPassword['password_hash'],$D['password'])!=$UserPassword['password']){
                Cookie::set('is_imgcode',$is_imgcode);
                return $this->ajaxReturn('密码不正确',$errorCode);
            }
            /*验证用户状态*/
    		$UserInfo=UserModel::getWebUserInfo(['user.id'=>$UserPassword['id']]);
    		if (!$UserInfo){
                Cookie::set('is_imgcode',$is_imgcode);
                return $this->ajaxReturn('用户信息不存在',$errorCode);
            }
            if (!$UserInfo['status']){
                Cookie::set('is_imgcode',$is_imgcode);
                return $this->ajaxReturn($UserInfo['disable_msg'],$errorCode);
            }
            $UserTimer = UserTimerModel::where(['uid'=>$UserInfo['id']])->find();
            $UserTimer->login_time=time();
            $UserTimer->login_ip=request()->ip();
            $UserTimer->login_devices=substr(request()->header('user-agent'),0,200);
            $UserLoginLog=new UserLoginLogModel;
            $UserLoginLog->uid=$UserInfo->id;
            $UserLoginLog->appid=request()->ApiInfo['app_id'];
            $UserLoginLog->ip=request()->ip();
            $UserLoginLog->devices_id=substr(request()->header('user-agent'),0,200);
            if (!empty($D['cache']) && $D['cache'])
                $this->cacheUserInfo($UserInfo);
            Db::startTrans();
            try {
                $UserTimer->save();
                $UserLoginLog->save();
                Db::commit();
                $this->setSuccessLogin($UserInfo);
                Cookie::delete('is_imgcode');
                return $this->ajaxReturn('登录成功',MsgCode::$success,$UserInfo);
            } catch (Exception $e) {
                Db::rollback();
                return $this->ajaxReturn('登录失败，请重试',$errorCode);
            }
    	}else{
	        return View::fetch();
    	}
    }
    public function vcode()
    {
        if (request()->isAjax()) {
            $D=request()->post();
            /**
             * 用户验证
             */
            try {
                validate(LoginValidate::class)->scene('vcode')->check($D);
            } catch (ValidateException $e) {
                return $this->ajaxReturn($e->getError(),MsgCode::$error);
            }
            $SendSms = new SendSms;
            $SendSms->sendType=$D['is_username_type'];
            $SendSms->username=$D['username'];
            $SendSms->vcode=$D['vcode'];
            $SendSms->action=$D['type'];
            if (!$SendSms->verification()){
                return $this->ajaxReturn($SendSms->getError(),MsgCode::$error);
            }

            $where['user.'.$D['is_username_type']]=$D['username'];
            /*验证用户状态*/
            $UserInfo=UserModel::getWebUserInfo($where);
            if (!$UserInfo){
                return $this->ajaxReturn('用户信息不存在',MsgCode::$error);
            }
            if (!$UserInfo['status']){
                return $this->ajaxReturn($UserInfo['disable_msg'],MsgCode::$error);
            }
            $UserTimer = UserTimerModel::where(['uid'=>$UserInfo['id']])->find();
            $UserTimer->login_time=time();
            $UserTimer->login_ip=request()->ip();
            $UserTimer->login_devices=request()->header('user-agent');
            $UserLoginLog=new UserLoginLogModel;
            $UserLoginLog->uid=$UserInfo->id;
            $UserLoginLog->appid=request()->ApiInfo['app_id'];
            $UserLoginLog->ip=request()->ip();
            $UserLoginLog->devices_id=substr(request()->header('user-agent'),0,200);
            if (!empty($D['cache']) && $D['cache'])
                $this->cacheUserInfo($UserInfo);
            Db::startTrans();
            try {
                $UserTimer->save();
                $UserLoginLog->save();
                Db::commit();
                $SendSms->delVcode();
                $this->setSuccessLogin($UserInfo);
                Cookie::delete('is_imgcode');
                return $this->ajaxReturn('登录成功',MsgCode::$success,$UserInfo);
            } catch (Exception $e) {
                Db::rollback();
                return $this->ajaxReturn('登录失败，请重试',MsgCode::$error);
            }
        }else{
            return View::fetch();
        }
    }
    public function register()
    {
        if (request()->isAjax()) {
            $D=request()->post();
            if (empty($D['is_username_type'])){
                return $this->ajaxReturn('未知的登录方式',MsgCode::$error);
            }
            $SendSms = new SendSms;
            $SendSms->sendType=$D['is_username_type'];
            $SendSms->username=$D['username'];
            $SendSms->vcode=$D['vcode'];
            $SendSms->action=$D['type'];
            if (!$SendSms->verification()){
                return $this->ajaxReturn($SendSms->getError(),MsgCode::$error);
            }
            $UserWxId=Session::get('UserWxId');
            if ($UserWxId) {
                $UserWxModel=UserWxModel::where(['id'=>$UserWxId])->find();
                if ($UserWxModel->uid)
                    return $this->ajaxReturn('该微信已绑定用户',MsgCode::$error);
            }
            $UserQqId=Session::get('UserQqId');
            if ($UserQqId) {
                $UserQqModel=UserQqModel::where(['id'=>$UserQqId])->find();
                if ($UserQqModel->uid)
                    return $this->ajaxReturn('该QQ已绑定用户',MsgCode::$error);
            }
            $where['user.mobile']=$D['username'];
            /*验证用户状态*/
            $UserInfo=UserModel::getWebUserInfo($where);
            if ($UserInfo){
                if (!$UserInfo['status']){
                    return $this->ajaxReturn($UserInfo['disable_msg'],MsgCode::$error);
                }
                $UserTimer = UserTimerModel::where(['uid'=>$UserInfo['id']])->find();
                $UserTimer->login_time=time();
                $UserTimer->login_ip=request()->ip();
                $UserTimer->login_devices=request()->header('user-agent');
                $UserLoginLog=new UserLoginLogModel;
                $UserLoginLog->uid=$UserInfo->id;
                $UserLoginLog->appid=request()->ApiInfo['app_id'];
                $UserLoginLog->ip=request()->ip();
                $UserLoginLog->devices_id=substr(request()->header('user-agent'),0,200);
                if ($UserWxId&&!empty($UserInfo['wx']))
                    return $this->ajaxReturn('该用户已绑定微信',MsgCode::$error);
                if ($UserQqId&&!empty($UserInfo['qq']))
                    return $this->ajaxReturn('该用户已绑定QQ',MsgCode::$error);
                if (!empty($D['cache']) && $D['cache'])
                    $this->cacheUserInfo($UserInfo);
                Db::startTrans();
                try {
                    $UserTimer->save();
                    $UserLoginLog->save();
                    if ($UserWxId) {
                        $UserWxModel->uid=$UserInfo['id'];
                        $UserWxModel->save();
                    }
                    if ($UserQqId) {
                        $UserQqModel->uid=$UserInfo['id'];
                        $UserQqModel->save();
                    }
                    Db::commit();
                    $SendSms->delVcode();
                    $this->setSuccessLogin($UserInfo);
                    Cookie::delete('is_imgcode');
                    Session::delete('BindUserInfo');
                    Session::delete('UserWxId');
                    Session::delete('UserQqId');
                    return $this->ajaxReturn('登录成功',MsgCode::$success,$UserInfo);
                } catch (Exception $e) {
                    Db::rollback();
                    return $this->ajaxReturn('登录失败，请重试',MsgCode::$error);
                }
            }
            /**
             * 用户验证
             */
            try {
                validate(LoginValidate::class)->scene('register')->check($D);
            } catch (ValidateException $e) {
                return $this->ajaxReturn($e->getError(),MsgCode::$error);
            }
            $passHash=Str::random(4);
            /*用户信息*/
            $User=new UserModel;
            $User->mobile=$D['username'];
            if (!empty($D['password']))
                $User->password=UserModel::getPassword($passHash,$D['password']);
            $User->password_hash=$passHash;
            /*用户详细信息*/
            $UserInfo=new UserInfoModel;
            if (Session::has('BindUserInfo')) {
                $BindUserInfo=Session::get('BindUserInfo');
                $UserInfo->nickname=$BindUserInfo['nickname'];
                $UserInfo->headimg=config('xy_default_avatar.user');
                $headimg=UploadFile::downWxAvatar($BindUserInfo['headimg']);
                if($headimg['code']===0)
                    $UserInfo->headimg=$headimg['data']['path'];
            }else{
                $UserInfo->nickname=base64_encode('XY_'.substr_replace($D['username'],'****',3,4));
                $UserInfo->headimg=config('xy_default_avatar.user');
            }
            $UserInfo->role_type=$D['role_type']?1:0;
            $UserInfo->app_id=request()->ApiInfo['app_id'];
            /*用户时间线*/
            $UserTimer=new UserTimerModel;
            $UserTimer->online_time=time();
            $UserTimer->online_ip=request()->ip();
            $UserTimer->online_devices=substr(request()->header('user-agent'),0,200);
            $UserTimer->login_time=time();
            $UserTimer->login_ip=request()->ip();
            $UserTimer->login_devices=substr(request()->header('user-agent'),0,200);
            $UserTimer->register_time=time();
            $UserTimer->register_ip=request()->ip();
            $UserTimer->register_devices=substr(request()->header('user-agent'),0,200);
            $UserVipModel=new UserVipModel;
            // 启动事务
            Db::startTrans();
            try {
                $User->save();
                $UserInfo->uid=$User->id;
                $UserTimer->uid=$User->id;
                $UserVipModel->uid=$User->id;
                $UserVipModel->save();
                $UserInfo->save();
                $UserTimer->save();
                if ($UserWxId) {
                    $UserWxModel->uid=$User->id;
                    $UserWxModel->save();
                }
                if ($UserQqId) {
                    $UserQqModel->uid=$User->id;
                    $UserQqModel->save();
                }
                // 提交事务
                Db::commit();
                Session::delete('BindUserInfo');
                Session::delete('UserWxId');
                Session::delete('UserQqId');
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                return $this->ajaxReturn('注册失败，请重试',MsgCode::$error);
            }
            $SendSms->delVcode();
            $where['user.id']=$User->id;
            $UserInfo=UserModel::getWebUserInfo($where);
            $this->setSuccessLogin($UserInfo);
            Cookie::delete('is_imgcode');
            return $this->ajaxReturn('注册成功',MsgCode::$success,$UserInfo);
        }else{
            return View::fetch();
        }
    }
    public function bind()
    {
        $G=request()->get();
        View::assign('UserInfo',$G);
        return View::fetch();
    }
    public function getVcode()
    {
        if (request()->isAjax()) {
            $D=request()->post();
            $is_imgcode=intval(Cookie::get('is_imgcode'),0);
            if (!CaptchaController::captcha_check($D))
                return $this->ajaxReturn('验证码错误',MsgCode::$error);
            $is_imgcode=$is_imgcode+1;
            /**
             * 用户验证
             */
            try {
                validate(LoginValidate::class)->scene('getCode')->check($D);
            } catch (ValidateException $e) {
                Cookie::set('is_imgcode',$is_imgcode);
                return $this->ajaxReturn($e->getError(),MsgCode::$error);
            }
            switch ($D['is_username_type']) {
                case 'email':
                    $msg=LoginValidate::VerificationEmailSendSum($D['username']);
                    if($msg){
                        Cookie::set('is_imgcode',$is_imgcode);
                        return $this->ajaxReturn($msg,MsgCode::$error);
                    }
                    break;
                case 'mobile':
                    $msg=LoginValidate::VerificationMobileSendSum($D['username']);
                    if($msg){
                        Cookie::set('is_imgcode',$is_imgcode);
                        return $this->ajaxReturn($msg,MsgCode::$error);
                    }
                    break;
                default:
                    Cookie::set('is_imgcode',$is_imgcode);
                    return $this->ajaxReturn('未知的验证方式',MsgCode::$error);
                    break;
            }
            $SendSms = new SendSms;
            $SendSms->sendType=$D['is_username_type'];
            $SendSms->username=$D['username'];
            $SendSms->action=$D['type'];
            if($SendSms->sendVcode()){
                return $this->ajaxReturn('验证码已发送');
            }else{
                return $this->ajaxReturn($SendSms->getError(),MsgCode::$error);
            }
        }
    }
    public function verificationVcode()
    {
        if (request()->isAjax()) {
            $D=request()->post();
            /**
             * 用户验证
             */
            try {
                validate(LoginValidate::class)->scene('verificationVcode')->check($D);
            } catch (ValidateException $e) {
                return $this->ajaxReturn($e->getError(),MsgCode::$error);
            }
            $SendSms = new SendSms;
            $SendSms->sendType=$D['is_username_type'];
            $SendSms->username=$D['username'];
            $SendSms->vcode=$D['vcode'];
            $SendSms->action=$D['type'];
            if ($SendSms->verification()) {
                return $this->ajaxReturn();
            }else{
                return $this->ajaxReturn($SendSms->getError(),MsgCode::$error);
            }
        }
    }
    public function cacheUserInfo($UserInfo)
    {
        $key=md5(request()->ip().'&'.$UserInfo->id.'&'.time());
        Cache::set($key,$UserInfo->toArray(),3600*24*7);
        Cookie::set('cacheUserInfo',$key,3600*24*7);
    }
    public function setSuccessLogin($UserInfo)
    {
        if (!Session::has('User')) {
            $key=md5('Message:&'.request()->ip().'&'.$UserInfo->id.'&'.time().'&'.Str::random(8));
            $UserInfo->token=$key;
            $UserInfo->client_id=[];
            Session::set('User',$UserInfo->toArray());
            Cache::set('Message::'.$key,$UserInfo->id);
        }
    }
    public function loginQrcode()
    {
        $G=request()->get();
        $logo_url=str_replace('/public/','/',config('web.icon'));
        $logo_url=str_replace('/uploads','uploads',$logo_url);
        $qrObj=new QrcodeUtil([
            'logo'      =>  true,
            'logo_url'  =>  $logo_url
        ]);
        $scheme=config('web.downUrl').'/qrlogin/'.$G['scheme'].'/'.request()->ip();
        return response($qrObj->createServer($scheme))->header([
            'Content-Type'=>$qrObj->_qr->getContentType()
        ]);
    }
    public function qrlogin($client_id,$to_client_id)
    {
        $User=Cache::pull(md5($to_client_id.$client_id));
        if($User&&$User['uid']&&$User['ip']===request()->ip()){
            /*验证用户状态*/
            $UserInfo=UserModel::getWebUserInfo(['user.id'=>$User['uid']]);
            if (!$UserInfo)
                return $this->ajaxReturn('用户信息不存在',MsgCode::$error);
            if (!$UserInfo['status'])
                return $this->ajaxReturn($UserInfo['disable_msg'],MsgCode::$error);
            $UserTimer = UserTimerModel::where(['uid'=>$UserInfo->id])->find();
            $UserTimer->login_time=time();
            $UserTimer->login_ip=request()->ip();
            $UserTimer->login_devices='scan_qr_login';
            $UserLoginLog=new UserLoginLogModel;
            $UserLoginLog->uid=$UserInfo->id;
            $UserLoginLog->appid=request()->ApiInfo['app_id'];
            $UserLoginLog->ip=request()->ip();
            $UserLoginLog->devices_id='scan_qr_login';
            Db::startTrans();
            try {
                $UserTimer->save();
                $UserLoginLog->save();
                Db::commit();
                $this->setSuccessLogin($UserInfo);
                return $this->ajaxReturn('登录成功',MsgCode::$success);
            } catch (Exception $e) {
                Db::rollback();
                return $this->ajaxReturn('登录失败，请重试',MsgCode::$error);
            }

        }else{
            return $this->ajaxReturn('授权失败，请重试',MsgCode::$error);
        }
    }
    /**
     * [captcha 手动验证码]
     * @return [type] [description]
     */
    public function captcha()
    {
        return CaptchaController::captcha();
    }
}
