<?php

namespace App\Http\Controllers\Api;

use App\Http\Requests\UserRegister;
use App\Models\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Validator;

class AuthApiController extends Controller
{

    use ThrottlesLogins, RegistersUsers;

    public function register(UserRegister $request)
    {
        $email = $request->input('email');
        if (User::where('email', $email)->exists()) {
            return $this->setError('Email has been taken');
        }

        //判断邮箱验证码
        $redisKey = 'sem_email_code_register_' . $email;
        $cachedEmailCode = Redis::get($redisKey);
        if ($cachedEmailCode != $request->input('email_code')) {
            return $this->setError('Email code invalid');
        }
        $user = User::createUser($request->all());

        \Auth::login($user);
        return $this->setSuccess('Register success');
    }


    public function login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|string|email|max:255',
            'password' => 'required|string|min:8',
        ], [
            'password.min' => 'Password must be at least 8 characters long.'
        ]);

        if ($validator->fails()) {
            return $this->setError($validator->errors()->first());
        }

        $userExists = User::where('email', $request->email)->exists();
        if (!$userExists) {
            return $this->setError('User dose not exist');
        }

        if ($this->attemptLogin($request)) {
            $request->session()->regenerate();
            return $this->setSuccess('Login success');
        }

        $this->incrementLoginAttempts($request);

        return $this->setError('Login failure');
    }

    public function logout(Request $request)
    {
        Auth::logout();
        return $this->setSuccess('Logout success');
    }

    public function resetPassword(Request $request)
    {

        $validator = Validator::make($request->all(), [
            'old_password' => 'required|min:8',
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ], [
            'old_password.min' => 'Password must be at least 8 characters long.',
            'password.min' => 'Password must be at least 8 characters long.',
            'password.confirmed' => 'Passwords do not match!',
        ]);

        if ($validator->fails()) {
            return $this->setError($validator->errors()->first());
        }
        $password = $request->get('password');
        $oldPassword = $request->get('old_password');
        $userId = Auth::user()->id;
        $hashedPassword = User::where('id', $userId)->value('password');
        if (!Hash::check($oldPassword, $hashedPassword)) {
            return $this->setError('Wrong Password!');
        }

        $user = User::find($userId);
        $user->password = Hash::make($password);
        $user->update_time = time();
        $result = $user->save();
        if (!$result) {
            return $this->setError('Reset password failed');
        }

        return $this->setSuccess('Reset password success');
    }

    //发送邮箱验证码
    public function sendEmailCode(Request $request)
    {
        $email = $request->input('email');
        $type = $request->input('type', 'register');
        if (!$email) {
            return $this->setError('Email address required');
        }
        $info = User::where('email', $email)->first();
        if ($info && $type == 'register') {
            return $this->setError('This email had been registered');
        }

        //发送验证码
        $code = mt_rand(1000, 9999);
        $redisKey = 'sem_email_code_' . $type . '_' . $email;
        if (Redis::get($redisKey)) {
            return $this->setError('Email code had been sent');
        }
        Redis::set($redisKey, $code);
        Redis::expire($redisKey, 60);
        $subject = config('mail.from.name');
        $msg = 'Email Code:' . $code . '.';
        Mail::raw($msg, function ($message) use ($email, $subject) {
            $message->to($email)->subject($subject);
        });

        //错误处理
        if (count(Mail::failures())) {
            return $this->setError('Email code send failed');
        }

        return $this->setSuccess('Email code send success');
    }

}