<?php

declare(strict_types=1);

namespace App\Livewire\Auth;

use App\Contracts\Services\RoleRedirectServiceInterface;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Validation\ValidationException;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Rule;
use Livewire\Component;

#[Layout('layouts.auth')]
final class Login extends Component
{
    #[Rule('required|email|max:255')]
    public string $email = '';

    #[Rule('required|string|min:8')]
    public string $password = '';

    public bool $emailVerified = false;

    public ?User $user = null;

    public string $userRole = '';

    public string $title = 'Welcome Back';

    public string $subtitle = 'Sign in to your account';

    public string $roleTitle = 'ESTATE';

    public string $roleDescription = 'Your vacation rental platform';

    public function mount(): void {}

    public function updatedEmail(): void
    {
        $this->checkEmail();
    }

    public function checkEmail(): void
    {
        // Clear previous errors
        $this->resetErrorBag('email');

        // Only validate if email is not empty and looks like a valid format
        if (empty($this->email)) {
            $this->emailVerified = false;
            $this->user = null;

            return;
        }

        // Basic email format check before database query
        if (! filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
            $this->emailVerified = false;
            $this->user = null;

            return;
        }

        $user = User::where('email', $this->email)->first();

        if (! $user) {
            $this->addError('email', 'No account found with this email address.');
            $this->emailVerified = false;
            $this->user = null;

            return;
        }

        if ($user->status !== 'active') {
            $this->addError('email', 'Your account is not active. Please contact support.');
            $this->emailVerified = false;
            $this->user = null;

            return;
        }

        $this->user = $user;
        $this->emailVerified = true;
        $this->userRole = $this->user->roles->first()?->name ?? 'guest';

        // Update role title and description based on user role
        $this->updateRoleDisplay();
    }

    public function login(): void
    {
        $this->validate();

        if (! $this->emailVerified || ! $this->user) {
            $this->addError('email', 'Please verify your email first.');

            return;
        }

        // Check rate limiting
        $key = 'login:'.$this->email;
        if (RateLimiter::tooManyAttempts($key, 5)) {
            $seconds = RateLimiter::availableIn($key);
            throw ValidationException::withMessages([
                'email' => "Too many login attempts. Please try again in {$seconds} seconds.",
            ]);
        }

        // Attempt authentication
        if (! Hash::check($this->password, $this->user->password)) {
            RateLimiter::hit($key, 300); // 5 minutes
            throw ValidationException::withMessages([
                'password' => 'The provided password is incorrect.',
            ]);
        }

        // Clear rate limiting on successful login
        RateLimiter::clear($key);

        // Login the user
        Auth::login($this->user);

        // Redirect based on role
        $redirectService = app(RoleRedirectServiceInterface::class);
        $redirectUrl = $redirectService->getRedirectUrl($this->user);

        $this->redirect($redirectUrl);
    }

    public function resetForm(): void
    {
        $this->email = '';
        $this->password = '';
        $this->emailVerified = false;
        $this->user = null;
        $this->userRole = '';
        $this->resetErrorBag();
    }

    private function updateRoleDisplay(): void
    {
        match ($this->userRole) {
            'admin' => [
                $this->roleTitle = 'ADMIN',
                $this->roleDescription = 'Manage the platform and users',
            ],
            'owner' => [
                $this->roleTitle = 'OWNER',
                $this->roleDescription = 'Manage your properties and bookings',
            ],
            'partner' => [
                $this->roleTitle = 'PARTNER',
                $this->roleDescription = 'Access partner tools and analytics',
            ],
            default => [
                $this->roleTitle = 'GUEST',
                $this->roleDescription = 'Find and book amazing properties',
            ]
        };
    }

    public function render()
    {
        return view('livewire.auth.login');
    }
}
