<?php
namespace Base\Domain\Authorization;

use Base\Common\ToolUtil;
use Base\Domain\AppAssign as AppAssignDomain;
use Base\Domain\Apps as AppsDomain;
use Base\Domain\Base;
use Base\Domain\Login;
use Base\Domain\User as UserDomain;
use Base\Domain\UserType;
use Base\Model\Authorization as AuthorizationModel;
use PhalApi\Exception\BadRequestException;

//新的统一登录
class AuthorizationLogin extends Base
{
    public $haveRegister = false; //是否已注册
    public $haveBind = false; //是否已经绑定了
    public $authorizationInfo = []; //authorizationInfo表信息
    public $registerInfo = [
        'from_channel'=>'',//app来源
        'username'=> '',//用户名
        'avatar'=>'', //头像
        'nickname' => '企业管理员',  //昵称
        'email' => null,  //邮箱
        'sex'=>'',  //性别
        'mobile'=>'', //手机
    ];//注册企业的信息
    public $needBingMenberId = 0;//需求给谁绑定
    public $login_user_name = '';//进行登录的用户名
    public $state = [];  //第三方的state
    public $successJump = '/platform/home'; //回调成功后跳转的页面

    //主流程
    public function loginHandle()
    {
        //是否进行绑定处理的
        //判断是登录后绑定的吗
        $userToken = \PhalApi\DI()->cache->get($this->state . "_token"); //主要是获取accesstoken的
        if (empty($userToken)) {
            //进行注册成员处理
            $this->registerMember();
        }else{
            //绑定跳转链接
            $this->successJump = '/platform/account/accountInfo';
            if ($this->haveBind){
                setcookie('bing_wechat_result',  '该微信已被其它的账户绑定，请先解绑', time() + 86400 * 30, '/');
                $this->headerUrl();
            }
            //进行绑定处理
            $decoded = \lmxdawn\jwt\JWT::decode($userToken, \PhalApi\DI()->config->get('app.jwt.key'), array('HS256'));
            $decodedArray = (array)$decoded;
            $uid = $decodedArray['uid'];
            $memberInfo = \Base\Model\Member::model()->get($uid);
            if (empty($memberInfo)){
               throw new BadRequestException('该用户不存在，清检查参数');
            }
            $this->needBingMenberId = $uid;
            $this->login_user_name = $memberInfo['username'];
        }

        //进行绑定处理
        $this->bingAuthorization();

        //返回前端额外信息,写进cooke里
        $this->returnExtraInfo();

        //进行登录处理
        $this->gotoLogin();

        //跳转
        $this->headerUrl();
    }
    //注册会员处理
    protected function registerMember()
    {
        //已经注册
        if (!empty($this->haveRegister)) {
            return;
        }

        //查询账户是否重复，重复进行
        $findUserInfo = \Base\Model\Member::model()->getData(['username' => $this->registerInfo['username']]);
        if (!empty($findUserInfo)) {
            throw new BadRequestException('自动生成账号重复，请重新注册');
        }

        $userDomain = new \Base\Domain\User();
        //注册成员处理
       $memberId =  $userDomain->register(
            $this->registerInfo['username'],
            \PhalApi\Tool::createRandStr(6),
            $this->registerInfo['avatar'],
            $this->registerInfo['nickname'],
            $this->registerInfo['email'],
            $this->registerInfo['sex'],
            $this->registerInfo['mobile'],
            UserType::MEMBER_LEVEL_ADMIN,
            ['from_channel'=>$this->registerInfo['from_channel']]
        );

        $this->needBingMenberId = $memberId;
        $this->login_user_name = $this->registerInfo['username'];

        //额外处理
        $this->extraHandle();
    }
    //注册后的额外处理，用于继承
    public function extraHandle(){

    }
    //绑定第三方登录
    public function bingAuthorization()
    {
        //判断是否绑定了
        if(!empty($this->haveBind)){
            return ;
        }
        //注册成功后进行绑定
        (new AuthorizationModel())->update($this->authorizationInfo['id'],['member_id'=>$this->needBingMenberId]);
    }
    //去登录
    protected function gotoLogin()
    {
        //进行内部登录,返回token
        $this->noPasswdLogin();
    }
    //跳转页面
    protected function headerUrl(){
        $url = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['SERVER_NAME'] .$this->successJump;
        header("Location: {$url}");
        exit();
    }
    //返回额外信息给前端
    public function returnExtraInfo(){
        if (!empty($this->state['extraInfo'])){
            //返回前端额外信息
            setcookie('extra_info', $this->state['extraInfo'], $_SERVER['REQUEST_TIME'] + 600, '/');//返回前端额外信息
        }
    }
    //内部登录获取token
    protected function noPasswdLogin()
    {
        $userDomain = new \Base\Domain\User();
        //获取账号信息
        $profile = $userDomain->profile($this->login_user_name);

        //只有一个直接登录处理
        $rs = $this->makeAccessToken($profile['id'], $profile['app_key'],$profile['username']);

        // 开放平台的cookie
        setcookie('p_username', $this->login_user_name, time() + 86400 * 30, '/');
        setcookie('p_debug_username', $this->login_user_name, time() + 86400 * 30, '/');

//        $result = [
//            'name' => 'p_token',
//            'value' => $rs['access_token'],
//            'expires' => 86400000,
//            'startTime' => $this->getUnixTimestamp()
//        ];
        setcookie('p_token', $rs['access_token'], time() + 86400 * 30, '/');
        setcookie('p_debug_token', $rs['access_token'], time() + 86400 * 30, '/');
        //登录记录
        Login::addLoginLog($profile['username'], Login::LOGIN_STATUS_SUCCESS, 'weChat');
        return $rs;
    }
    //账号成员登陆生成token
    protected function makeAccessToken($uid,$appKey,$username){
        $config = \PhalApi\DI()->config;
        $key = $config->get('app.jwt.key');
        $time = time();

        $token = array(
            "iss" => ToolUtil::createISS($key),        // 该JWT的签发者
            "aud" => 'user',        // 接收该JWT的一方
            "sub" => $appKey,                    // 该JWT所面向的开发者
            "uid" => intval($uid),     //memberId
            "iat" => $time,                         // 在什么时候签发的
            "exp" => $time + $config->get('app.jwt.exp', 86400),        // 什么时候过期，这里是一个Unix时间戳

        );

        $jwt = \lmxdawn\jwt\JWT::encode($token, $key, 'HS256');

        // 记录登录成功
        Login::addLoginLog($username, Login::LOGIN_STATUS_SUCCESS);

        // 开放平台的cookie
        setcookie('p_username', $username, time() + 86400 * 30, '/');

        $rs['access_token'] = $jwt;
        $rs['expire_at'] = $token['exp'];

        return $rs;
    }

    public function getUnixTimestamp()
    {
        list($s1, $s2) = explode(' ', microtime());
        return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
    }
}

