<?php

namespace Mtc\Plugins\BlockManager\Tests\Feature;

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

class VariantDraftCrudApiTest extends TestCase
{
    /** @var string[] */
    private array $createdUuids = [];

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

    public function test_index_returns_data_envelope(): void
    {
        $response = $this->getJson('/api/block-manager/variants');
        $response->assertStatus(200);
        $response->assertJsonStructure(['data']);
        $this->assertIsArray($response->json('data'));
    }

    public function test_index_lists_existing_drafts(): void
    {
        $a = $this->seedDraft('button', 'phase8-list-a-' . Str::random(6));
        $b = $this->seedDraft('heading', 'phase8-list-b-' . Str::random(6));

        $data = $this->getJson('/api/block-manager/variants')->json('data');
        $slugs = array_column($data, 'variant_slug');

        $this->assertContains($a->variant_slug, $slugs);
        $this->assertContains($b->variant_slug, $slugs);
    }

    public function test_index_filters_by_element_type(): void
    {
        $btn = $this->seedDraft('button',  'phase17-filter-btn-' . Str::random(6));
        $hd  = $this->seedDraft('heading', 'phase17-filter-hd-'  . Str::random(6));

        $data = $this->getJson('/api/block-manager/variants?element_type=button')->json('data');
        $types = array_unique(array_column($data, 'element_type'));
        $slugs = array_column($data, 'variant_slug');

        $this->assertSame(
            ['button'],
            array_values($types),
            "?element_type=button must narrow the index to button drafts only."
        );
        $this->assertContains($btn->variant_slug, $slugs);
        $this->assertNotContains(
            $hd->variant_slug,
            $slugs,
            "Heading drafts must NOT appear when filtering by element_type=button."
        );
    }

    public function test_show_returns_draft_payload(): void
    {
        $draft = $this->seedDraft('button', 'phase8-show-' . Str::random(6));

        $response = $this->getJson("/api/block-manager/variants/{$draft->id}");
        $response->assertStatus(200);
        $payload = $response->json('data');

        $this->assertSame($draft->id, $payload['id']);
        $this->assertSame('button', $payload['element_type']);
        $this->assertSame($draft->variant_slug, $payload['variant_slug']);
        $this->assertIsArray($payload['properties_json'] ?? null);
    }

    public function test_show_returns_404_for_unknown_id(): void
    {
        $this->getJson('/api/block-manager/variants/99999999')->assertStatus(404);
    }

    public function test_store_creates_draft_with_minimal_payload(): void
    {
        $slug = 'phase8-create-' . Str::random(8);

        $response = $this->postJson('/api/block-manager/variants', [
            'element_type' => 'button',
            'variant_slug' => $slug,
            'label'        => 'Phase 8 Create',
        ]);
        $response->assertStatus(201);

        $payload = $response->json('data');
        $this->assertNotEmpty($payload['uuid']);
        $this->assertSame('button', $payload['element_type']);
        $this->assertSame($slug, $payload['variant_slug']);
        $this->createdUuids[] = $payload['uuid'];

        $this->assertNotNull(BlockManagerVariantDraft::where('uuid', $payload['uuid'])->first());
    }

    public function test_store_persists_properties_json_round_trip(): void
    {
        $slug = 'phase8-props-' . Str::random(8);
        $properties = [
            'element_type' => 'button',
            'variant_slug' => $slug,
            'base' => [
                'default' => [
                    'desktop' => [
                        'background' => ['color' => ['token' => '@primary_color']],
                        'box'        => ['padding_x' => ['raw' => '12px']],
                    ],
                ],
                'hover'   => ['desktop' => ['background' => ['color' => ['token' => '@secondary_color']]]],
                'focus'   => [],
                'active'  => [],
                'disabled' => [],
            ],
        ];

        $response = $this->postJson('/api/block-manager/variants', [
            'element_type'    => 'button',
            'variant_slug'    => $slug,
            'label'           => 'Phase 8 Round-trip',
            'properties_json' => $properties,
        ]);
        $response->assertStatus(201);
        $this->createdUuids[] = $response->json('data.uuid');

        $payload = $response->json('data');
        $this->assertSame(
            '@primary_color',
            $payload['properties_json']['base']['default']['desktop']['background']['color']['token']
        );

        $fresh = BlockManagerVariantDraft::where('uuid', $payload['uuid'])->firstOrFail();
        $this->assertSame(
            '@primary_color',
            $fresh->properties_json['base']['default']['desktop']['background']['color']['token']
        );
    }

    public function test_store_validates_required_fields(): void
    {
        $this->postJson('/api/block-manager/variants', [])->assertStatus(422);

        $this->postJson('/api/block-manager/variants', [
            'variant_slug' => 'phase8-noelement',
        ])->assertStatus(422);

        $this->postJson('/api/block-manager/variants', [
            'element_type' => 'button',
        ])->assertStatus(422);
    }

    public function test_store_validates_element_type_is_a_known_element(): void
    {
        $response = $this->postJson('/api/block-manager/variants', [
            'element_type' => 'pizza',
            'variant_slug' => 'phase8-bogus-' . Str::random(6),
            'label'        => 'Phase 8 Bogus',
        ]);
        $response->assertStatus(422);
    }

    public function test_store_rejects_duplicate_element_variant_pair(): void
    {
        $slug = 'phase8-dup-' . Str::random(6);

        $first = $this->postJson('/api/block-manager/variants', [
            'element_type' => 'button',
            'variant_slug' => $slug,
            'label'        => 'Phase 8 Dup A',
        ]);
        $first->assertStatus(201);
        $this->createdUuids[] = $first->json('data.uuid');

        // Same pair → reject
        $second = $this->postJson('/api/block-manager/variants', [
            'element_type' => 'button',
            'variant_slug' => $slug,
            'label'        => 'Phase 8 Dup B',
        ]);
        $second->assertStatus(422);

        // Same slug under a different element → allowed
        $third = $this->postJson('/api/block-manager/variants', [
            'element_type' => 'heading',
            'variant_slug' => $slug,
            'label'        => 'Phase 8 Cross-element',
        ]);
        $third->assertStatus(201);
        $this->createdUuids[] = $third->json('data.uuid');
    }

    public function test_update_modifies_draft(): void
    {
        $draft = $this->seedDraft('button', 'phase8-update-' . Str::random(6));

        $response = $this->putJson("/api/block-manager/variants/{$draft->id}", [
            'label'           => 'Phase 8 Updated Label',
            'properties_json' => ['base' => ['default' => ['desktop' => ['background' => ['color' => ['raw' => '#abcdef']]]]]],
        ]);
        $response->assertStatus(200);

        $fresh = BlockManagerVariantDraft::find($draft->id);
        $this->assertSame('Phase 8 Updated Label', $fresh->label);
        $this->assertSame('#abcdef', $fresh->properties_json['base']['default']['desktop']['background']['color']['raw']);
    }

    public function test_update_returns_404_for_unknown_id(): void
    {
        $this->putJson('/api/block-manager/variants/99999999', ['label' => 'nope'])->assertStatus(404);
    }

    public function test_destroy_removes_draft(): void
    {
        $draft = $this->seedDraft('button', 'phase8-destroy-' . Str::random(6));
        $id = $draft->id;

        $this->deleteJson("/api/block-manager/variants/{$id}")->assertStatus(204);
        $this->assertNull(BlockManagerVariantDraft::find($id));

        $this->createdUuids = array_filter($this->createdUuids, fn ($u) => $u !== $draft->uuid);
    }

    public function test_destroy_returns_404_for_unknown_id(): void
    {
        $this->deleteJson('/api/block-manager/variants/99999999')->assertStatus(404);
    }

    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 8 Seed',
            'properties_json' => ['base' => ['default' => ['desktop' => []]]],
        ]);
    }
}
