<?php

declare(strict_types=1);

use App\Framework\Core\ValueObjects\Version;
use App\Framework\UserAgent\Enums\BrowserType;
use App\Framework\UserAgent\Enums\EngineType;
use App\Framework\UserAgent\Enums\PlatformType;
use App\Framework\UserAgent\ParsedUserAgent;
use App\Framework\UserAgent\ValueObjects\DeviceCategory;

describe('ParsedUserAgent Value Object', function () {
    it('creates ParsedUserAgent with Version value objects', function () {
        $parsed = new ParsedUserAgent(
            raw: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0',
            browser: BrowserType::CHROME,
            browserVersion: Version::fromString('120.0.0'),
            platform: PlatformType::WINDOWS,
            platformVersion: Version::fromString('10.0.0'),
            engine: EngineType::BLINK,
            engineVersion: Version::fromString('120.0.0'),
            isMobile: false,
            isBot: false,
            isModern: true
        );

        expect($parsed->browser)->toBe(BrowserType::CHROME);
        expect($parsed->browserVersion)->toBeInstanceOf(Version::class);
        expect($parsed->browserVersion->toString())->toBe('120.0.0');
        expect($parsed->platform)->toBe(PlatformType::WINDOWS);
        expect($parsed->platformVersion->toString())->toBe('10.0.0');
        expect($parsed->isModern)->toBeTrue();
    });

    it('returns browser name with version', function () {
        $parsed = new ParsedUserAgent(
            raw: 'Mozilla/5.0',
            browser: BrowserType::FIREFOX,
            browserVersion: Version::fromString('115.0.0'),
            platform: PlatformType::LINUX,
            platformVersion: Version::fromString('5.15.0'),
            engine: EngineType::GECKO,
            engineVersion: Version::fromString('115.0.0'),
            isMobile: false,
            isBot: false,
            isModern: true
        );

        expect($parsed->getBrowserName())->toBe('Firefox 115.0.0');
    });

    it('returns platform name with version', function () {
        $parsed = new ParsedUserAgent(
            raw: 'Mozilla/5.0',
            browser: BrowserType::SAFARI,
            browserVersion: Version::fromString('16.5.0'),
            platform: PlatformType::MACOS,
            platformVersion: Version::fromString('13.4.0'),
            engine: EngineType::WEBKIT,
            engineVersion: Version::fromString('605.1.15'),
            isMobile: false,
            isBot: false,
            isModern: true
        );

        expect($parsed->getPlatformName())->toBe('macOS 13.4.0');
    });

    it('returns correct device category for desktop', function () {
        $parsed = new ParsedUserAgent(
            raw: 'Mozilla/5.0',
            browser: BrowserType::CHROME,
            browserVersion: Version::fromString('120.0.0'),
            platform: PlatformType::WINDOWS,
            platformVersion: Version::fromString('10.0.0'),
            engine: EngineType::BLINK,
            engineVersion: Version::fromString('120.0.0'),
            isMobile: false,
            isBot: false,
            isModern: true
        );

        expect($parsed->getDeviceCategory())->toBe(DeviceCategory::DESKTOP);
        expect($parsed->getDeviceCategory()->isDesktop())->toBeTrue();
    });

    it('returns correct device category for mobile', function () {
        $parsed = new ParsedUserAgent(
            raw: 'Mozilla/5.0',
            browser: BrowserType::CHROME,
            browserVersion: Version::fromString('120.0.0'),
            platform: PlatformType::ANDROID,
            platformVersion: Version::fromString('13.0.0'),
            engine: EngineType::BLINK,
            engineVersion: Version::fromString('120.0.0'),
            isMobile: true,
            isBot: false,
            isModern: true
        );

        expect($parsed->getDeviceCategory())->toBe(DeviceCategory::MOBILE);
        expect($parsed->getDeviceCategory()->isMobile())->toBeTrue();
    });

    it('returns correct device category for bot', function () {
        $parsed = new ParsedUserAgent(
            raw: 'Googlebot/2.1',
            browser: BrowserType::UNKNOWN,
            browserVersion: Version::fromString('0.0.0'),
            platform: PlatformType::UNKNOWN,
            platformVersion: Version::fromString('0.0.0'),
            engine: EngineType::UNKNOWN,
            engineVersion: Version::fromString('0.0.0'),
            isMobile: false,
            isBot: true,
            isModern: false
        );

        expect($parsed->getDeviceCategory())->toBe(DeviceCategory::BOT);
        expect($parsed->getDeviceCategory()->isBot())->toBeTrue();
    });

    it('checks browser feature support using Version comparison', function () {
        $parsed = new ParsedUserAgent(
            raw: 'Mozilla/5.0',
            browser: BrowserType::CHROME,
            browserVersion: Version::fromString('90.0.0'),
            platform: PlatformType::WINDOWS,
            platformVersion: Version::fromString('10.0.0'),
            engine: EngineType::BLINK,
            engineVersion: Version::fromString('90.0.0'),
            isMobile: false,
            isBot: false,
            isModern: true
        );

        expect($parsed->supports('webp'))->toBeTrue();
        expect($parsed->supports('avif'))->toBeTrue(); // Chrome 90+ supports AVIF
        expect($parsed->supports('es2017'))->toBeTrue();
        expect($parsed->supports('es2020'))->toBeTrue();
    });

    it('does not support features for bots', function () {
        $parsed = new ParsedUserAgent(
            raw: 'Googlebot/2.1',
            browser: BrowserType::UNKNOWN,
            browserVersion: Version::fromString('0.0.0'),
            platform: PlatformType::UNKNOWN,
            platformVersion: Version::fromString('0.0.0'),
            engine: EngineType::UNKNOWN,
            engineVersion: Version::fromString('0.0.0'),
            isMobile: false,
            isBot: true,
            isModern: false
        );

        expect($parsed->supports('webp'))->toBeFalse();
        expect($parsed->supports('es2017'))->toBeFalse();
    });

    it('converts to array with Version strings', function () {
        $parsed = new ParsedUserAgent(
            raw: 'Mozilla/5.0',
            browser: BrowserType::FIREFOX,
            browserVersion: Version::fromString('115.0.0'),
            platform: PlatformType::LINUX,
            platformVersion: Version::fromString('5.15.0'),
            engine: EngineType::GECKO,
            engineVersion: Version::fromString('115.0.0'),
            isMobile: false,
            isBot: false,
            isModern: true
        );

        $array = $parsed->toArray();

        expect($array['browser']['version'])->toBe('115.0.0');
        expect($array['platform']['version'])->toBe('5.15.0');
        expect($array['engine']['version'])->toBe('115.0.0');
        expect($array['deviceCategory'])->toBe('desktop');
        expect($array['flags']['isModern'])->toBeTrue();
    });

    it('returns comprehensive summary', function () {
        $parsed = new ParsedUserAgent(
            raw: 'Mozilla/5.0',
            browser: BrowserType::CHROME,
            browserVersion: Version::fromString('120.0.0'),
            platform: PlatformType::ANDROID,
            platformVersion: Version::fromString('13.0.0'),
            engine: EngineType::BLINK,
            engineVersion: Version::fromString('120.0.0'),
            isMobile: true,
            isBot: false,
            isModern: true
        );

        $summary = $parsed->getSummary();

        expect($summary)->toContain('Chrome 120.0.0');
        expect($summary)->toContain('Android 13.0.0');
        expect($summary)->toContain('(Mobile)');
    });
});
