<?php

namespace Mtc\Plugins\BlockManager\Tests\Unit;

use Mtc\Plugins\BlockManager\Services\ElementCatalogueService;
use Tests\TestCase;

class ElementCatalogueServiceTest extends TestCase
{
    private ElementCatalogueService $service;

    protected function setUp(): void
    {
        parent::setUp();
        $this->service = app(ElementCatalogueService::class);
    }

    public function test_service_is_resolvable_from_container(): void
    {
        $this->assertInstanceOf(ElementCatalogueService::class, $this->service);
    }

    public function test_list_returns_all_starter_elements(): void
    {
        $elements = $this->service->list();

        $this->assertIsArray($elements);

        $types = array_map(fn ($e) => $e['type'], $elements);
        foreach (['heading', 'paragraph', 'button'] as $expected) {
            $this->assertContains(
                $expected,
                $types,
                "ElementCatalogueService::list() did not include '{$expected}'."
            );
        }
    }

    public function test_list_includes_phase17_html_primitives(): void
    {
        $types = array_map(fn ($e) => $e['type'], $this->service->list());

        foreach (['link', 'details', 'table', 'hr', 'image'] as $expected) {
            $this->assertContains(
                $expected,
                $types,
                "Phase 17 expanded the catalogue to include '{$expected}'. Drop plugins/BlockManager/elements/{$expected}/."
            );
        }
    }

    public function test_phase17_link_element_carries_expected_inputs(): void
    {
        $link = $this->service->get('link');

        $this->assertNotNull($link, "Phase 17 element 'link' must be present in the catalogue.");
        $inputNames = array_column($link['inputs'], 'name');
        foreach (['text', 'link', 'target'] as $required) {
            $this->assertContains(
                $required,
                $inputNames,
                "Element 'link' must declare a '{$required}' input."
            );
        }
    }

    public function test_list_elements_have_required_keys(): void
    {
        foreach ($this->service->list() as $element) {
            foreach (['type', 'label', 'category', 'icon', 'inputs', 'variants', 'default_variant'] as $key) {
                $this->assertArrayHasKey(
                    $key,
                    $element,
                    "Element '{$element['type']}' returned by list() is missing key '{$key}'."
                );
            }
        }
    }

    public function test_get_returns_manifest_for_known_type(): void
    {
        $heading = $this->service->get('heading');

        $this->assertNotNull($heading);
        $this->assertSame('heading', $heading['type']);
        $this->assertIsArray($heading['inputs']);
        $this->assertIsArray($heading['variants']);
    }

    public function test_get_returns_null_for_unknown_type(): void
    {
        $this->assertNull($this->service->get('does-not-exist-element-' . uniqid()));
    }

    public function test_variants_returns_variant_list_for_known_type(): void
    {
        $variants = $this->service->variants('button');

        $this->assertIsArray($variants);
        $this->assertGreaterThanOrEqual(2, count($variants));

        foreach ($variants as $variant) {
            $this->assertArrayHasKey('id', $variant);
            $this->assertArrayHasKey('label', $variant);
        }
    }

    public function test_variants_returns_empty_array_for_unknown_type(): void
    {
        $this->assertSame([], $this->service->variants('not-a-real-element-' . uniqid()));
    }
}
