<?php

declare(strict_types=1);

namespace App\Tests\Unit\Administration\Domain\Model\Session;

use App\Administration\Domain\Model\Session\Location;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

final class LocationTest extends TestCase
{
    #[Test]
    public function fromIpCreatesLocationWithCountryAndCity(): void
    {
        $location = Location::fromIp('192.168.1.1', 'France', 'Paris');

        self::assertSame('France', $location->country);
        self::assertSame('Paris', $location->city);
        self::assertSame('192.168.1.1', $location->ip);
    }

    #[Test]
    public function fromIpCreatesLocationWithCountryOnly(): void
    {
        $location = Location::fromIp('10.0.0.1', 'Germany', null);

        self::assertSame('Germany', $location->country);
        self::assertNull($location->city);
    }

    #[Test]
    public function unknownCreatesUnknownLocation(): void
    {
        $location = Location::unknown();

        self::assertNull($location->country);
        self::assertNull($location->city);
        self::assertNull($location->ip);
    }

    #[Test]
    public function formatReturnsCountryAndCity(): void
    {
        $location = Location::fromIp('192.168.1.1', 'France', 'Paris');

        self::assertSame('France, Paris', $location->format());
    }

    #[Test]
    public function formatReturnsCountryOnlyWhenNoCityAvailable(): void
    {
        $location = Location::fromIp('10.0.0.1', 'Germany', null);

        self::assertSame('Germany', $location->format());
    }

    #[Test]
    public function formatReturnsInconnuWhenUnknown(): void
    {
        $location = Location::unknown();

        self::assertSame('Inconnu', $location->format());
    }

    #[Test]
    public function formatReturnsInconnuForPrivateIpRanges(): void
    {
        $location = Location::fromIp('192.168.1.1', null, null);

        self::assertSame('Inconnu', $location->format());
    }

    #[Test]
    public function reconstituteRestoresFromStorage(): void
    {
        $location = Location::reconstitute(
            ip: '8.8.8.8',
            country: 'United States',
            city: 'Mountain View',
        );

        self::assertSame('8.8.8.8', $location->ip);
        self::assertSame('United States', $location->country);
        self::assertSame('Mountain View', $location->city);
    }
}
