<?php
// +----------------------------------------------------------------------
// | A3Mall
// +----------------------------------------------------------------------
// | Copyright (c) 2020 http://www.a3-mall.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: xzncit <158373108@qq.com>
// +----------------------------------------------------------------------

namespace app\common\service\wechat;

use think\facade\Request;
use app\common\service\Config;
use app\common\library\jwt\Token;
use app\common\library\utils\Hash;
use app\common\library\utils\Tool;
use app\common\library\wechat\Wechat;
use app\common\model\Users as UsersModel;
use app\common\model\UsersAuth as UsersAuthModel;
use app\common\service\Config as ConfigService;
use app\common\enum\Terminal as TerminalEnum;
use app\common\service\promotion\Award as AwardService;
use app\common\service\promotion\Invite as InviteService;
use app\common\service\Users as UsersService;

/**
 * @package app\common\service\wechat
 * @class Auth
 * @author xzncit 2024-01-29
 */
class Auth {

    /**
     * 登录
     * @param $type
     * @param array $params
     * @return mixed
     * @throws \Exception
     */
    public static function login($params=[]){
        if(empty($params["scene"])){
            throw new \Exception("获取scene类型失败",0);
        }

        $method = $params["scene"];
        if(!method_exists(__CLASS__,$method)){
            throw new \Exception("您选择的登录方法不存在",0);
        }

        $array = self::$method($params);
        return self::getUser($array);
    }

    /**
     * 小程序登录
     * @param array $params
     */
    public static function miniprogram($params=[]){
        if(empty($params["code"])){
            throw new \Exception("登录失败，获取code失败",0);
        }

        $session = Wechat::create($params["scene"])->oauth->code2Session($params["code"]);
        if(empty($session["openid"])){
            throw new \Exception("获取openid授权信息失败");
        }

        return [
            "openid"    => $session["openid"],
            "unionid"   => $session["unionid"]??"",
            "uid"       => $params["uid"]??"0"
        ];
    }

    /**
     * 获取用户信息
     * @param $params
     */
    public static function getUser($params){
        $terminal  = TerminalEnum::getTerminalNo(Request::header("Client-Type","h5"));
        $condition = [];
        if(!empty($params["unionid"])){
            $condition[] = ["unionid","=",$params["unionid"]];
        }else{
            $condition[] = ["openid","=",$params["openid"]];
            $condition[] = ["terminal","=",$terminal];
        }

        if(UsersService::auth("id",0)){
            $condition[] = ["user_id","=",UsersService::auth("id",0)];
        }

        $auth = UsersAuthModel::where($condition)->find();
        if(!empty($auth) || UsersService::auth("id",0)){
            $user_id = UsersService::auth("id",$auth["user_id"]??0);
            $user    = UsersModel::where("id",$user_id)->find();

            if(is_null(UsersAuthModel::where(["openid"=>$params["openid"],"user_id"=>$user_id,"terminal"=>$terminal])->find())){
                $auth["id"] = UsersAuthModel::create([
                    "user_id"       => $user_id,
                    "openid"        => $params["openid"],
                    "unionid"       => $params["unionid"]??"",
                    "terminal"      => $terminal,
                    "create_time"   => time(),
                    "update_time"   => time()
                ])->id;
            }else{
                UsersAuthModel::where(["openid"=>$params["openid"],"user_id"=>$user_id,"terminal"=>$terminal])->update([
                    "unionid"       => $params["unionid"]??"",
                    "update_time"   => time()
                ]);
            }
        }else{
            $salt = Tool::getRands(5);

            $uid = 0;
            if(!empty($params["uid"])){
                $uid = UsersModel::where(["id"=>$params["uid"],"status"=>1])->value("id",0);
            }

            $userId = UsersModel::create([
                "username"      => self::getUserName('wx_'),
                "nickname"      => Tool::getNickName(),
                "password"      => Hash::md5(uniqid(),$salt),
                "salt"          => $salt,
                "join_ip"       => Request::ip(),
                "login_ip"      => Request::ip(),
                "status"        => 1,
                "terminal"      => $terminal,
                "inviter_id"    => $uid,
                "login_time"    => time(),
                "prev_time"     => time(),
                "create_time"   => time(),
                "update_time"   => time(),
                "join_time"     => time()
            ])->id;

            UsersAuthModel::create([
                "user_id"       => $userId,
                "openid"        => $params["openid"],
                "unionid"       => $params["unionid"],
                "terminal"      => $terminal,
                "create_time"   => time(),
                "update_time"   => time()
            ]);

            AwardService::reward($userId);
            InviteService::reward($userId,$uid);
            $user = UsersModel::where("id",$userId)->find();
        }

        if(empty($user)){
            throw new \Exception("您的帐号登录异常，如有疑问请联系客服",0);
        }

        if($user["status"] == 2){
            throw new \Exception("您的帐号审核中",0);
        }else if($user["status"] == 3){
            throw new \Exception("您的帐号已被管理员锁定，如有疑问请联系管理员",0);
        }else if($user["status"] == 4){
            throw new \Exception("您选择登录的帐号不存在",0);
        }

        $isBind = false;
        if(ConfigService::getArray("users.users_bind_mobile",0) && empty($user["mobile"])){
            $isBind = true;
        }

        return [
            "token"     => Token::set("id",$user["id"]),
            "is_bind"   => $isBind
        ];
    }

    /**
     * 生成唯一用户名
     * @param string $prefix
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getUserName($prefix=""){
        $username = $prefix . Tool::getRands(10);
        if(UsersModel::where("username",$username)->find()){
            return self::getUserName($prefix);
        }

        return $username;
    }

    /**
     * 获取公众号基本信息
     * @return array
     */
    public static function config(){
        $config = Config::getArray("wechat",[]);
        return [
            "domain"    => Request::domain() . "/mobile",
            "appid"     => trim($config["appid"]??""),
            "state"     => Tool::getRands(10)
        ];
    }

}