<?php

namespace Mtc\Plugins\BlockManager\Tests\Unit;

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

class PropertySchemaServiceTest extends TestCase
{
    private PropertySchemaService $service;

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

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

    public function test_panels_includes_phase9_baseline_set(): void
    {
        $panels = $this->service->panels();

        $this->assertIsArray($panels);
        $this->assertNotEmpty($panels, 'Schema must return at least one panel.');

        $ids = array_map(fn ($p) => $p['id'] ?? null, $panels);
        foreach (['typography', 'box', 'border', 'background'] as $required) {
            $this->assertContains(
                $required,
                $ids,
                "Phase 9 requires the '{$required}' panel to be present."
            );
        }
    }

    public function test_each_panel_has_id_label_and_properties_list(): void
    {
        foreach ($this->service->panels() as $panel) {
            foreach (['id', 'label', 'properties'] as $key) {
                $this->assertArrayHasKey($key, $panel, "Panel missing '{$key}'.");
            }
            $this->assertIsArray($panel['properties']);
            $this->assertNotEmpty(
                $panel['properties'],
                "Panel '{$panel['id']}' must declare at least one property."
            );
        }
    }

    public function test_each_property_has_name_label_input_and_token_types(): void
    {
        foreach ($this->service->panels() as $panel) {
            foreach ($panel['properties'] as $property) {
                foreach (['name', 'label', 'input', 'token_types'] as $key) {
                    $this->assertArrayHasKey(
                        $key,
                        $property,
                        "Property in panel '{$panel['id']}' missing key '{$key}'."
                    );
                }
                $this->assertIsArray(
                    $property['token_types'],
                    "Property '{$property['name']}' in panel '{$panel['id']}' must declare token_types as an array."
                );
            }
        }
    }

    public function test_anchor_properties_per_panel(): void
    {
        $byId = [];
        foreach ($this->service->panels() as $panel) {
            $byId[$panel['id']] = $panel;
        }

        // Typography → has `color` accepting `color` tokens
        $typography = $this->findProperty($byId['typography'] ?? null, 'color');
        $this->assertNotNull($typography, "Typography panel must include a 'color' property.");
        $this->assertContains('color', $typography['token_types'] ?? [], "Typography 'color' must accept color tokens.");

        // Box → has a property whose name contains "padding"
        $boxProps = $byId['box']['properties'] ?? [];
        $paddingProp = null;
        foreach ($boxProps as $p) {
            if (str_contains((string) ($p['name'] ?? ''), 'padding')) {
                $paddingProp = $p;
                break;
            }
        }
        $this->assertNotNull($paddingProp, "Box panel must include a padding-* property.");

        // Border → has a property whose name contains "radius"
        $borderProps = $byId['border']['properties'] ?? [];
        $radiusProp = null;
        foreach ($borderProps as $p) {
            if (str_contains((string) ($p['name'] ?? ''), 'radius')) {
                $radiusProp = $p;
                break;
            }
        }
        $this->assertNotNull($radiusProp, "Border panel must include a *radius* property.");

        // Background → has `color` accepting `color` tokens
        $bgColor = $this->findProperty($byId['background'] ?? null, 'color');
        $this->assertNotNull($bgColor, "Background panel must include a 'color' property.");
        $this->assertContains('color', $bgColor['token_types'] ?? [], "Background 'color' must accept color tokens.");
    }

    private function findProperty(?array $panel, string $name): ?array
    {
        if (!is_array($panel) || empty($panel['properties'])) {
            return null;
        }
        foreach ($panel['properties'] as $property) {
            if (($property['name'] ?? null) === $name) {
                return $property;
            }
        }
        return null;
    }
}
