<?php

namespace Mtc\Plugins\BlockManager\Tests\Feature;

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

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

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

    /** @var array<string, string> path => original content */
    private array $manifestBackups = [];

    protected function tearDown(): void
    {
        foreach ($this->writtenFiles as $path) {
            @unlink($path);
        }
        foreach ($this->manifestBackups as $path => $content) {
            file_put_contents($path, $content);
        }
        app(\Mtc\Plugins\BlockManager\Services\VariantStyleAggregator::class)->rebuild();
        if (!empty($this->createdUuids)) {
            BlockManagerVariantDraft::whereIn('uuid', $this->createdUuids)->delete();
        }
        parent::tearDown();
    }

    public function test_import_returns_404_for_unknown_element_or_variant(): void
    {
        $response = $this->postJson('/api/block-manager/variants/import-existing', [
            'element_type' => 'button',
            'variant_slug' => 'no-such-variant-' . Str::random(6),
        ]);

        $response->assertStatus(404);
    }

    public function test_import_designer_authored_variant_returns_draft_with_properties(): void
    {
        $properties = [
            'base' => [
                'default' => ['desktop' => [
                    'background' => ['color' => ['token' => '@primary_color']],
                    'box'        => ['padding_x' => ['raw' => '24px']],
                ]],
                'hover' => ['desktop' => [
                    'background' => ['color' => ['token' => '@secondary_color']],
                ]],
            ],
        ];

        $slug = 'phase14-import-' . Str::random(6);
        $draft = $this->seedDraft('button', $slug, $properties);
        $this->backupManifest('button');
        $this->publish($draft);

        $response = $this->postJson('/api/block-manager/variants/import-existing', [
            'element_type' => 'button',
            'variant_slug' => $slug,
        ]);
        $response->assertStatus(200);

        $data = $response->json('data');

        $this->assertFalse(
            (bool) ($data['read_only'] ?? true),
            "Designer-authored variant must report read_only=false."
        );
        $this->assertSame(
            $draft->id,
            $data['draft_id'] ?? null,
            "Import must return the existing draft id when one matches the (element_type, variant_slug) pair."
        );
        $this->assertSame(
            $properties,
            $data['properties_json'] ?? null,
            "Properties round-trip via the @designer-meta header must equal the original."
        );
    }

    public function test_import_foreign_variant_marks_read_only(): void
    {
        // Phase 2 starter — hand-authored, no @designer-meta header.
        $response = $this->postJson('/api/block-manager/variants/import-existing', [
            'element_type' => 'button',
            'variant_slug' => 'primary',
        ]);
        $response->assertStatus(200);

        $data = $response->json('data');

        $this->assertTrue(
            (bool) ($data['read_only'] ?? false),
            "Foreign (hand-authored) variants must report read_only=true."
        );
        $this->assertArrayHasKey('draft_id', $data);
        $this->assertNull($data['draft_id'], "Foreign import must NOT create a draft.");
        $this->assertArrayHasKey('properties_json', $data);
        $this->assertNull($data['properties_json'], "Foreign variants have no reconstructable property tree.");
    }

    public function test_import_existing_draft_returns_same_draft_id(): void
    {
        $slug = 'phase14-import-idemp-' . Str::random(6);
        $draft = $this->seedDraft('button', $slug, [
            'base' => ['default' => ['desktop' => [
                'background' => ['color' => ['raw' => '#abcdef']],
            ]]],
        ]);
        $this->backupManifest('button');
        $this->publish($draft);

        $first  = $this->postJson('/api/block-manager/variants/import-existing', [
            'element_type' => 'button',
            'variant_slug' => $slug,
        ])->json('data');

        $second = $this->postJson('/api/block-manager/variants/import-existing', [
            'element_type' => 'button',
            'variant_slug' => $slug,
        ])->json('data');

        $this->assertSame(
            $first['draft_id'] ?? null,
            $second['draft_id'] ?? null,
            "Repeated imports of the same published variant must return the same draft id (no duplicates)."
        );
        $this->assertSame(
            1,
            BlockManagerVariantDraft::where('element_type', 'button')
                ->where('variant_slug', $slug)
                ->count(),
            "Repeated imports must not create duplicate BlockManagerVariantDraft rows."
        );
    }

    private function seedDraft(string $elementType, string $variantSlug, array $properties): BlockManagerVariantDraft
    {
        $uuid = (string) Str::uuid();
        $this->createdUuids[] = $uuid;

        return BlockManagerVariantDraft::create([
            'uuid'            => $uuid,
            'element_type'    => $elementType,
            'variant_slug'    => $variantSlug,
            'label'           => 'Phase 14 Import Probe',
            'properties_json' => $properties,
        ]);
    }

    private function publish(BlockManagerVariantDraft $draft): void
    {
        $result = app(VariantPublishService::class)->publish($draft);
        $this->writtenFiles[] = $result['twig_path'];
        $this->writtenFiles[] = $result['less_path'];
    }

    private function backupManifest(string $elementType): void
    {
        $path = base_path("plugins/BlockManager/elements/{$elementType}/element.json");
        if (!isset($this->manifestBackups[$path]) && is_file($path)) {
            $this->manifestBackups[$path] = file_get_contents($path);
        }
    }
}
