<?php

namespace App\Http\Controllers\Api;

use App\Exceptions\SmsException;
use App\Models\AdminRole;
use App\Models\User;
use App\Models\UserInfoModel;
use App\Models\UserInviteLog;
use App\Models\UserVipLimit;
use App\Services\JPushService;
use App\Services\SmsService;
use App\Services\TencentImAccountService;
use App\Transformers\UserTransformer;
use Carbon\Carbon;
use http\Env\Response;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use PHPUnit\Util\Exception;


class AuthorizationsController extends Controller
{
    protected $tencentImAccountService;

    public function __construct(TencentImAccountService $tencentImAccountService)
    {
        $this->tencentImAccountService = $tencentImAccountService;
    }

    /**
     * 极光认证一键登录
     */
    public function auth_login(Request $request){
        file_put_contents("login_data.log",var_export($request->all(),true).PHP_EOL,FILE_APPEND);
        try {
            if(empty($request->loginToken)){
                throw new Exception("参数错误");
            }
            $loginToken = $request->loginToken;
            $exID = $request->post('exID','800');
            $ret = JPushService::jgLoginTokenVerify($loginToken,$exID);
            $mobile = JPushService::jgOpensslPrivateDecrypt($ret['phone']);
            $res = $this->do_login($mobile);
        }catch (\Exception $exception){
            return $this->response->errorForbidden($exception->getMessage());
        }
        return response()->json($res);
    }


    /**
     * 手机号登录
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function login_by_mobile(Request $request)
    {
        file_put_contents("login_data.log",var_export($request->all(),true).PHP_EOL,FILE_APPEND);
        try {
            $validator = Validator::make($request->all(), [
                'mobile' => ['required', 'regex:/^1[3456789]\d{9}$/'],
                'verifyKey' => 'bail|required|string',
                'smsCode' => 'bail|required',
            ], [
                'mobile.required'=>"手机号码必须",
                'mobile.regex'=>"手机号码格式错误",
                'verifyKey.required'=>"验证码必须",
                'smsCode.required'=>"短信验证码必须",
            ]);
            if ($validator->fails()) {
                return $this->response()->errorForbidden($validator->messages()->first());
            }
            //验证短信验证码
            SmsService::checkSmsCodeByVerifyKey($request->verifyKey, $request->smsCode);

            $res = $this->do_login($request->mobile,null,$request->registrationId,$request->phoneModel);
        }catch (\Exception $exception){
            return $this->response->errorForbidden($exception->getMessage());
        } catch (SmsException $e) {
            return $this->response->errorForbidden($e->getMessage());
        }

        return response()->json($res);
    }

    /**
     * 用户账号密码登录
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|void
     */
    public function login_by_account_password(Request $request)
    {
        file_put_contents("login_data.log",var_export($request->all(),true).PHP_EOL,FILE_APPEND);
        try {
            $validator = Validator::make($request->all(), [
                'mobile' => ['required', 'regex:/^1[3456789]\d{9}$/'],
                'password' => 'required|string',
            ],[
                'mobile.required'=>"手机号码必须",
                'mobile.regex'=>"手机号码格式错误",
                'password.required'=>"密码必须",
            ]);
            if ($validator->fails()) {
                throw new Exception($validator->messages()->first());
            }
            $res = $this->do_login($request->mobile,$request->password);
        }catch (\Exception $exception){
            return $this->response->errorForbidden($exception->getMessage());
        }

        return response()->json($res);
    }


    //登录操作
    public function do_login($mobile,$password=null,$registrationId=null,$phoneModel=null){
        if(!empty($password)){
            if (!$user=User::query()->where(['mobile' => $mobile,'is_distory'=>0])->whereNull('deleted_at')->first()) {
                throw new Exception("用户不存在");
            }
            $credentials = ['mobile'=>$mobile,'password'=>$password];

            if (!auth('api')->attempt($credentials)) {
                throw new Exception("用户名或密码错误");
            }
        }else{
            if(!User::query()->where(['mobile'=>$mobile,'is_distory'=>0])->first()){
                User::query()->create([
                    'mobile' => $mobile,
                ]);
            }
            $user = User::query()->where(['mobile'=>$mobile,'is_distory'=>0])->whereNull('deleted_at')->first();
        }

        if (!$user->ycode) {
            $user->ycode = $this->create_code();
        }
        if(!UserInfoModel::query()->where('user_id',$user->id)->first()){
            UserInfoModel::query()->create([
                'user_id'=>$user->id,
                'avatar'=>"https://zhengda.oss-cn-chengdu.aliyuncs.com/chengluApp/default.jpg",
                'nickname'=>"用户".$user->mobile,
                'birthday'=>"1990-01-01"
            ]);
        }

        if(!UserVipLimit::query()->where('user_id',$user->id)->first()){
            UserVipLimit::query()->create([
                'user_id'=>$user->id,
            ]);
        }

        if (!$user->tencent_im_user_id) {
            $user->tencent_im_user_id = $this->tencentImAccountService->accountImport($user);
        }
        if($user->status!=1){
            throw new Exception("用户已被禁用，请联系管理员");
        }
        $token = Auth::guard('api')->fromUser($user);
        $user->remember_token = $token;
        $user->last_login_time = Carbon::now();
        $user->last_login_ip = request()->ip();
        if(!empty($registrationId)){
            $user->registrationId = $registrationId;
            $user->phoneModel = $phoneModel;
        }

        $user->save();

        $resdata['token'] = "Bearer ".$token;
        $resdata['sex'] = $user->sex;
        $resdata['password'] = $user->password?1:0;
        $resdata['tencent_im_user_id'] =$user->tencent_im_user_id;
        $resdata['mobile'] =$user->mobile;
        $resdata['lock_pass'] =$user->lock_pass?$user->lock_pass:false;
        $resdata['status'] =$user->status;
        $resdata['is_auth'] =$user->is_auth;
        $resdata['ycode'] =$user->ycode;
        $resdata['online'] =$user->online;
        $resdata['notice_status'] =$user->notice_status;
        return $resdata;
    }


    public function captcha(){
      return  response(captcha_src());
    }

    /**
     * 根据用户ID生成唯一邀请码
     * @param $user_id
     * @return string
     */
   public function create_code() {
       $code =  create_invite_code();
       if(User::where(['ycode'=>$code])->first()){
           $code =  create_invite_code();
       }
       return $code;
    }

    /**
     * 注册账号
     */
    public function register(Request $request){
        $validator = Validator::make($request->all(), [
            'mobile' => ['required', 'regex:/^1[3456789]\d{9}$/'],
            'password' => 'bail|required',
        ],[
            'mobile.required'=>"手机号码必须",
            'mobile.regex'=>"手机号码格式错误",
            'password.required'=>"密码必须",
        ]);
        if ($validator->fails()){
            return $this->response()->errorForbidden($validator->messages()->first());
        }
        if(User::where(['mobile'=>$request->mobile,'is_distory'=>0])->first()){
            return $this->response->errorForbidden("该手机号码已使用");
        }

        $ins = array();

        $ins['mobile'] = $request->mobile;
        $ins['password'] = $request->password;
        if(User::create($ins)){
            return response()->json(['message'=>"注册成功"]);
        }else{
            return $this->response->errorForbidden("注册失败");
        }
    }

    public function reg_h5(Request $request){
        $validator = Validator::make($request->all(), [
            'mobile' => ['required', 'regex:/^1[3456789]\d{9}$/'],
            'password' => 'bail|required',
            'smsCode' => 'bail|required',
        ],[
            'mobile.required'=>"手机号码必须",
            'mobile.regex'=>"手机号码格式错误",
            'password.required'=>"密码必须",
            'smsCode.required'=>"短信验证码必须",
        ]);
        if ($validator->fails()){
            return response()->json([
                'code'=>0,
                'message'=>$validator->messages()->first()
            ]);
        }
        DB::beginTransaction();
        try {
            //验证短信验证码
            SmsService::checkSmsCodeByVerifyKey($request->verifyKey, $request->smsCode);

            if(User::where(['mobile'=>$request->mobile,'is_distory'=>0])->first()){
                throw new Exception("该手机号码已使用");
            }
            //邀请码设置
            $pid = 0;
            if(isset($request->ycode) && $request->ycode!=""){
                if(!$puser = User::where(['ycode'=>$request->ycode])->first()){
                    throw new Exception("邀请码不存在");
                }
                $pid = $puser->id;
            }
            $ins = array();
            $ins['mobile'] = $request->mobile;
            $ins['password'] = $request->password;
            $ins['pid'] = $pid;
            $ins['created_at'] = date('Y-m-d H:i:s');
            $ins['updated_at'] = date('Y-m-d H:i:s');
            $insid = User::query()->insertGetId($ins);
            //赠送会员天数
            UserInviteLog::query()->create([
                'user_id'=>$pid,
                'invite_id'=>$insid,
                'day'=>1,
                'status'=>0,
            ]);
            DB::commit();
        } catch (SmsException $e) {
            DB::rollBack();
            return response()->json([
                'code'=>0,
                'message'=>$e->getMessage()
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'code'=>0,
                'message'=>'短信校验失败'
            ]);
        }
        return response()->json([
            'code'=>1,
            'message'=>'注册成功'
        ]);
    }



    /**
     * 忘记密码
     */
    public function forget_password(Request $request){
        try {
            $validator = Validator::make($request->all(), [
                'mobile' => ['required', 'regex:/^1[3456789]\d{9}$/'],
                'verifyKey' => 'bail|required|string',
                'smsCode' => 'bail|required',
                'password' => 'bail|required',
            ],[
                'mobile.required'=>"手机号码必须",
                'mobile.regex'=>"手机号码格式错误",
                'verifyKey.required'=>"验证码必须",
                'smsCode.required'=>"短信验证码必须",
                'password.required'=>"密码必须",
            ]);
            if ($validator->fails()) {
                throw new Exception($validator->messages()->first());
            }
            //验证短信验证码
            SmsService::checkSmsCodeByVerifyKey($request->verifyKey, $request->smsCode);

            $user = User::where(['mobile'=>$request->mobile])->first();
            $user->password =$request->password;// Hash::make($request->password);
            if(!$user->save()){
                throw new Exception("设置失败");
            }
            $res = $this->do_login($request->mobile,$request->password);
        }catch (\Exception $exception){
            return $this->response->errorForbidden($exception->getMessage());
        } catch (SmsException $e) {
            return $this->response->errorForbidden($e->getMessage());
        }
        return response()->json($res);

    }

    /**
     * 用户协议
     */
    public function xieyi(Request $request){
        if(isset($request->cont) && $request->cont==1){
            $data = DB::table("document")->where(['id'=>$request->id])->first();
            return response()->json(['data'=>$data]);
        }else{
            $url = "https://".$_SERVER['HTTP_HOST']."/xieyi/content.html?id=1";
            $url2 = "https://".$_SERVER['HTTP_HOST']."/xieyi/content.html?id=2";
            return response()->json(['url1'=>$url,'url2'=>$url2]);
        }
    }

    /**
     * Get the authenticated User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function me()
    {
        $user = auth('api')->user();
        return $this->response->item($user, new UserTransformer());
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        auth('api')->logout();

        return response()->json(['message' => '退出成功！']);
    }

    /**
     * Refresh a token.
     * 刷新token，如果开启黑名单，以前的token便会失效。
     * 值得注意的是用上面的getToken再获取一次Token并不算做刷新，两次获得的Token是并行的，即两个都可用。
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->respondWithToken(Auth::guard('api')->refresh());
    }

    static public function updateLastLogin(User $user, string $jwtToken)
    {
        $user->remember_token = $jwtToken;
        $user->last_login_time = Carbon::now();
        $user->last_login_ip = request()->ip();
        $user->save();
    }

    /**
     * Get the token array structure.
     *
     * @param string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'Bearer',
            'expires_in' => Auth::guard('api')->factory()->getTTL() * 60
        ]);
    }
}
