<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\View\View;

class TwoFactorChallengeController extends Controller
{
    public function create(Request $request): View|RedirectResponse
    {
        if (! $request->session()->has('login.two_factor.user_id')) {
            return redirect()->route('login');
        }

        return view('auth.two-factor-challenge');
    }

    public function store(Request $request): RedirectResponse
    {
        $request->validate(['code' => ['required', 'digits:6']]);

        $userId = (int) $request->session()->get('login.two_factor.user_id');
        $key = '2fa-login:'.$userId;
        $rateKey = '2fa-login-attempts:'.$userId.'|'.$request->ip();

        if (RateLimiter::tooManyAttempts($rateKey, 5)) {
            return back()->withErrors(['code' => 'Demasiados intentos. Intenta nuevamente en unos minutos.']);
        }

        $hash = Cache::get($key);

        if (! $hash || ! Hash::check($request->string('code'), $hash)) {
            RateLimiter::hit($rateKey, 600);

            return back()->withErrors(['code' => 'El código no es válido o ya venció.']);
        }

        $user = User::findOrFail($userId);

        Cache::forget($key);
        RateLimiter::clear($rateKey);

        Auth::login($user, (bool) $request->session()->pull('login.two_factor.remember', false));
        $request->session()->forget('login.two_factor.user_id');
        $request->session()->regenerate();

        $user->forceFill([
            'last_login_at' => now(),
            'last_login_ip' => $request->ip(),
        ])->save();

        return redirect()->intended(route('dashboard', absolute: false));
    }
}
