<?php

namespace Tests\Feature;

use App\Services\ContentMigrationProcessor;
use Tests\DatabaseTestCase;

class ContentMigrationBlocksTest extends DatabaseTestCase
{
    private ContentMigrationProcessor $processor;

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

    public function testBuildsBlocksSkeletonAlignedWithOfferStructure()
    {
        $structure = $this->processor->buildOfferFieldStructure();
        $blocks = $this->processor->buildBlocksSkeleton($structure);

        $this->assertCount(count($structure), $blocks);

        $offerFields = $blocks[0];
        $this->assertSame('Offer fields', $offerFields['name']);
        $this->assertTrue($offerFields['isGroup']);
        $this->assertSame('group', $offerFields['fieldId']);
        // Sentinel keeps top-level blocks undeletable in the edit panel.
        $this->assertTrue($offerFields['template_element_id']);
        $this->assertFalse($offerFields['repeatable']);
        $this->assertFalse($offerFields['editable']);
        $this->assertCount(count($structure[0]['fields']), $offerFields['children']);
    }

    public function testFieldBlocksCarryEditorComponentNames()
    {
        $structure = $this->processor->buildOfferFieldStructure();
        $blocks = $this->processor->buildBlocksSkeleton($structure);

        $children = collect($blocks[0]['children']);

        $nameBlock = $children->firstWhere('slug', 'name');
        $this->assertSame('TextField', $nameBlock['componentName']);
        $this->assertSame('EditableContentTextField', $nameBlock['component']);
        $this->assertSame('text', $nameBlock['field_type']);
        $this->assertTrue($nameBlock['required']);

        $descriptionBlock = $children->firstWhere('slug', 'description');
        $this->assertSame('Editor', $descriptionBlock['componentName']);

        $priceBlock = $children->firstWhere('slug', 'price');
        $this->assertSame('NumberField', $priceBlock['componentName']);
    }

    public function testImageFieldBlockCarriesMaxCountOption()
    {
        $structure = $this->processor->buildOfferFieldStructure();
        $blocks = $this->processor->buildBlocksSkeleton($structure);

        $thumbnail = collect($blocks[0]['children'])->firstWhere('slug', 'thumbnail');

        $this->assertSame('image', $thumbnail['field_type']);
        $this->assertSame(1, $thumbnail['meta']['options']['maxCount']);
        $this->assertSame([], $thumbnail['meta']['selected']);
    }

    public function testRepeatableElementGetsSingleItemPrototype()
    {
        $structure = [
            [
                'name' => 'Cards',
                'repeatable' => true,
                'nestedLimit' => 4,
                'fields' => [
                    ['slug' => 'title', 'name' => 'Title', 'type' => 'text', 'repeatable' => false],
                    [
                        'slug' => 'links',
                        'name' => 'Links',
                        'type' => 'text',
                        'repeatable' => true,
                        'children' => [
                            ['slug' => 'label', 'name' => 'Label', 'type' => 'text', 'repeatable' => false],
                        ],
                    ],
                ],
            ],
        ];

        $blocks = $this->processor->buildBlocksSkeleton($structure);
        $element = $blocks[0];

        $this->assertTrue($element['repeatable']);
        $this->assertSame(4, $element['nestedLimit']);
        // Repeatable elements ship ONE prototype the frontend clones per item.
        $this->assertCount(1, $element['children']);

        $prototype = $element['children'][0];
        $this->assertTrue($prototype['isGroup']);
        $this->assertStringEndsWith('__item', $prototype['slug']);
        $this->assertCount(2, $prototype['children']);

        // Nested repeatable field becomes a group container with its own prototype.
        $nested = collect($prototype['children'])->firstWhere('name', 'Links');
        $this->assertTrue($nested['repeatable']);
        $this->assertTrue($nested['isGroup']);
        $this->assertCount(1, $nested['children']);
        $this->assertSame('links__item', $nested['children'][0]['slug']);
        $this->assertSame('label', $nested['children'][0]['children'][0]['slug']);
    }

    public function testNestedLimitIsNeverFalse()
    {
        // DraggableContentList compares children.length >= nestedLimit and a
        // boolean false coerces to 0, which would disable "Add another".
        $structure = [
            [
                'name' => 'Cards',
                'repeatable' => true,
                'fields' => [
                    ['slug' => 'title', 'name' => 'Title', 'type' => 'text', 'repeatable' => false],
                ],
            ],
        ];

        $blocks = $this->processor->buildBlocksSkeleton($structure);

        $this->assertNull($blocks[0]['nestedLimit']);
    }

    public function testUnknownFieldTypeFallsBackToComponentNotFound()
    {
        $structure = [
            [
                'name' => 'Odd',
                'fields' => [
                    ['slug' => 'mystery', 'name' => 'Mystery', 'type' => 'not-a-real-type', 'repeatable' => false],
                ],
            ],
        ];

        $blocks = $this->processor->buildBlocksSkeleton($structure);
        $field = $blocks[0]['children'][0];

        $this->assertSame('ComponentNotFound', $field['componentName']);
        $this->assertSame('EditableContentComponentNotFound', $field['component']);
    }

    public function testNewCarStructureBlocksAlign()
    {
        $structure = $this->processor->buildNewCarFieldStructure();
        $blocks = $this->processor->buildBlocksSkeleton($structure);

        $this->assertCount(1, $blocks);
        $this->assertSame('New car images', $blocks[0]['name']);
        $hero = collect($blocks[0]['children'])->firstWhere('slug', 'hero_image');
        $this->assertSame(1, $hero['meta']['options']['maxCount']);
    }
}
