<?php
namespace app\wechatminiprogram\controller;
use think\facade\Db;
use think\helper\Str;
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\UploadFile;
use helper\URL;
use sendSms\SendSms;

class Login extends Base
{
    public function index()
    {
        $wxConfig=config('xy_wechatminiprogram');
        if(empty($wxConfig['status']) || !$wxConfig['status'])
            return $this->ajaxReturn('小程序暂不可用',MsgCode::$error);
        $D=request()->post();
        if(empty($D['code']))
            return $this->ajaxReturn('授权失败[100]',MsgCode::$error);
        $ret=json_decode(URL::get('https://api.weixin.qq.com/sns/jscode2session',[
            'appid'=>$wxConfig['appid'],
            'secret'=>$wxConfig['secret'],
            'js_code'=>$D['code'],
            'grant_type'=>'authorization_code',
            ]),true);
        if(empty($ret['unionid'])||empty($ret['openid']))
            return $this->ajaxReturn('授权失败[101]',MsgCode::$error);
        $UserWxModel=UserWxModel::where(['unionid'=>$ret['unionid']])->find();
        if (!$UserWxModel)
            $UserWxModel=UserWxModel::where(['mp_openid'=>$ret['openid']])->find();

        if ($UserWxModel && $UserWxModel->uid){
            $UserWxModel->mp_openid=$ret['openid'];
            $UserInfo=UserModel::getAppUserInfo(['user.id'=>$UserWxModel->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->online_time=time();
            $UserTimer->online_ip=request()->ip();
            $UserTimer->online_devices=request()->header('xycms-deviceid');
            $UserTimer->login_time=time();
            $UserTimer->login_ip=request()->ip();
            $UserTimer->login_devices=request()->header('xycms-deviceid');
            $UserLoginLog=new UserLoginLogModel;
            $UserLoginLog->uid=$UserInfo->id;
            $UserLoginLog->appid=request()->ApiInfo['app_id'];
            $UserLoginLog->ip=request()->ip();
            $UserLoginLog->devices_id=request()->header('xycms-deviceid');
            Db::startTrans();
            try {
                $UserWxModel->save();
                $UserTimer->save();
                $UserLoginLog->save();
                Db::commit();
                return $this->ajaxReturn('登录成功',MsgCode::$success,$UserInfo);
            } catch (Exception $e) {
                Db::rollback();
                return $this->ajaxReturn('登录失败，请重试',MsgCode::$error);
            }
        }else{
            $Data=[
                'openId'        =>  $ret['openid'],
                'unionId'       =>  $ret['unionid'],
                'session_key'   =>  $ret['session_key'],
            ];
            return $this->ajaxReturn('',MsgCode::$captcha,$Data);
        }
    }
    /**
     * 检验数据的真实性，并且获取解密后的明文.
     * @param $encryptedData string 加密的用户数据
     * @param $iv string 与用户数据一同返回的初始向量
     * @param $data string 解密后的原文
     *
     * @return int 成功0，失败返回对应的错误码
     */
    public function decryptData( $encryptedData, $iv,$sessionKey)
    {
        $wxConfig=config('xy_wechatminiprogram');
        if (strlen($sessionKey) != 24)
            return false;

        $aesKey=base64_decode($sessionKey);
        if (strlen($iv) != 24) 
            return false;

        $aesIV=base64_decode($iv);
        $aesCipher=base64_decode($encryptedData);
        $result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
        $dataObj=json_decode( $result );
        if( $dataObj  == NULL )
            return false;
        if( $dataObj->watermark->appid != $wxConfig['appid'] )
            return false;
        return json_decode($result,true);
    }
    public function bindWx()
    {
        $D=request()->post();
        $result=$this->decryptData($D['encrypted'],$D['iv'],$D['session_key']);
        if($result){
            $D['username']=$result['purePhoneNumber'];
            $D['headimg']=$D['avatarUrl'];
            $D['nickName']=$D['nickName'];
            $User=UserModel::where(['mobile'=>$D['username']])->find();
            if (!$User){
            	$uid=$this->register($D);
            }else{
	            if (!$User->status)
	                return $this->ajaxReturn($User->disable_msg,MsgCode::$error);
            	$uid=$User->id;
            }
            if($uid){
                $UserWxModel=UserWxModel::where(['unionid'=>$D['unionId']])->find();
                if (!$UserWxModel)
                    $UserWxModel=UserWxModel::where(['mp_openid'=>$D['openId']])->find();
                if(!$UserWxModel){
                    $UserWxModel=new UserWxModel;
                }elseif($UserWxModel->uid && $uid===$UserWxModel->uid){
                    return $this->ajaxReturn('该微信已绑定用户，请勿重复绑定',MsgCode::$error);
                }
                if (UserWxModel::where(['uid'=>$uid])->count())
                    return $this->ajaxReturn('该手机号已绑定其他微信账户，请换个手机号重试',MsgCode::$error);

                $UserWxModel->uid           =   $uid;
                $UserWxModel->nickname      =   base64_encode($D['nickName']);
                $UserWxModel->mp_openid     =   $D['openId'];
                $UserWxModel->unionid       =   $D['unionId'];
                $UserWxModel->sex           =   $D['gender'];
                $UserWxModel->headimgurl    =   $D['avatarUrl'];
                $UserWxModel->city          =   $D['city'];
                $UserWxModel->province      =   $D['province'];
                $UserWxModel->country       =   $D['country'];
                if ($UserWxModel->save()) {
                    $UserInfo=UserModel::getAppUserInfo(['user.id'=>$UserWxModel->uid]);
                    return $this->ajaxReturn('绑定成功',MsgCode::$success,$UserInfo);
                }else{
                    return $this->ajaxReturn('更新用户信息失败，请重试',MsgCode::$error);
                }
            }else{
                return $this->ajaxReturn('绑定失败，请重试',MsgCode::$error);
            }
        }else{
            return $this->ajaxReturn('解析用户信息失败',MsgCode::$error);
        }
    }
    public function register($D)
    {
        $passHash=Str::random(4);
        /*用户信息*/
        $User=new UserModel;
        $User->mobile=$D['username'];
        /*用户详细信息*/
        $UserInfo=new UserInfoModel;
        $UserInfo->nickname=base64_encode($D['nickName']);
        $UserInfo->headimg=config('xy_default_avatar.user');
        $headimg=UploadFile::downWxAvatar($D['headimg']);
        if($headimg['code']===0)
            $UserInfo->headimg=$headimg['data']['path'];
        $UserInfo->role_type=0;
        $UserInfo->app_id=request()->ApiInfo['app_id'];
        /*用户时间线*/
        $UserTimer=new UserTimerModel;
        $UserTimer->online_time=time();
        $UserTimer->online_ip=request()->ip();
        $UserTimer->online_devices=request()->header('xycms-deviceid');
        $UserTimer->login_time=time();
        $UserTimer->login_ip=request()->ip();
        $UserTimer->login_devices=request()->header('xycms-deviceid');
        $UserTimer->register_time=time();
        $UserTimer->register_ip=request()->ip();
        $UserTimer->register_devices=request()->header('xycms-deviceid');
        $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();
            // 提交事务
            Db::commit();
            return $User->id;
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            return false;
        }
    }
    public function getVcode()
    {
        $D=request()->post();
        /**
         * 用户验证
         */
        try {
            validate(LoginValidate::class)->scene('getCode')->check($D);
        } catch (ValidateException $e) {
            return $this->ajaxReturn($e->getError(),MsgCode::$error);
        }
        switch ($D['is_username_type']) {
            case 'email':
                $msg=LoginValidate::VerificationEmailSendSum($D['username']);
                if($msg) return $this->ajaxReturn($msg,MsgCode::$error);
                break;
            case 'mobile':
                $msg=LoginValidate::VerificationMobileSendSum($D['username']);
                if($msg) return $this->ajaxReturn($msg,MsgCode::$error);
                break;
            default:
                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 outLogin()
    {
        $UserDevicesModel=UserDevicesModel::where(['uid'=>request()->_uid,'appid'=>request()->ApiInfo['app_id'],'devices_id'=>request()->header('xycms-deviceid')])->find();
        if($UserDevicesModel&&$UserDevicesModel->delete()){
            return $this->ajaxReturn();
        }else{
            return $this->ajaxReturn();
        }
    }
}
