<?php

declare(strict_types=1);

namespace App\Listeners;

use App\Models\LoginHistory;
use App\Models\User;
use Illuminate\Auth\Events\Failed;
use Illuminate\Support\Facades\Log;
use Jenssegers\Agent\Agent;
use Stevebauman\Location\Facades\Location;

class RecordFailedLogin
{
    public function handle(Failed $event): void
    {
        // Look up user by email — may not exist
        $email = $event->credentials['email'] ?? null;

        if (! $email) {
            return;
        }

        $user = $event->user ?? User::query()->where('email', $email)->first();

        if (! $user) {
            return;
        }

        $request = request();
        $ip = $request->ip() ?? '127.0.0.1';
        $userAgentString = $request->userAgent() ?? '';

        // Parse user agent
        $agent = new Agent;
        $agent->setUserAgent($userAgentString);

        $deviceType = $this->resolveDeviceType($agent);
        $browser = $agent->browser() ?: null;
        $os = $agent->platform() ?: null;

        // GeoIP lookup
        $country = null;
        $city = null;

        try {
            $position = Location::get($ip);

            if ($position) {
                $country = $position->countryName ?? null;
                $city = $position->cityName ?? null;
            }
        } catch (\Exception $e) {
            Log::debug('GeoIP lookup failed for failed login history', [
                'ip' => $ip,
                'error' => $e->getMessage(),
            ]);
        }

        $deviceHash = LoginHistory::generateDeviceHash($userAgentString, $ip);

        LoginHistory::query()->create([
            'user_id' => $user->id,
            'ip_address' => $ip,
            'user_agent' => $userAgentString,
            'device_type' => $deviceType,
            'browser' => $browser,
            'os' => $os,
            'location_country' => $country,
            'location_city' => $city,
            'success' => false,
            'two_factor_used' => false,
            'is_new_device' => false,
            'device_hash' => $deviceHash,
        ]);
    }

    private function resolveDeviceType(Agent $agent): string
    {
        if ($agent->isRobot()) {
            return 'Robot';
        }

        if ($agent->isPhone()) {
            return 'Phone';
        }

        if ($agent->isTablet()) {
            return 'Tablet';
        }

        if ($agent->isDesktop()) {
            return 'Desktop';
        }

        return 'Other';
    }
}
