<?php

namespace App\Tests\Entity;

use App\Entity\AnalyticsEvent;
use App\Entity\AnalyticsUniqId;
use App\Entity\User;
use PHPUnit\Framework\TestCase;

class AnalyticsTest extends TestCase
{
    // --- AnalyticsUniqId ---

    public function testUniqIdConstructor(): void
    {
        $v = new AnalyticsUniqId();
        $this->assertNull($v->getId());
        $this->assertInstanceOf(\DateTimeImmutable::class, $v->getCreatedAt());
        $this->assertCount(0, $v->getEvents());
    }

    public function testUniqIdSettersFluentAndGetters(): void
    {
        $v = new AnalyticsUniqId();

        $this->assertSame($v, $v->setUid('uid-123'));
        $this->assertSame('uid-123', $v->getUid());

        $this->assertSame($v, $v->setHash('hash-abc'));
        $this->assertSame('hash-abc', $v->getHash());

        $this->assertSame($v, $v->setIpHash('ip-hash'));
        $this->assertSame('ip-hash', $v->getIpHash());

        $this->assertSame($v, $v->setUserAgent('Mozilla/5.0'));
        $this->assertSame('Mozilla/5.0', $v->getUserAgent());

        $this->assertSame($v, $v->setDeviceType('mobile'));
        $this->assertSame('mobile', $v->getDeviceType());

        $this->assertSame($v, $v->setScreenWidth(1920));
        $this->assertSame(1920, $v->getScreenWidth());

        $this->assertSame($v, $v->setScreenHeight(1080));
        $this->assertSame(1080, $v->getScreenHeight());

        $this->assertSame($v, $v->setLanguage('fr'));
        $this->assertSame('fr', $v->getLanguage());

        $this->assertSame($v, $v->setOs('Linux'));
        $this->assertSame('Linux', $v->getOs());

        $this->assertSame($v, $v->setBrowser('Firefox'));
        $this->assertSame('Firefox', $v->getBrowser());
    }

    public function testUniqIdUser(): void
    {
        $v = new AnalyticsUniqId();
        $this->assertNull($v->getUser());

        $user = new User();
        $user->setEmail('u@t.com');
        $user->setFirstName('U');
        $user->setLastName('T');
        $user->setPassword('h');

        $this->assertSame($v, $v->setUser($user));
        $this->assertSame($user, $v->getUser());

        $this->assertSame($v, $v->setUser(null));
        $this->assertNull($v->getUser());
    }

    // --- AnalyticsUniqId static parsers ---

    public function testParseDeviceTypeDesktop(): void
    {
        $this->assertSame('desktop', AnalyticsUniqId::parseDeviceType('Mozilla/5.0 (Windows NT 10.0; Win64; x64)'));
    }

    public function testParseDeviceTypeMobile(): void
    {
        $this->assertSame('mobile', AnalyticsUniqId::parseDeviceType('Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X)'));
        $this->assertSame('mobile', AnalyticsUniqId::parseDeviceType('Mozilla/5.0 (Linux; Android 12; Pixel 6) Mobile'));
    }

    public function testParseDeviceTypeTablet(): void
    {
        $this->assertSame('tablet', AnalyticsUniqId::parseDeviceType('Mozilla/5.0 (iPad; CPU OS 15_0 like Mac OS X)'));
    }

    public function testParseOsWindows(): void
    {
        $this->assertSame('Windows', AnalyticsUniqId::parseOs('Mozilla/5.0 (Windows NT 10.0; Win64; x64)'));
    }

    public function testParseOsMac(): void
    {
        $this->assertSame('macOS', AnalyticsUniqId::parseOs('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)'));
    }

    public function testParseOsIos(): void
    {
        $this->assertSame('iOS', AnalyticsUniqId::parseOs('Mozilla/5.0 (iPhone; CPU iPhone OS 15_0)'));
    }

    public function testParseOsAndroid(): void
    {
        $this->assertSame('Android', AnalyticsUniqId::parseOs('Mozilla/5.0 (Linux; Android 12; Pixel 6)'));
    }

    public function testParseOsLinux(): void
    {
        $this->assertSame('Linux', AnalyticsUniqId::parseOs('Mozilla/5.0 (X11; Linux x86_64)'));
    }

    public function testParseOsUnknown(): void
    {
        $this->assertNull(AnalyticsUniqId::parseOs('some-random-bot'));
    }

    public function testParseBrowserChrome(): void
    {
        $this->assertSame('Chrome', AnalyticsUniqId::parseBrowser('Mozilla/5.0 Chrome/120.0.0.0 Safari/537.36'));
    }

    public function testParseBrowserFirefox(): void
    {
        $this->assertSame('Firefox', AnalyticsUniqId::parseBrowser('Mozilla/5.0 Firefox/121.0'));
    }

    public function testParseBrowserEdge(): void
    {
        $this->assertSame('Edge', AnalyticsUniqId::parseBrowser('Mozilla/5.0 Chrome/120.0 Edg/120.0'));
    }

    public function testParseBrowserSafari(): void
    {
        $this->assertSame('Safari', AnalyticsUniqId::parseBrowser('Mozilla/5.0 (Macintosh) AppleWebKit/605.1.15 Safari/605.1.15'));
    }

    public function testParseBrowserOpera(): void
    {
        $this->assertSame('Opera', AnalyticsUniqId::parseBrowser('Mozilla/5.0 OPR/106.0.0.0'));
    }

    public function testParseBrowserUnknown(): void
    {
        $this->assertNull(AnalyticsUniqId::parseBrowser('some-random-bot'));
    }

    // --- AnalyticsEvent ---

    public function testEventConstructor(): void
    {
        $e = new AnalyticsEvent();
        $this->assertNull($e->getId());
        $this->assertInstanceOf(\DateTimeImmutable::class, $e->getCreatedAt());
    }

    public function testEventSetters(): void
    {
        $v = new AnalyticsUniqId();
        $e = new AnalyticsEvent();
        $e->setVisitor($v);
        $e->setEventName('pageview');
        $e->setUrl('/home');
        $e->setTitle('Accueil');
        $e->setReferrer('https://google.com');

        $this->assertSame($v, $e->getVisitor());
        $this->assertSame('pageview', $e->getEventName());
        $this->assertSame('/home', $e->getUrl());
        $this->assertSame('Accueil', $e->getTitle());
        $this->assertSame('https://google.com', $e->getReferrer());
    }

    public function testEventNullables(): void
    {
        $e = new AnalyticsEvent();
        $this->assertNull($e->getTitle());
        $this->assertNull($e->getReferrer());
    }
}
