<?php

namespace App\Livewire\Auth;

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Livewire\Attributes\Layout;
use Livewire\Component;

/**
 * Where somebody waits between registering and confirming.
 *
 * Signed in but not through: the account exists, and nothing in the portal
 * opens until the address is confirmed. The page therefore has to offer the
 * only two things that can move somebody forward — send it again, or sign out
 * and register with the address they meant.
 *
 * Fortify would own this page, but 'views' => false: the app renders its own
 * screens (R1/R2) and Fortify keeps only the POST actions.
 */
#[Layout('layouts.portal')]
class VerifyEmail extends Component
{
    /**
     * Six a minute is generous for a person and useless for anything else.
     * Without it this is a button that makes the server send mail to an
     * arbitrary address as fast as it can be clicked.
     */
    private const PER_MINUTE = 6;

    /**
     * Somebody already through has no step left, and telling them they do is
     * how a confirmed account goes looking for a mail it does not need. The
     * `verified` middleware only guards the other direction — it keeps the
     * unconfirmed out of the portal and has nothing to say about this page.
     */
    public function mount()
    {
        if (Auth::user()?->hasVerifiedEmail()) {
            return $this->redirectRoute('dashboard', navigate: false);
        }

        return null;
    }

    public function resend(): void
    {
        $user = Auth::user();

        // Already through — a stale tab, or the link opened in another window.
        // Sending another confirmation for an address that no longer needs one
        // is how somebody ends up chasing a mail they do not need.
        if ($user === null || $user->hasVerifiedEmail()) {
            $this->redirectRoute('dashboard', navigate: true);

            return;
        }

        $key = 'verify-resend:'.$user->getKey();

        if (RateLimiter::tooManyAttempts($key, self::PER_MINUTE)) {
            $this->dispatch('notify', message: __('verify_email.notice_hint'));

            return;
        }

        RateLimiter::hit($key, 60);
        $user->sendEmailVerificationNotification();

        $this->dispatch('notify', message: __('verify_email.notice_sent'));
    }

    public function signOut()
    {
        Auth::guard('web')->logout();
        session()->invalidate();
        session()->regenerateToken();

        return $this->redirectRoute('login', navigate: false);
    }

    public function render()
    {
        return view('livewire.auth.verify-email', [
            'email' => Auth::user()?->getEmailForVerification() ?? '',
        ]);
    }
}
