<?php

declare(strict_types=1);

namespace App\Filament\System\Pages\Auth;

use App\Models\PlatformUser;
use App\Models\ManagedEnvironment;
use App\Services\Intune\AuditLogger;
use Filament\Auth\Http\Responses\Contracts\LoginResponse;
use Filament\Auth\Pages\Login as BaseLogin;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Validation\ValidationException;

class Login extends BaseLogin
{
    /**
     * Filament's base login page uses Livewire-level rate limiting. We override it
     * to enforce the System panel policy via Laravel's RateLimiter (SR-003).
     */
    protected function rateLimit($maxAttempts, $decaySeconds = 60, $method = null, $component = null): void {}

    public function authenticate(): ?LoginResponse
    {
        $data = $this->form->getState();
        $email = (string) ($data['email'] ?? '');
        $throttleKey = $this->throttleKey($email);

        if (RateLimiter::tooManyAttempts($throttleKey, 10)) {
            $this->audit(status: 'failure', email: $email, actor: null, reason: 'throttled');

            $seconds = RateLimiter::availableIn($throttleKey);

            throw ValidationException::withMessages([
                'data.email' => __('auth.throttle', [
                    'seconds' => $seconds,
                    'minutes' => (int) ceil($seconds / 60),
                ]),
            ]);
        }

        try {
            $response = parent::authenticate();
        } catch (ValidationException $exception) {
            RateLimiter::hit($throttleKey, 60);
            $this->audit(status: 'failure', email: $email, actor: null, reason: 'invalid_credentials');

            throw $exception;
        }

        if (! $response) {
            return null;
        }

        /** @var PlatformUser|null $user */
        $user = auth('platform')->user();

        if (! ($user instanceof PlatformUser)) {
            return $response;
        }

        if (! $user->is_active) {
            auth('platform')->logout();

            RateLimiter::hit($throttleKey, 60);
            $this->audit(status: 'failure', email: $email, actor: null, reason: 'inactive');

            throw ValidationException::withMessages([
                'data.email' => __('filament-panels::auth/pages/login.messages.failed'),
            ]);
        }

        RateLimiter::clear($throttleKey);
        $user->forceFill(['last_login_at' => now()])->saveQuietly();

        $this->audit(status: 'success', email: $email, actor: $user);

        return $response;
    }

    private function throttleKey(string $email): string
    {
        $ip = (string) request()->ip();
        $normalizedEmail = mb_strtolower(trim($email));

        return "system-login:{$ip}:{$normalizedEmail}";
    }

    private function audit(string $status, string $email, ?PlatformUser $actor, ?string $reason = null): void
    {
        $tenant = ManagedEnvironment::query()->where('slug', 'platform')->first();

        if (! $tenant) {
            return;
        }

        app(AuditLogger::class)->log(
            tenant: $tenant,
            action: 'platform.auth.login',
            context: [
                'attempted_email' => $email,
                'ip' => request()->ip(),
                'user_agent' => request()->userAgent(),
                'reason' => $reason,
            ],
            actorId: $actor?->getKey(),
            actorEmail: $actor?->email ?? ($email ?: null),
            actorName: $actor?->name,
            status: $status,
            resourceType: 'platform_user',
            resourceId: $actor ? (string) $actor->getKey() : null,
        );
    }
}
