<?php

namespace Mtc\Plugins\BlockManager\Tests\Unit;

use Illuminate\Support\Str;
use Mtc\Plugins\BlockManager\Models\BlockManagerVariantDraft;
use Mtc\Plugins\BlockManager\Services\VariantTwigGenerator;
use Tests\TestCase;

class VariantTwigGeneratorTest extends TestCase
{
    private VariantTwigGenerator $service;

    /** @var string[] */
    private array $createdUuids = [];

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

    protected function tearDown(): void
    {
        if (!empty($this->createdUuids)) {
            BlockManagerVariantDraft::whereIn('uuid', $this->createdUuids)->delete();
        }
        parent::tearDown();
    }

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

    public function test_generates_twig_with_variant_class_for_button(): void
    {
        $slug = 'phase11-tg-' . Str::random(6);
        $draft = $this->seedDraft('button', $slug);

        $output = $this->service->generate($draft);

        $this->assertStringContainsString(
            "bm-button--{$slug}",
            $output,
            "Twig output for a button must include the variant-scoped class 'bm-button--{$slug}'."
        );
    }

    public function test_generates_twig_with_variant_class_for_heading(): void
    {
        $slug = 'phase11-tg-' . Str::random(6);
        $draft = $this->seedDraft('heading', $slug);

        $output = $this->service->generate($draft);

        $this->assertStringContainsString(
            "bm-heading--{$slug}",
            $output,
            "Twig output for a heading must include the variant-scoped class 'bm-heading--{$slug}'."
        );
    }

    public function test_twig_references_each_element_manifest_input(): void
    {
        $draft = $this->seedDraft('button', 'phase11-tg-' . Str::random(6));

        $output = $this->service->generate($draft);

        // Button manifest declares inputs: label, link, target.
        $this->assertStringContainsString(
            '{{ label }}',
            $output,
            "Twig for a button must emit a {{ label }} slot from the manifest input."
        );
        $this->assertMatchesRegularExpression(
            '/\blink(\.|\s*\|)/',
            $output,
            "Twig for a button must reference the link input (e.g. link.url or link|default)."
        );
    }

    private function seedDraft(string $elementType, string $variantSlug): BlockManagerVariantDraft
    {
        $uuid = (string) Str::uuid();
        $this->createdUuids[] = $uuid;

        return BlockManagerVariantDraft::create([
            'uuid'            => $uuid,
            'element_type'    => $elementType,
            'variant_slug'    => $variantSlug,
            'label'           => 'Phase 11 TwigGenerator Probe',
            'properties_json' => null,
        ]);
    }
}
