<?php

namespace App\Http\Controllers\V1;

use App\Models\Job;
use App\Models\User;
use App\Services\Api\CommonService;
use App\Services\Api\ErrorMsgServive;
use App\Services\Api\UserService;
use App\Services\JPushService;
use App\Services\SmsServer;
use Cache;
use EasyWeChat\Factory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Laravel\Socialite\Facades\Socialite;
use PHPUnit\Util\Exception;
use Illuminate\Support\Facades\Validator;

class AuthController extends Controller
{
    public function __construct()
    {
        $this->wxConfig = ['app_id' => env("WECHAT_MINI_PROGRAM_APPID"), 'secret' => env("WECHAT_MINI_PROGRAM_SECRET"), 'response_type' => 'array'];
    }
    //注册
    public function register(Request $request)
    {
        $account   = $request->input('account', '');
        $password = $request->input('password', '');
        $passwords = $request->input('passwords', '');
        $validator = Validator::make($request->all(), [
            'account' => 'required',
            'name' => 'required|alpha_num',
            'email' => 'required',
            'password' => 'required|min:6',
            'passwords' => 'required|min:6',
        ]);
        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }
        if($password != $passwords){
            return $this->error('密码不一致！');
        }
        // 查询用户是否存在
        $user = User::query()
            ->where('account','=',$account)
            ->first();
        if($user){
            return $this->error('账号已存在！');
        }
        if (CommonService::is_email($request->email)){ // 邮箱格式
            if(!EmailController::isEmailCodeRight($request->email,$request->code)){
                return $this->error("验证码验证失败！");
            }
        }else{
            return $this->error('账号格式不正确！');
        }
        $user = \App::make('getUserInstance'); //在 app/Providers/AppServiceProvider.php 里面可以创一个单例模式
        $user->name = $request->name; // 姓名
        $user->account = $request->account; // 账号
        $user->email = $request->email; // 邮箱
        $user->password = $password; //这个不是直接存密码，User模型中使用了修改器
        $user->register_ip = request()->ip();
        $user->save();
        return $this->success('创建成功！');
    }

    //账号密码登录
    public function login(Request $request)
    {
        $account = $request->input('account');
        $password = $request->input('password');
        $jpush_reg_id = $request->input('jpush_reg_id');
        if (!$user = User::query()->where('account','=',$account)->first()) {
            return $this->error('账号不存在');
        }
        // 账号是否禁用
        if($user->status == 0){
            return $this->error('账号已被禁用！');
        }
        $credentials1 = ['account' => $account, 'password' => $password];
        if (!auth('api')->attempt($credentials1)) {
            return $this->error('密码错误！');
        }
        $data = $this->doLogin($user, $jpush_reg_id);
        return $this->success($data);
    }

    //短信验证码登录
    public function loginBySmsCode(Request $request)
    {
        try {
            if (!$user = User::query()->where(['mobile' => $request->mobile])->first()) {
              return $this->error('账号不存在');
            }
            //手机验证码验证
            SmsServer::checkSmsCodeByVerifyKey($request->mobile, $request->smsCode);
            //如果登录类型和 openid 不为空
            $type = $request->type;
            if (isset($type) && !empty($type)) {
                if ($type == 'weixin') {
                    if ($user->wx_openid != '') {
                      return $this->error('已经绑定微信');
                    }
                    $user->wx_openid = $request->openid;
                    $user->save();
                }
            }
            $data = $this->doLogin($request->mobile, $request->post('jpush_reg_id', ''));
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
        return $this->success($data);
    }

    //APP第三方授权登录(微信)
    public function authLogin(Request $request)
    {
        try {
            $socialite = Socialite::driver('weixin')->stateless()->user();
            $user = User::query()->where('open_id', $socialite->getId())->first();
            if (!$user) {
                $data['open_id'] = $socialite->getId();
                $data['user'] = [];
            } else {
                $account = $user->mobile ?: $user->email;
                $data = $this->doLogin($account, $request->post('jpush_reg_id', ''));
            }
        } catch (Exception $exception) {
            ErrorMsgServive::write($exception, requst()->url());
            return $this->error('微信授权登录出错~');
        }
        return $this->success($data);
    }

    //微信小程序登录(微信)
    public function miniProgram(Request $request)
    {
        try {
            $mini = Factory::miniProgram($this->wxConfig);
            $newMini = $mini->auth->session($request->input('code'));

            $iv = $request->input('iv');
            $encryptData = $request->input('encryptData');
            $decryptedData = $mini->encryptor->decryptData($newMini['session_key'], $iv, $encryptData);
            $openId = $decryptedData['openid'];
            $user = User::query()->where('open_id', $openId)->first();
            if (!$user) {
                $data['open_id'] = $openId;
                $data['user'] = [];
            } else {
                $account = $user->mobile ?: $user->email;
                $data = $this->doLogin($account, $request->post('jpush_reg_id', ''));
            }
        } catch (Exception $exception) {
            ErrorMsgServive::write($exception, requst()->url());
            return $this->error('微信授权登录出错~');
        }
        return $this->success($data);
    }

    //微信小程序获取手机号
    public function decryptPhone(Request $request)
    {
        $user = auth('api')->user();
        try {
            $mini = Factory::miniProgram($this->wxConfig);
            $newMini = $mini->auth->session($request->input('code'));

            $iv = $request->input('iv');
            $encryptData = $request->input('encryptData');
            $decryptedData = $mini->encryptor->decryptData($newMini['session_key'], $iv, $encryptData);

            $user = User::query()->where('id', $user->id)->first();
            $user->mobile = $decryptedData['purePhoneNumber'];
            $user->save();
        } catch (\Exception $exception) {
            ErrorMsgServive::write($exception, requst()->url());
            return $this->error('获取手机号出错~');
        }
        return $this->success();
    }

    //H5 应用进行微信授权登录
    public function h5Oauth()
    {

    }

    //微信小程序 code
    public function miniCode()
    {

    }

    //执行登录
    public function doLogin($user, $jpush_reg_id = null)
    {
        if (!empty($jpush_reg_id)) {
            //清除登陆过本设备的账号设备id
            User::query()->where('jpush_reg_id', $jpush_reg_id)->update(['jpush_reg_id' => '']);
            //当前登录用户绑定设备
            $user->jpush_reg_id = $jpush_reg_id;
            //清除别名
            JPushService::deleteAlias('user_id_' . $user->id);
            //设置极光推送别名
            JPushService::updateAlias($user->jpush_reg_id, 'user_id_' . $user->id);
        }
        $user->online = 1;
        $user->last_login_time = date('Y-m-d H:i:s');
        $user->last_login_ip = request()->ip();
        if (!$user->save()) {
            return $this->error('登录失败！');
        }
        $token = Auth::guard('api')->fromUser($user);
        $userInfo = UserService::getUserInfoById($user->id);
        $data = [
            'token' => "Bearer " . $token,
            'user_info' => $userInfo,
        ];
        return $data;
    }

    //用户是否存在
    public function isUserExist($account)
    {
        $user = User::where(['mobile' => $account])
            ->orWhere(['email' => $account])
            ->first();
        if (!$user) {
            return false;
        }
        return $user;
    }

    //忘记密码
    public function forgetPassword(Request $request)
    {
        $account   = $request->input('account', '');
        $validator = Validator::make($request->all(), [
            'account' => 'required',
        ]);
        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }
        // 查询用户是否存在
        $user = User::query()
            ->where('account','=',$account)
            ->first();
        if(!$user){
            return $this->error('账号不存在！');
        }
        if($user->status == 0){
            return $this->error('账号已被禁用！');
        }
        // 随机生成密码
        $password = rand(100000, 999999);
        $content = '您找回的密码为系统重新生成：'.$password.'，登录后请自行修改！';
        $res = EmailController::sendNotice($user->email,'找回密码通知',$content);
        if(!$res){
            return $this->error("找回密码失败！");
        }
        $user->password = $password; // 处理过加密的
        $user->save();
        return $this->success('',0,'我们已将密码发至您的电子邮件！');
    }

    //找回ID
    public function findId(Request $request)
    {
        $email   = $request->input('email', '');
        $validator = Validator::make($request->all(), [
            'email' => 'required',
        ]);
        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }
        // 查询用户是否存在
        $user = User::query()
            ->where('email','=',$email)
            ->first();
        if(!$user){
            return $this->error('邮箱不存在！');
        }
        if($user->status == 0){
            return $this->error('账号已被禁用！');
        }
        $content = '您找回的ID为：'.$user->account.'，请妥善保存！';
        $res = EmailController::sendNotice($user->email,'找回ID通知',$content);
        if(!$res){
            return $this->error("找回ID失败！");
        }
        return $this->success('',0,'我们已将ID发至您的电子邮箱！');
    }

    //退出
    public function logout()
    {
        $user = auth('api')->user();
        if($user){
            if(!empty($user->jpush_reg_id)){
                //清空极光别名
                JPushService::updateAlias($user->jpush_reg_id, '');
            }
            $user->online = 0;
            $user->save();
        }
        auth('api')->logout();
        return $this->success('',0,'退出成功！');
    }
}
