<?php

namespace Mtc\Plugins\BlockManager\Tests\Feature;

use Illuminate\Support\Str;
use Mtc\Modules\BlockRegistry\Models\BlockRegistry;
use Mtc\Plugins\BlockManager\Models\BlockManagerBlock;
use Tests\TestCase;

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

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

    protected function tearDown(): void
    {
        $twigDir = base_path('sites/default/templates/includes/page_blocks');
        $jsonDir = base_path('modules/BlockRegistry/blocks');

        foreach ($this->shippedSlugs as $slug) {
            @unlink($twigDir . "/{$slug}.twig");
            @unlink($jsonDir . "/{$slug}.json");
            BlockRegistry::where('slug', $slug)->delete();
        }
        if (!empty($this->createdUuids)) {
            BlockManagerBlock::whereIn('uuid', $this->createdUuids)->delete();
        }
        parent::tearDown();
    }

    public function test_update_allows_slug_change_before_ship(): void
    {
        $block = $this->seedBlock();
        $newSlug = 'phase6-newslug-' . Str::random(6);

        $response = $this->putJson("/api/block-manager/{$block->id}", ['slug' => $newSlug]);
        $response->assertStatus(200);

        $fresh = BlockManagerBlock::find($block->id);
        $this->assertSame($newSlug, $fresh->slug);
    }

    public function test_update_blocks_slug_change_after_ship(): void
    {
        $block = $this->seedShipableBlock();
        $this->postJson("/api/block-manager/{$block->id}/ship")->assertStatus(200);
        $this->shippedSlugs[] = $block->slug;

        $originalSlug = $block->slug;
        $response = $this->putJson("/api/block-manager/{$block->id}", [
            'slug' => 'phase6-attempt-rename-' . Str::random(6),
        ]);
        $response->assertStatus(422);

        $fresh = BlockManagerBlock::find($block->id);
        $this->assertSame(
            $originalSlug,
            $fresh->slug,
            "Slug must not change once the block has been shipped."
        );
    }

    public function test_update_allows_name_and_structure_changes_after_ship(): void
    {
        $block = $this->seedShipableBlock();
        $this->postJson("/api/block-manager/{$block->id}/ship")->assertStatus(200);
        $this->shippedSlugs[] = $block->slug;

        $response = $this->putJson("/api/block-manager/{$block->id}", [
            'name'           => 'Renamed After Ship',
            'description'    => 'changed',
            'structure_json' => ['elements' => [
                ['instance_id' => 'el-x', 'element_type' => 'paragraph', 'variant' => 'default', 'field_name' => 'body'],
            ]],
        ]);
        $response->assertStatus(200);

        $fresh = BlockManagerBlock::find($block->id);
        $this->assertSame('Renamed After Ship', $fresh->name);
        $this->assertSame('changed', $fresh->description);
        $this->assertSame('paragraph', $fresh->structure_json['elements'][0]['element_type']);
    }

    // ---- helpers ----

    private function seedBlock(?array $structure = null): BlockManagerBlock
    {
        $uuid = (string) Str::uuid();
        $this->createdUuids[] = $uuid;

        return BlockManagerBlock::create([
            'uuid'           => $uuid,
            'slug'           => 'phase6-' . Str::random(8),
            'name'           => 'Phase6 Slug-lock Probe',
            'description'    => 'Auto-seeded by SlugLockApiTest.',
            'icon'           => 'fa-cube',
            'structure_json' => $structure ?? ['elements' => []],
        ]);
    }

    private function seedShipableBlock(): BlockManagerBlock
    {
        return $this->seedBlock([
            'elements' => [
                ['instance_id' => 'el-1', 'element_type' => 'heading', 'variant' => 'default', 'field_name' => 'title'],
            ],
        ]);
    }
}
