<?php
/**
 * 获取accesstoken
 */
namespace app\api\controller\v1;

use think\Controller;
use think\Request;
use app\api\controller\Api;
use think\Response;
use app\api\controller\UnauthorizedException;
use app\api\controller\Send;
use app\api\controller\Oauth as Oauth2;
use app\api\model\Oauth as Oauth;
use think\Db;
use think\Cache;
class Token extends Controller
{	
	use Send;
	//手机客户端请求验证规则
	public static $rule_mobile = [
        'app_key'     =>  'require',
        'mobilephone' =>  'require',
        'nonce'       =>  'require',
        'timestamp'   =>  'require',
        'captcha'     =>  'number'   //手机验证码
    ];
    //微信端请求验证规则
    public static $rule_wechat = [
        'app_key'     =>  'require',
        'open_id'     =>  'require',
        'nonce'       =>  'require',
        'timestamp'   =>  'require',
        'union_id'    =>  'require',
        'access_token'=>  'require' //微信端的access_token用于验证用户的信息是否真实
    ];
    
    /**
     * 构造函数
     * 初始化检测请求时间，签名等
     */
    public function __construct()
    {
        $this->request = Request::instance();
        //为了调试注释掉时间验证与前面验证，请开发者自行测试
        //$this->checkTime();
        //$this->checkSign();
    }

	public function wechat()
	{    
		$this->checkAppkey(self::$rule_wechat);  //检测appkey
	}

	/**
	 * 为客户端提供access_token
	 * 手机号登录，手机号登录必须是注册过的手机号，不支持手机号注册
	 */
	public function read($uuid){
	    //$uuid

    }
    public function save($json){
	    //项目注册
        //验参
        if(empty($_POST['json'])){
            $this->returnmsg(400);
        }
        $json=$_POST['json'];
//        var_dump($json);die;
        $json_obj=json_decode($json);
//        var_dump($json_obj);die;
        $groupModel = model('Token');
        $list=$groupModel->vali($json_obj);
        if($list){
            //写入数据
            $data['uuid']=$json_obj->uuid;
            $data['create_time']=date("Y-m-d H:i:s",time());
            $data['update_time']=date("Y-m-d H:i:s",time());
            $data['expiry_time']=date("Y-m-d H:i:s",time()+604800);
            $data['group_id']=$list;
            $data['remake']=$json_obj->remake;
            $data['accress_token']=md5(md5( $data['uuid'].time().rand(10,19999)));
            $data['refresh_token']=md5(md5( $data['uuid'].time().rand(10,19999)));
            $token_model= model('Token');
            $status=$token_model->save_data($data);
            if($status){
                $this->render(200,$data);
            }else{
                $this->returnmsg(401);
            }
        }else{
            $this->returnmsg('402',[],[],'service_message','Key error.','ID和秘钥不匹配');
        }

    }

    public function update(){
        //刷新ACCESStoken
//        if(empty($type = $_SERVER['REQUEST_METHOD'])){
//            $this->returnmsg(400);
//        }
//        var_dump($_GET['res']);

//        $type = $_SERVER['REQUEST_METHOD'];
        parse_str(file_get_contents('php://input'), $data);
        if(empty($data['refresh_token'])||empty($data['app_id'])||empty($data['app_secret'])){
            $this->returnmsg(400);
        }
        $groupModel = model('Token');
        $json=json_decode(json_encode($data));
//        var_dump($json);die;
        $list=$groupModel->vali($json);
        if($list){
                    //刷新accesstoken
            $token_model= model('Token');
            $status=$token_model->update_token($data['refresh_token']);
            if($status){
                $this->render(200,$status);
            }else{
                $this->returnmsg('402',[],[],'refresh_token','refresh_token error.','refresh_token错误');
            }

        }else{
            $this->returnmsg('402',[],[],'service_message','Key error.','ID和秘钥不匹配');
        }
//      $data = array_merge($_GET, $_POST, $data);
//        var_dump($data['res']);
//        $count=count($data);
//        var_dump($count);
    }


	public function mobile()
	{	
		//检测appkey
		$this->checkAppkey(self::$rule_mobile);
		//获取短信验证码
		if(!empty($this->request->param('captcha'))){
			//$sms = Factory::getInstance(\app\api\controller\Sms::class);
			//$code = $sms->getMobileCode($this->request->param('mobilephone')); 
			//return $this->returnmsg(200,'success',['code'=>$code]);
		}else{
			//$mobilebind = Db::name('tb_user')->field('mobilephone,id as user_id')->where('mobilephone',$this->request->param('mobilephone'))->find();  //取数据库对应手机号绑定用户
            $mobilebind = ['uuid'=>110,'mobilephone'=>138888888888];
			if(!empty($mobilebind)){
				try {
					$mobilebind['app_key'] = $this->request->param('app_key');
					$accessTokenInfo = $this->setAccessToken($mobilebind);
					return $this->returnmsg(200,'success',$accessTokenInfo);
				} catch (\Exception $e) {
					$this->sendError(500, 'server error!!', 500);
				}
			}else{
				return $this->returnmsg(401,'mobilephone is not bind');
			}
		}
	}

	/**
	 * 检测时间+_300秒内请求会异常
	 */
	public function checkTime()
	{
		$time = $this->request->param('timestamp');
		if($time > time()+300  || $time < time()-300){
			return $this->returnmsg(401,'The requested time is incorrect');
		}
	}

	/**
	 * 检查微信用户是否真实
	 */
	public function checkWechat()
	{
		#todo
	}

	/**
	 * 检测appkey的有效性
	 * @param 验证规则数组
	 */
	public function checkAppkey($rule)
	{
		$result = $this->validate($this->request->param(),$rule);
		if(true !== $result){
			return $this->returnmsg(405,$result);
		}
        //====调用模型验证app_key是否正确，这里注释，请开发者自行建表======
		// $result = Oauth::get(function($query){
		// 	$query->where('app_key', $this->request->param('app_key'));
		// 	$query->where('expires_in','>' ,time());
		// });
		if(empty($result)){
			return $this->returnmsg(401,'App_key does not exist or has expired. Please contact management');
		}
	}

	/**
	 * 检查签名
	 */
	public function checkSign()
	{	
		$baseAuth = Factory::getInstance(\app\api\controller\Oauth::class);
		$app_secret = Oauth::get(['app_key' => $this->request->param('app_key')]);
    	$sign = $baseAuth->makesign($this->request->param(),$app_secret['app_secret']);     //生成签名
    	if($sign !== $this->request->param['signature']){
    		return self::returnmsg(401,'Signature error',[],[]);
    	}
	}

	/**
     * 设置AccessToken
     * @param $clientInfo
     * @return int
     */
    protected function setAccessToken($clientInfo)
    {
        //生成令牌
        $accessToken = self::buildAccessToken();
        $accessTokenInfo = [
            'access_token' => $accessToken,//访问令牌
            'expires_time' => time() + Oauth2::$expires,      //过期时间时间戳
            'client' => $clientInfo,//用户信息
        ];
        self::saveAccessToken($accessToken, $accessTokenInfo);
        return $accessTokenInfo;
    }

    /**
     * 生成AccessToken
     * @return string
     */
    protected static function buildAccessToken($lenght = 32)
    {
        //生成AccessToken
        $str_pol = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789abcdefghijklmnopqrstuvwxyz";
		return substr(str_shuffle($str_pol), 0, $lenght);

    }

    /**
     * 存储
     * @param $accessToken
     * @param $accessTokenInfo
     */
    protected static function saveAccessToken($accessToken, $accessTokenInfo)
    {
        //存储accessToken
        Cache::set(Oauth2::$accessTokenPrefix . $accessToken, $accessTokenInfo, Oauth2::$expires);

        //存储用户与信息索引 用于比较,这里涉及到user_id，如果有需要请关掉注释
        //Cache::set(self::$accessTokenAndClientPrefix . $accessTokenInfo['client']['user_id'], $accessToken, self::$expires);
    }
}