<?php
/**
 *  ╔═══════════════════════════════════════════════════╗
 *  ║                                                   ║
 *  ║     ██╗  ██╗   █████╗    ██████╗                  ║
 *  ║     ██║  ██║  ██╔══██╗  ██╔═══██╗                 ║
 *  ║     ███████║  ███████║  ██║   ██║                 ║
 *  ║     ██╔══██║  ██╔══██║  ██║   ██║                 ║
 *  ║     ██║  ██║  ██║  ██║  ╚██████╔╝   SNS           ║
 *  ║                                                   ║    
 *  ║                                                   ║    
 *  ║     © 2023 HaoSNS™ All Rights Reserved            ║
 *  ║     官方网站: https://www.haosns.com                *
 *  ║     本代码由赣州乐易网络科技有限公司®提供             *
 *  ║                                                    *
 *  ║   未经授权禁止复制、传播或用于其他商业目的            *
 *  ║                                                   ║
 *  ╚═══════════════════════════════════════════════════╝
 */


namespace app\api\logic;

use app\api\service\{
    UserTokenService,
    WechatUserService
};
use app\common\{enum\LoginEnum,
    enum\UserTerminalEnum,
    model\User,
    logic\BaseLogic,
    model\UserAuth,
    service\FileService,
    service\WeChatService};
use think\facade\{
    Db,
    Config,
};
use Requests;



class LoginLogic extends BaseLogic
{
    /**
     * @notes 用户账号登录
     * @param $params
     * @return false|mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function login($params)
    {
        try {
            if ($params['scene'] == LoginEnum::MOBILE_PASSWORD || $params['scene'] == LoginEnum::MOBILE_CAPTCHA) {
                // 手机号密码、手机验证码登录
                $where = ['mobile' => $params['account']];
            } else {
                // 账号密码登录
                $where = ['account' => $params['account']];
            }
            $user = User::where($where)
            ->whereOr('account',$params['account'])
            ->findOrEmpty();
            if($user->isEmpty()){
                $user = User::where($where)
                ->whereOr('email',$params['account'])
                ->findOrEmpty();
            }


            if ($user->isEmpty()) {
                // 验证码登录时，如果账户不存在则 自动创建
                if( $params['scene'] == LoginEnum::MOBILE_CAPTCHA ){
                    RegisterLogic::register([
                        'mobile' => $params['account'],
                        'register_source' => $params['terminal'],
                        'no_password'  => true,
                        'invite_code'  => $params['invite_code']
                    ]);

                    $user = User::where($where)->findOrEmpty();

                } else {
                    throw new \Exception('用户不存在');
                }    
            }
            


            //更新登录信息
            $user->login_time = time();
            $user->login_ip = request()->ip();
            if( isset($params['push_clientid'])  && $params['push_clientid'] ){
                $user->push_clientid =$params['push_clientid'];  //更新推送标识
            }

            try {
                $ip = $_SERVER['REMOTE_ADDR'];
                $ip_address = '';
                // 初始化，指定QQWry.dat文件路径
                $qqwry = new \app\common\service\QQWry('qqwry.dat');
                // 获取客户端IP
                $ip = $_SERVER['REMOTE_ADDR'];
                // 查询IP地理位置
                $location = $qqwry->getLocation($ip);
                $ip_address = $location['country'];
                $user->ip = $ip;
                $user->ip_address =  $ip_address;
                
            } catch (\Exception $e) {
                // echo "发生错误: " . $e->getMessage();
            }
            
            $user->save();
            
            //设置token
            $userInfo = \app\api\service\UserTokenService::setToken($user->id, $params['terminal']);

            //返回登录信息
            $avatar = $user->avatar ? $user->avatar : Config::get('project.default_image.user_avatar');
            return [
                'user_id' => $userInfo['user_id'],
                'nickname' => $userInfo['nickname'],
                'sn' => $userInfo['sn'],
                'mobile' => $userInfo['mobile'],
                'avatar' => $avatar,
                'token' => $userInfo['token'],
            ];
        } catch (\Exception $e) {
            self::setError($e->getMessage());
            return false;
        }
    }


    /**
     * @notes 退出登录
     * @param $userInfo
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function logout($userInfo)
    {

        //token不存在，不注销
        if (!isset($userInfo['token'])) {
            return false;
        }

        //设置token过期
        return UserTokenService::expireToken($userInfo['token']);

    }


    /**
     * @notes 更新登录信息
     * @param $userId
     * @throws \Exception
     */
    public function updateLoginInfo($userId)
    {
        $user = User::findOrEmpty($userId);
        if ($user->isEmpty()) {
            throw new \Exception('用户不存在');
        }
        $time = time();
        $user->login_time = $time;
        $user->login_ip = request()->ip();
        $user->update_time = $time;
        $user->save();
    }

    /**
     * @notes 更新用户头像昵称
     * @param $post
     * @param $user_id
     * @return bool
     * @throws \think\db\exception\DbException
     */
    public static function updateUser($post,$user_id)
    {
        Db::name('user')->where(['id'=>$user_id])->update(['nickname'=>$post['nickname'],'avatar'=>FileService::setFileUrl($post['avatar']),'is_new_user'=>0]);
        return true;
    }


    /**
     * @notes 小程序端绑定微信
     * @param array $params
     * @return bool
     * @author lgp
     * @date 2022/7/17 10:57
     */
    public function mnpAuthLogin(array $params)
    {

        try {
            //通过code获取微信openid
            $response = WeChatService::getMnpResByCode($params);
            $response['user_id'] = $params['user_id'];
            $response['terminal'] = UserTerminalEnum::WECHAT_MMP;

            return $this->createAuth($response);

        } catch (\Exception  $e) {

            self::$error = $e->getMessage();
            return false;
        }
    }

    /**
     * @notes 生成一条授权记录
     * @param $response
     * @return bool
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @author lgp
     * @date 2022/5/17 16:18
     */
    public function createAuth($response)
    {

        //先检查openid是否有记录
        $isAuth = UserAuth::where('openid', '=', $response['openid'])->findOrEmpty();
        if(!$isAuth->isEmpty()){
            throw new \Exception('该微信已经绑定，请切换微信授权登录');
        }
        if(isset($response['unionid']) && !empty($response['unionid'])) {
            //在用unionid找记录，防止生成两个账号，同个unionid的问题
            $userAuth = UserAuth::where(['unionid'=>$response['unionid']])
                ->findOrEmpty();
            if (!$userAuth->isEmpty() && $userAuth->user_id != $response['user_id']) {
                throw new \Exception('该微信已经绑定，请切换微信授权登录');
            }
        }

        //如果没有授权，直接生成一条微信授权记录
        UserAuth::create([
            'user_id'   => $response['user_id'],
            'openid'    => $response['openid'],
            'unionid'   => $response['unionid'] ?? '',
            'terminal'  => $response['terminal'],
        ]);
        return true;
    }
}