<?php

namespace Tests\Unit;

use App\Filament\Resources\PageResource\Pages\EditPage;
use PHPUnit\Framework\TestCase;
use ReflectionClass;

class EditPagePreviewNormalizationTest extends TestCase
{
    private function invokePrivate(object $object, string $method, mixed ...$args): mixed
    {
        $reflection = new ReflectionClass($object);
        $privateMethod = $reflection->getMethod($method);
        $privateMethod->setAccessible(true);

        return $privateMethod->invoke($object, ...$args);
    }

    private function makeEditPageInstance(): EditPage
    {
        $reflection = new ReflectionClass(EditPage::class);

        return $reflection->newInstanceWithoutConstructor();
    }

    public function test_category_map_is_not_treated_as_upload_map(): void
    {
        $page = $this->makeEditPageInstance();

        $categoryMap = [
            'd9471fb6-94e2-4004-a26a-a47f48ddc438' => [
                'name' => 'Category A',
                'url' => '#',
                'icon' => 'fas fa-vial',
                'text_position' => 'overlay',
                'overlay_style' => 'gradient',
            ],
        ];

        $isEphemeral = $this->invokePrivate($page, 'isEphemeralFileMap', $categoryMap);

        $this->assertFalse($isEphemeral);
    }

    public function test_upload_map_is_treated_as_upload_map(): void
    {
        $page = $this->makeEditPageInstance();

        $uploadMap = [
            'd9471fb6-94e2-4004-a26a-a47f48ddc438' => [
                'url' => 'http://127.0.0.1:8000/storage/hero/sample.jpg',
                'name' => 'sample.jpg',
                'mime_type' => 'image/jpeg',
                'size' => 12345,
            ],
        ];

        $isEphemeral = $this->invokePrivate($page, 'isEphemeralFileMap', $uploadMap);

        $this->assertTrue($isEphemeral);
    }

    public function test_normalize_preview_data_preserves_category_structure(): void
    {
        $page = $this->makeEditPageInstance();

        $categoryMap = [
            'd9471fb6-94e2-4004-a26a-a47f48ddc438' => [
                'name' => 'Category A',
                'url' => '#',
                'icon' => 'fas fa-vial',
            ],
        ];

        $normalized = $this->invokePrivate($page, 'normalizePreviewData', $categoryMap);

        $this->assertIsArray($normalized);
        $this->assertArrayHasKey('d9471fb6-94e2-4004-a26a-a47f48ddc438', $normalized);
        $this->assertIsArray($normalized['d9471fb6-94e2-4004-a26a-a47f48ddc438']);
        $this->assertSame('Category A', $normalized['d9471fb6-94e2-4004-a26a-a47f48ddc438']['name']);
    }

    public function test_normalize_for_hash_stabilizes_transient_upload_urls(): void
    {
        $page = $this->makeEditPageInstance();

        $normalizedA = $this->invokePrivate($page, 'normalizeForHash', [
            'temporaryUrl' => 'http://127.0.0.1:8000/livewire/preview-file/abc123?expires=111&signature=one',
        ]);

        $normalizedB = $this->invokePrivate($page, 'normalizeForHash', [
            'temporaryUrl' => 'http://127.0.0.1:8000/livewire/preview-file/abc123?expires=222&signature=two',
        ]);

        $this->assertSame('tmp-upload', $normalizedA);
        $this->assertSame('tmp-upload', $normalizedB);
    }

    public function test_contains_transient_upload_detects_livewire_temporary_paths(): void
    {
        $page = $this->makeEditPageInstance();

        $hasTransient = $this->invokePrivate($page, 'containsTransientUpload', [
            'background_image' => 'http://127.0.0.1:8000/livewire/preview-file/xyz456?expires=333',
        ]);

        $this->assertTrue($hasTransient);
    }
}
