<?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;

class TwigGeneratorFieldsPanelTest extends TestCase
{
    private TwigGenerator $generator;

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

    public function test_generator_emits_renamed_field_bindings(): void
    {
        $block = $this->makeBlock([
            'elements' => [
                ['instance_id' => 'el-1', 'element_type' => 'heading', 'variant' => 'default', 'field_name' => 'title'],
            ],
            'fields_panel' => [
                'renames' => ['title_text' => 'title'],
            ],
        ]);

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

        $this->assertStringContainsString('fields.title', $output, "Generator must emit renamed 'fields.title'.");
        $this->assertStringNotContainsString('fields.title_text', $output, "Generator must drop the auto-derived 'fields.title_text'.");
    }

    public function test_deriveFields_returns_renamed_names(): void
    {
        $block = $this->makeBlock([
            'elements' => [
                ['instance_id' => 'el-1', 'element_type' => 'heading', 'variant' => 'default', 'field_name' => 'title'],
            ],
            'fields_panel' => [
                'renames' => ['title_text' => 'title'],
            ],
        ]);

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

        $this->assertContains('title', $names, "deriveFields() must reflect rename to 'title'.");
        $this->assertNotContains('title_text', $names, "deriveFields() must replace 'title_text' with the rename.");
    }

    public function test_deriveFields_appends_custom_fields(): void
    {
        $block = $this->makeBlock([
            'elements' => [
                ['instance_id' => 'el-1', 'element_type' => 'heading', 'variant' => 'default', 'field_name' => 'title'],
            ],
            'fields_panel' => [
                'custom' => [
                    ['name' => 'show_section', 'label' => 'Show section', 'type' => 'checkbox', 'required' => false],
                ],
            ],
        ]);

        $fields = $this->generator->deriveFields($block);
        $byName = [];
        foreach ($fields as $f) {
            $byName[$f['name']] = $f;
        }

        $this->assertArrayHasKey('show_section', $byName, "Custom field 'show_section' should be present.");
        $this->assertSame('checkbox', $byName['show_section']['type']);
    }

    public function test_generator_wraps_repeater_group_with_for_loop(): void
    {
        $block = $this->makeBlock([
            'elements' => [
                ['instance_id' => 'el-1', 'element_type' => 'paragraph', 'variant' => 'default', 'field_name' => 'slide_a'],
                ['instance_id' => 'el-2', 'element_type' => 'paragraph', 'variant' => 'default', 'field_name' => 'slide_b'],
            ],
            'fields_panel' => [
                'repeaters' => [
                    ['name' => 'slides', 'instance_ids' => ['el-1', 'el-2'], 'singular' => 'slide'],
                ],
            ],
        ]);

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

        $this->assertMatchesRegularExpression(
            '/\{%\s*for\s+slide\s+in\s+slides\s*%\}/',
            $output,
            "Generator must open {% for slide in slides %}."
        );
        $this->assertStringContainsString('{% endfor %}', $output, "Generator must close the loop with {% endfor %}.");
        $this->assertStringContainsString('slide.text', $output, "Bindings inside the loop must use the singular: 'slide.text'.");
        $this->assertStringNotContainsString('fields.slide_a_text', $output, "Grouped instances must not bind at the top-level 'fields.*' scope.");
    }

    // ---- helper ----

    /**
     * @param array{elements: array, fields_panel?: array} $structure
     */
    private function makeBlock(array $structure): BlockManagerBlock
    {
        $block = new BlockManagerBlock([
            'uuid'           => (string) Str::uuid(),
            'slug'           => 'twiggen-panel-' . Str::random(6),
            'name'           => 'TwigGenerator panel probe',
            'structure_json' => $structure,
        ]);

        $block->setRawAttributes($block->getAttributes(), true);
        $block->setAttribute('structure_json', $structure);

        return $block;
    }
}
