<?php

namespace Mtc\Plugins\BlockManager\Tests\Unit;

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

class VariantPreviewServiceTest extends TestCase
{
    private VariantPreviewService $service;

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

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

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

    public function test_service_is_resolvable_from_container(): void
    {
        $this->assertInstanceOf(VariantPreviewService::class, $this->service);
    }

    public function test_preview_emits_button_html_for_button_element(): void
    {
        $draft = $this->seedDraft('button');
        $out = $this->service->render($draft);

        $this->assertIsArray($out);
        $this->assertStringContainsString(
            '<button',
            $out['html'] ?? '',
            "Preview html for a button element must contain a <button> tag."
        );
    }

    public function test_preview_emits_heading_html_for_heading_element(): void
    {
        $draft = $this->seedDraft('heading');
        $out = $this->service->render($draft);

        $this->assertMatchesRegularExpression(
            '/<h[1-6]/',
            $out['html'] ?? '',
            "Preview html for a heading element must contain a heading tag."
        );
    }

    public function test_preview_resolves_color_token_to_variables_less_value(): void
    {
        $draft = $this->seedDraft('button');
        $out = $this->service->render($draft, [
            'base' => ['default' => ['desktop' => [
                'typography' => ['color' => ['token' => '@primary_color']],
            ]]],
        ]);

        $css = $out['css'] ?? '';
        $this->assertMatchesRegularExpression(
            '/color:\s*#[0-9a-fA-F]+/',
            $css,
            "Preview css must contain a resolved hex color from variables.less."
        );
        $this->assertStringNotContainsString(
            '@primary_color',
            $css,
            "Preview css must NOT contain the literal '@primary_color' token name — it must be resolved."
        );
    }

    public function test_preview_preserves_raw_value_in_css(): void
    {
        $draft = $this->seedDraft('button');
        $out = $this->service->render($draft, [
            'base' => ['default' => ['desktop' => [
                'box' => ['padding_x' => ['raw' => '24px']],
            ]]],
        ]);

        $css = $out['css'] ?? '';
        $this->assertStringContainsString('padding-left: 24px', $css);
        $this->assertStringContainsString('padding-right: 24px', $css);
    }

    public function test_preview_warns_for_unknown_token(): void
    {
        $draft = $this->seedDraft('button');
        $out = $this->service->render($draft, [
            'base' => ['default' => ['desktop' => [
                'typography' => ['color' => ['token' => '@no_such_token_' . uniqid()]],
            ]]],
        ]);

        $warnings = $out['warnings'] ?? [];
        $this->assertIsArray($warnings);
        $this->assertNotEmpty(
            $warnings,
            "Unknown token references must surface as a warning."
        );

        // The unknown-token property must NOT appear in the resolved CSS.
        $this->assertStringNotContainsString(
            '@no_such_token',
            $out['css'] ?? '',
            "Unknown token names must not leak into the CSS."
        );
    }

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

        return BlockManagerVariantDraft::create([
            'uuid'            => $uuid,
            'element_type'    => $elementType,
            'variant_slug'    => 'phase10-preview-' . Str::random(8),
            'label'           => 'Phase 10 Preview Probe',
            'properties_json' => null,
        ]);
    }
}
