<?php

namespace app\index\controller;

use app\common\controller\Frontend;
use app\common\library\Sms;
use fast\Random;
use think\exception\HttpResponseException;
use think\Request;
use think\Response;

class Wechat extends Frontend
{

    protected $noNeedLogin = '*';

    private $wechat = null;

    private $_error = '';

    private $has_mobile = false;

    private $is_notice = false;

    public function __construct(Request $request = null)
    {
        parent::__construct($request);
        $this->wechat = new \app\common\controller\Wechat();
    }

    /**
     * 在公网接口处重写此方法：验证服务器有效性
     * @return string
     */
    public function serverValidation()
    {
        $TOKEN = 'I8cezsHeF1buiCBPwD';
        $signature = $_GET["signature"] ?? "";
        $timestamp = $_GET["timestamp"] ?? "";
        $nonce = $_GET["nonce"] ?? "";
        $tmpArr = array($TOKEN, $timestamp, $nonce);
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);

        if ($tmpStr == $signature) {
            return $_GET["echostr"] ?? '';
        }
        return 'error';
    }

    /**
     * 在公网接口处重写此方法：引导用户进入授权页，并跳转到目标页
     * @param string $url 授权后需要跳转的页面地址，必须进行base64编码
     * @author fuyelk <fuyelk@fuyelk.com>
     */
    public function bootToUrl($url = '')
    {
        $redirect_uri = request()->domain() . '/index/wechat/wechatRedirect?redirect=' . $url;
        $appid = $this->wechat->appid;
        $redirect_uri = urlencode($redirect_uri);
//        $scope = 'snsapi_base'; // 静默授权，只能获取openid
        $scope = 'snsapi_userinfo'; // 授权弹窗，可获取用户昵称头像
        $wechat_authorize = "http://2.ipfsfil168.com/get-weixin-code.html?appid={$appid}&redirect_uri={$redirect_uri}&response_type=code&scope={$scope}&state=123#wechat_redirect";
        $this->redirect($wechat_authorize);
    }

    /**
     * 在公网接口处重写此方法：用户授权后微信将用户重定向至此接口并携带code，
     * 使用code可获取access_token及用户openid，完成业务逻辑处理后拼接上openid将用户重定向指指定页面
     */
    public function wechatRedirect()
    {
        $code = input('code');
        $redirect = input('redirect');
        // 获取用户信息
        if ($code) {
            $wechat_url = 'https://api.weixin.qq.com/sns/oauth2/access_token' .
                '?appid=' . $this->wechat->appid .
                '&secret=' . $this->wechat->appsecret .
                '&code=' . input('code') .
                '&grant_type=authorization_code';

            try {
                $res = $this->wechat->http_request($wechat_url);
            } catch (\Exception $e) {
                $redirect = $redirect . (strpos($redirect, '?') ? '&' : '?') . 'status=0&token=&errmsg=' . $e->getMessage();
                $this->redirect($redirect ? urldecode($redirect) : '/h5/#/');
                exit();
            }

            $res = json_decode($res, true);
            if (empty($res['openid'])) {
                $redirect = $redirect . (strpos($redirect, '?') ? '&' : '?') . 'status=0&token=&errmsg=登录失败';
                $this->redirect($redirect ? urldecode($redirect) : '/h5/#/');
                exit();
            }

            $redirect = base64_decode($redirect);
            $redirect = htmlspecialchars_decode($redirect);
            $query = parse_url(strstr($redirect, '?'), PHP_URL_QUERY);
            parse_str($query, $params);

            // 获取用户信息
            if ('snsapi_userinfo' == $res['scope']) {
                $userinfo = file_get_contents("https://api.weixin.qq.com/sns/userinfo?access_token={$res['access_token']}&openid={$res['openid']}&lang=zh_CN");
                $userinfo = json_decode($userinfo, true);
                if (!empty($userinfo['errcode']) && !empty($userinfo['errmsg'])) {
                    $redirect = $redirect . (strpos($redirect, '?') ? '&' : '?') . 'status=0&token=&errmsg=' . $userinfo['errmsg'];
                    $this->redirect($redirect ? urldecode($redirect) : '/h5/#/');
                    exit();
                }
                //    [openid] => ou6NC6kBSloLS94gUhCyKeguIaYI
                //    [nickname] => fuyelk
                //    [sex] => 1 // 1=男，2=女，0=未知
                //    [language] => zh_CN
                //    [city] => 郑州
                //    [province] => 河南
                //    [country] => 中国
                //    [headimgurl] => https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKY3E1A2MFK46y1fNv7OElhtQFefO4mrBy8kcQoFCHP9diaULlpeINYB1FJ7KNh4fx5v3rzAJ2LzFg/132

                $invite_code = $params['sharecode'] ?? '';

                $is_channel = $params['channel'] ?? '';

                $token = $this->login($userinfo['openid'], $userinfo['nickname'], $userinfo['headimgurl'], $invite_code, $is_channel);

                if (false === $token) {
                    $errmsg = $this->_error ?: '登录失败';
                    $redirect = $redirect . (strpos($redirect, '?') ? '&' : '?') . 'status=0&token=&errmsg=' . $errmsg;
                    $this->redirect($redirect ? urldecode($redirect) : '/h5/#/');
                    exit();
                }

            } else {
                $errmsg = $this->_error ?: '仅支持snsapi_userinfo';
                $redirect = $redirect . (strpos($redirect, '?') ? '&' : '?') . 'status=0&token=&errmsg=' . $errmsg;
                $this->redirect($redirect ? urldecode($redirect) : '/h5/#/');
                exit();
            }



            // 绑定过手机，直接去首页
            if ($this->has_mobile) {
                $this->redirect('/h5/#/?status=1&errmsg=&token=' . $token  . "&is_notice=". $this->is_notice);
            }

            $redirect = $redirect . (strpos($redirect, '?') ? '&' : '?') . 'status=1&errmsg=&token=' . $token  . "&is_notice=". $this->is_notice;

            $this->redirect($redirect ? urldecode($redirect) : '/h5/#/');
        }
        $errmsg = $this->_error ?: '授权失败';
        $redirect = $redirect . (strpos($redirect, '?') ? '&' : '?') . 'status=0&token=&errmsg=' . $errmsg;
        $this->redirect($redirect ? urldecode($redirect) : '/h5/#/');
    }

    /**
     * 登录
     * @param string $openid 登录
     * @param string $invite_code
     * @return bool|mixed
     * @author fuyelk <fuyelk@fuyelk.com>
     */
    private function login($openid, $nickname = '', $avatar = '', $invite_code = '', $is_channel ='')
    {
        $user = \app\common\model\User::getByWechatOpenid($openid);
        if ($user) {
            if ($user->status != 'normal') {
                $this->_error = '账号被锁定';
                return false;
            }
            //如果已经有账号则直接登录
            $ret = $this->auth->direct($user->id);
        } else {
            $extend = [
                'invite_code' => $invite_code,
                'wechat_openid' => $openid,
                'nickname' => $nickname,
                'avatar' => $avatar,
            ];
            $ret = $this->auth->register('', Random::alnum(), '', '', $extend);
            if($ret && $is_channel == '49ba59abbe56e057'){  //赠送10金币
                \app\common\model\User::where(['id'=>$this->auth->id])->setInc("coin", 10);
                $this->is_notice = 1;
            }
        }
        if ($ret) {
            $data = $this->auth->getUserinfo();
            $this->has_mobile = !empty($data['mobile']) ? true : false;
            return $data['token'];
        }
        $this->_error = $this->auth->getError();
        return false;
    }

    /**
     * 微信登录并重定向
     * @author fuyelk <fuyelk@fuyelk.com>
     */
    public function wechatLoginRedirect()
    {
        $redirect = input('redirect');
        if (empty('')) {
            throw new HttpResponseException(Response::create(['code' => 403, 'msg' => '重定向地址为空', 'data' => null], 'json', 200));
        }
        $this->redirect('/index/wechat/bootToUrl?url=' . base64_encode($redirect));
    }
}