<?php

namespace Mtc\Plugins\BlockManager\Tests\Unit;

use Illuminate\Support\Str;
use Mtc\Plugins\BlockManager\Models\BlockManagerBlock;
use Mtc\Plugins\BlockManager\Services\TwigGenerator;
use Tests\TestCase;

/**
 * Container nesting in the shipped Twig template: a container emits a wrapper
 * <div class="bm-container bm-ci-…"> around its children's includes, and nested
 * children's inputs still register as BlockRegistry fields.
 */
class TwigGeneratorContainerTest extends TestCase
{
    private TwigGenerator $generator;

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

    public function test_container_wraps_children_in_scoped_div(): void
    {
        $block = $this->makeBlock([
            [
                'instance_id'  => 'ctr-1',
                'element_type' => 'container',
                'variant'      => 'default',
                'children'     => [
                    ['instance_id' => 'h-1', 'element_type' => 'heading', 'variant' => 'default', 'field_name' => 'title'],
                    ['instance_id' => 'b-1', 'element_type' => 'button',  'variant' => 'primary', 'field_name' => 'cta'],
                ],
            ],
        ]);

        $output = $this->generator->generate($block);

        $this->assertStringContainsString('<div class="bm-container bm-ci-ctr-1">', $output);
        $this->assertStringContainsString('</div>', $output);
        $this->assertStringContainsString('heading/variants/default.twig', $output);
        $this->assertStringContainsString('button/variants/primary.twig', $output);

        // Child includes must sit between the wrapper open and close.
        $open  = strpos($output, '<div class="bm-container bm-ci-ctr-1">');
        $close = strrpos($output, '</div>');
        $heading = strpos($output, 'heading/variants/default.twig');
        $this->assertGreaterThan($open, $heading);
        $this->assertLessThan($close, $heading);
    }

    public function test_nested_children_inputs_register_as_fields(): void
    {
        $block = $this->makeBlock([
            [
                'instance_id'  => 'ctr-1',
                'element_type' => 'container',
                'variant'      => 'default',
                'children'     => [
                    ['instance_id' => 'h-1', 'element_type' => 'heading', 'variant' => 'default', 'field_name' => 'title'],
                ],
            ],
        ]);

        $fields = $this->generator->deriveFields($block);
        $names = array_column($fields, 'name');

        // Heading declares 'text' + 'level'; with field_name 'title' they map to
        // title_text / title_level. The container itself contributes nothing.
        $this->assertNotEmpty($fields, 'Nested child inputs must become BlockRegistry fields.');
        $this->assertTrue(
            (bool) array_filter($names, fn ($n) => str_contains($n, 'text')),
            'Expected a field derived from the nested heading text input.'
        );
    }

    /**
     * @param array<int, array<string, mixed>> $elements
     */
    private function makeBlock(array $elements): BlockManagerBlock
    {
        $block = new BlockManagerBlock([
            'uuid'           => (string) Str::uuid(),
            'slug'           => 'twiggen-ctr-' . Str::random(6),
            'name'           => 'TwigGenerator container probe',
            'structure_json' => ['elements' => $elements],
        ]);
        $block->setRawAttributes($block->getAttributes(), true);
        $block->setAttribute('structure_json', ['elements' => $elements]);

        return $block;
    }
}
