<?php

namespace Mtc\Plugins\BlockManager\Tests\Unit;

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

class VariantLessGeneratorStatesTest extends TestCase
{
    private VariantLessGenerator $service;

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

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

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

    public function test_emits_hover_state_block_when_overrides_present(): void
    {
        $draft = $this->seedDraft('button', 'phase12-states-' . Str::random(6), [
            'base' => [
                'default' => ['desktop' => [
                    'background' => ['color' => ['raw' => '#ffffff']],
                ]],
                'hover' => ['desktop' => [
                    'background' => ['color' => ['raw' => '#abcdef']],
                ]],
            ],
        ]);

        $output = $this->service->generate($draft);

        // The state block must exist
        $this->assertMatchesRegularExpression(
            '/&:hover\s*\{/',
            $output,
            "LESS output must contain a nested '&:hover {' block."
        );

        // The hover override property must appear somewhere
        $this->assertStringContainsString(
            'background-color: #abcdef',
            $output,
            "Hover override must produce 'background-color: #abcdef'."
        );

        // The hover block specifically must contain that property
        $this->assertSame(
            1,
            preg_match('/&:hover\s*\{[^}]*background-color:\s*#abcdef[^}]*\}/s', $output),
            "The '&:hover { ... }' block must contain the override property."
        );
    }

    public function test_emits_each_declared_state_as_separate_nested_block(): void
    {
        $draft = $this->seedDraft('button', 'phase12-states-' . Str::random(6), [
            'base' => [
                'default'  => ['desktop' => ['background' => ['color' => ['raw' => '#ffffff']]]],
                'hover'    => ['desktop' => ['background' => ['color' => ['raw' => '#aaaaaa']]]],
                'focus'    => ['desktop' => ['border' => ['border_width' => ['raw' => '2px']]]],
                'disabled' => ['desktop' => ['typography' => ['color' => ['raw' => '#cccccc']]]],
            ],
        ]);

        $output = $this->service->generate($draft);

        foreach (['&:hover', '&:focus', '&:disabled'] as $stateSelector) {
            $this->assertMatchesRegularExpression(
                '/' . preg_quote($stateSelector, '/') . '\s*\{/',
                $output,
                "LESS output must contain a nested '{$stateSelector} {' block."
            );
        }
    }

    public function test_omits_state_block_when_no_overrides_present(): void
    {
        $draft = $this->seedDraft('button', 'phase12-states-' . Str::random(6), [
            'base' => [
                'default' => ['desktop' => [
                    'background' => ['color' => ['raw' => '#ffffff']],
                    'box'        => ['padding_x' => ['raw' => '24px']],
                ]],
                // No hover/focus/active/disabled cells
            ],
        ]);

        $output = $this->service->generate($draft);

        foreach (['&:hover', '&:focus', '&:active', '&:disabled'] as $stateSelector) {
            $this->assertStringNotContainsString(
                $stateSelector,
                $output,
                "State '{$stateSelector}' block must NOT appear when there are no overrides."
            );
        }

        // Base properties stay in the outer selector
        $this->assertStringContainsString('background-color: #ffffff', $output);
        $this->assertStringContainsString('padding-left: 24px',          $output);
    }

    public function test_state_block_only_contains_overrides_not_base_copies(): void
    {
        $draft = $this->seedDraft('button', 'phase12-states-' . Str::random(6), [
            'base' => [
                'default' => ['desktop' => [
                    'background' => ['color' => ['raw' => '#ffffff']],
                    'typography' => ['font_size' => ['raw' => '16px']],
                ]],
                'hover' => ['desktop' => [
                    'typography' => ['font_size' => ['raw' => '20px']],
                ]],
            ],
        ]);

        $output = $this->service->generate($draft);

        // Extract just the &:hover { ... } block
        $this->assertSame(
            1,
            preg_match('/&:hover\s*\{([^}]*)\}/s', $output, $m),
            "Output must contain a '&:hover { ... }' block."
        );
        $hoverBody = $m[1];

        $this->assertStringContainsString(
            'font-size: 20px',
            $hoverBody,
            "Hover override must appear inside the hover block."
        );
        $this->assertStringNotContainsString(
            'background-color',
            $hoverBody,
            "Hover block must NOT carry copies of base properties (no background-color since hover didn't override it)."
        );
    }

    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 12 States Probe',
            'properties_json' => $properties,
        ]);
    }
}
