<?php

declare(strict_types=1);

namespace App\Listeners;

use App\Models\LoginHistory;
use App\Notifications\NewDeviceLoginNotification;
use Illuminate\Auth\Events\Login;
use Illuminate\Support\Facades\Log;
use Jenssegers\Agent\Agent;
use Stevebauman\Location\Facades\Location;

class RecordLoginHistory
{
    public function handle(Login $event): void
    {
        $user = $event->user;
        $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 login history', [
                'ip' => $ip,
                'error' => $e->getMessage(),
            ]);
        }

        // Device hash and new device detection
        $deviceHash = LoginHistory::generateDeviceHash($userAgentString, $ip);
        $hasExistingLogins = LoginHistory::query()
            ->forUser($user->id)
            ->exists();
        $isNewDevice = false;

        if ($hasExistingLogins) {
            $existingDevice = LoginHistory::query()
                ->forUser($user->id)
                ->where('device_hash', $deviceHash)
                ->exists();
            $isNewDevice = ! $existingDevice;
        }

        // Check if 2FA was used (user has 2FA enabled means it was used for this login)
        $twoFactorUsed = ! empty($user->two_factor_secret);

        $loginHistory = 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' => true,
            'two_factor_used' => $twoFactorUsed,
            'is_new_device' => $isNewDevice,
            'device_hash' => $deviceHash,
        ]);

        // Notify on new device (only if user has previous logins)
        if ($isNewDevice) {
            $user->notify(new NewDeviceLoginNotification($loginHistory));
        }
    }

    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';
    }
}
