<?php
namespace Passport\Src;

use Dever;
use Passport\Lib\Base;

# 小程序

class Applet extends Base
{
    private $cache = 'applet_sessionKey_';

    public function init()
    {
        $uid = $this->check();
        $user = Dever::load('passport/user-one', $uid);

        return $user;
    }

    /**
     * 用户绑定 生成用户信息
     *
     * @return mixed
     */
    public function bind()
    {
        $create = Dever::input('create', 2);
        $data = $this->getLoginInfo();

        if ($create == 1) {
            # 未授权，生成临时用户，针对有的项目，不需要授权，但是还要生成用户
            $data = $this->create($data, false);
        }

        return $data;
    }

    /**
     * 一次性登录：通过code或者openid、sessionkey来注册用户，此时已经授权，可以直接拿到unioinid
     *
     * @return mixed
     */
    public function login()
    {
        $data = $this->getLoginInfo();

        $data += $this->getWechatData($data['session_key']);

        $data['username'] = Dever::input('nickname');
        $data['avatar'] = Dever::input('avatarurl');
        $data['sex'] = Dever::input('gender');
        $data['city'] = Dever::input('city');
        //$data['mobile'] = Dever::input('mobile');
        $data['province'] = Dever::input('province');
        $data['country'] = Dever::input('country');

        $result = $this->create($data);

        return $result;
    }

    /**
     * 更新用户信息
     *
     * @return mixed
     */
    public function update()
    {
        $uid = $this->check();
        $vid = Dever::input('vid');
        $info = Dever::db('passport/user')->one($uid);
        if ($info) {
            if ($info['temp'] == 1) {
                # 针对未授权，生成临时用户的用户进行设置积分
                Dever::score($uid, 'bind_wechat', '用户微信授权');
            }
            $data['temp'] = 2;
            $data['username'] = Dever::input('nickname');
            $data['avatar'] = Dever::input('avatarurl');
            $data['sex'] = Dever::input('gender');
            $data['city'] = Dever::input('city');
            $data['province'] = Dever::input('province');
            $data['country'] = Dever::input('country');

            if ($data['sex'] == 1) {
                $data['sex'] = 1;
            } elseif ($data['sex'] == 2) {
                $data['sex'] = 2;
            } else {
                $data['sex'] = 3;
            }
            $this->updateUser($uid, $data);
        } else {
            Dever::alert('无效的用户id,请重新登录');
        }

        $result['vid'] = $vid;
        $result['uid'] = $uid;
        $result['signature'] = Dever::login($uid);

        return $result;
    }

    /**
     * 更新用户信息 手机号
     *
     * @return mixed
     */
    public function mobile()
    {
        $uid = $this->check();
        $vid = Dever::input('vid');
        $result = array();
        $mobile = $phoneNumber = '';

        $iv = Dever::input('iv');
        $encryptedData = Dever::input('encryptedData');
        
        if ($iv && $encryptedData) {
            $key = $this->cache . $vid;
            $session_key = Dever::cache($key);
            if (!$session_key) {
                $vinfo = Dever::db('passport/wechat')->one($vid);
                $session_key = $vinfo['session_key'];
            }
            
            $data = $this->getWechatData($session_key);
            if ($data && $data['mobile']) {
                $mobile = $data['mobile'];
                $phoneNumber = $data['phone'];
            }
        }

        if ($mobile && $phoneNumber && $uid) {
            $uid = $this->combine($uid, $mobile, 'mobile');

            $info = Dever::load('passport/user-one', $uid);
            $result['mobile'] = $mobile;
            if ($info) {
                if (!$info['mobile']) {
                    Dever::score($uid, 'bind_mobile', '绑定手机号');
                }
                $update['mobile'] = $mobile;
                $update['bind'] = 1;
                $update['where_id'] = $uid;
                Dever::db('passport/user')->update($update);

                $state = Dever::config('base', 'project')->regSendSms;
                if ($state) {
                    Dever::setInput('skin', $state);
                    $this->send($mobile, $uid);
                }
            } else {
                Dever::alert('无效的用户id,请重新登录');
            }
        }

        $result['vid'] = $vid;
        $result['uid'] = $uid;
        $result['signature'] = Dever::login($uid);

        return $result;
    }

    /**
     * 生成用户，返回uid
     *
     * @return int
     */
    public function create($data, $state = true)
    {
        $uid = false;
        $data['system'] = Dever::input('system', 1);
        $info = Dever::db('passport/wechat')->one(array('openid' => $data['openid']));

        $wechat = array();
        if (!$info) {
            if (isset($data['unionid']) && $data['unionid']) {
                $info = Dever::db('passport/wechat')->one(array('unionid' => $data['unionid']));
                if (!$info) {
                    $uid = false;
                } else {
                    # 判断用户是否存在，是否需要合并
                    //$uid = $this->combine($info['uid'], $data['unionid']);
                    $uid = $info['uid'];
                }
                $wechat['unionid'] = $data['unionid'];
            }
            if (!$uid) {
                $uid = $this->reg('applet', $data);
                if ($state) {
                    Dever::score($info['id'], 'bind_wechat', '用户微信授权');
                }
            }
             
            $wechat['openid'] = $data['openid'];
            $wechat['session_key'] = $data['session_key'];
            $wechat['uid'] = $uid;
            $wechat['type'] = 1;
            $wechat['system_id'] = $data['system'];
            $id = Dever::db('passport/wechat')->insert($wechat);

            $key = $this->cache . $id;
            $cache = Dever::cache($key, $data['session_key']);
        } else {
            $uid = $info['uid'];
            $id = $info['id'];
            /*
            if (isset($data['unionid']) && $data['unionid']) {
                # 判断用户是否存在，是否需要合并
                $wechat['uid'] = $this->combine($uid, $data['unionid']);

                if ($wechat['uid'] != $uid) {
                    $uid = $wechat['uid'];
                }
            }
            */

            $key = $this->cache . $id;
            $cache = Dever::cache($key, $data['session_key']);

            if (!$cache) {
                $wechat['session_key'] = $data['session_key'];
            }

            if ($wechat) {
                $wechat['where_id'] = $id;
                Dever::db('passport/wechat')->update($wechat);
            }
        }

        $user = Dever::db('passport/user')->one($uid);

        $result['vid'] = $id;
        $result['uid'] = $uid;
        $result['signature'] = Dever::login($uid);
      
        if (isset($user['mobile']) && $user['mobile']) {
            $result['mobile'] = $user['mobile'];
        }

        return $result;
    }

    private function unionid($session_key)
    {
        $data = $this->decryptData($session_key);
        if ($data && isset($data->unionId)) {
            return $data->unionId;
        }
        
        return false;
    }

    private function getWechatData($session_key)
    {
        $result = array();
        $data = $this->decryptData($session_key);

        $result['openid'] = '';
        $result['unionid'] = '';
        $result['mobile'] = '';
        $result['phone'] = '';
        if ($data && isset($data->openId)) {
            $result['openid'] = $data->openId;
            if (isset($data->unionId)) {
                $result['unionid'] = $data->unionId;
            }
        }

        if ($data && isset($data->phoneNumber)) {
            if (isset($data->phoneNumber)) {
                $result['phone'] = $data->phoneNumber;
            }
        }

        if ($data && isset($data->purePhoneNumber)) {  
            if (isset($data->purePhoneNumber)) {
                $result['mobile'] = $data->purePhoneNumber;
            }
        }
        
        return $result;
    }

    private function decryptData($session_key)
    {
        $iv = Dever::input('iv');
        $encryptedData = Dever::input('encryptedData');

        if (!$iv || !$encryptedData) {
            return false;
        }
        if (strlen($session_key) != 24) {
            return false;
        }
        if (strlen($iv) != 24) {
            return false;
        }

        $aesKey = base64_decode($session_key);

        $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;
        }
        /*
        $applet = Dever::config('base', 'project')->applet;
        $appid = $applet['appid'];
        if($dataObj->watermark->appid != $appid) {
            return false;
        }*/
        return $dataObj;
    }

    private function getApplet()
    {
        $applet = Dever::config('base', 'project')->applet;
        $project = false;
        $system = Dever::input('system', 1);
        if (Dever::project('token')) {
            $project = Dever::db('token/project')->one($system);
        }

        if (!$project) {
            if (isset($applet['project']) && $applet['project']) {
                $project = Dever::db($applet['project'])->one($system);
            }
        }

        if ($project) {
            $applet['appid'] = $project['appid'];
            $applet['secret'] = $project['secret'];
        }

        if (!$applet || !$applet['appid'] || !$applet['secret']) {
            Dever::alert('错误的appid');
        }

        return $applet;
    }

    private function getLoginInfo()
    {
        $session_key = Dever::input('session_key');
        if ($session_key) {
            return array('session_key' => $session_key, 'openid' => $openid);
        }
        $applet = $this->getApplet();
        $appid = $applet['appid'];
        $secret = $applet['secret'];
        $url = $applet['url'];
        $code = Dever::input('code');
        if (!$applet || !$applet['appid'] || !$applet['secret']) {
            Dever::alert('错误的appid');
        }

        $url .= '?appid=' . $appid;
        $url .= '&secret=' . $secret;
        $url .= '&js_code=' . $code;
        $url .= '&grant_type=authorization_code';

        $data = Dever::curl($url);
        Dever::log($data, 'passport_applet');
        if (strstr($data, 'errcode')) {
            Dever::alert($data);
        }

        //YzJkOThpRFhwZ1lQTF9mZl9hLVZjZnFXemJVenlYcDQ3d3JWekk0b1I4NjBBQ0Naejg4a0VQa0U=
        //$data = '{"session_key":"aNAXk7nG\/DRYI\/G0KzJRsw==","openid":"oIZ895RZs2ZkywasoZIv6WavPZlQ"}';
        $data = Dever::json_decode($data);

        return $data;
    }
}