<?php

namespace Tests\Unit;

use App\ColorPicker;
use App\Models\Email;
use ReflectionClass;
use Tests\TestCase;

// Create a test class that uses the trait
class TestModel
{
    use ColorPicker;
}

class ColorPickerTest extends TestCase
{
    protected function setUp(): void
    {
        parent::setUp();
    }

    /** @test */
    public function it_returns_correct_colors_for_uppercase_letters(): void
    {
        $this->assertEquals([
            'dark' => 'dark:bg-amber-500',
            'light' => 'bg-amber-800',
        ], TestModel::chooseColor('A'));

        $this->assertEquals([
            'dark' => 'dark:bg-teal-500',
            'light' => 'bg-teal-800',
        ], TestModel::chooseColor('Z'));
    }

    /** @test */
    public function it_handles_lowercase_letters_correctly(): void
    {
        $this->assertEquals([
            'dark' => 'dark:bg-amber-500',
            'light' => 'bg-amber-800',
        ], TestModel::chooseColor('a'));

        $this->assertEquals([
            'dark' => 'dark:bg-purple-500',
            'light' => 'bg-purple-800',
        ], TestModel::chooseColor('m'));
    }

    /** @test */
    public function it_returns_default_gray_color_for_invalid_letters(): void
    {
        $this->assertEquals([
            'dark' => 'dark:bg-gray-500',
            'light' => 'bg-gray-800',
        ], TestModel::chooseColor('1'));

        $this->assertEquals([
            'dark' => 'dark:bg-gray-500',
            'light' => 'bg-gray-800',
        ], TestModel::chooseColor('@'));

        $this->assertEquals([
            'dark' => 'dark:bg-gray-500',
            'light' => 'bg-gray-800',
        ], TestModel::chooseColor(''));
    }

    /** @test */
    public function it_handles_special_characters(): void
    {
        $this->assertEquals([
            'dark' => 'dark:bg-gray-500',
            'light' => 'bg-gray-800',
        ], TestModel::chooseColor('#'));

        $this->assertEquals([
            'dark' => 'dark:bg-gray-500',
            'light' => 'bg-gray-800',
        ], TestModel::chooseColor('*'));
    }

    /** @test */
    public function it_returns_array_with_dark_and_light_keys(): void
    {
        $colors = TestModel::chooseColor('B');

        $this->assertIsArray($colors);
        $this->assertArrayHasKey('dark', $colors);
        $this->assertArrayHasKey('light', $colors);
    }

    /** @test */
    public function it_provides_consistent_color_mapping(): void
    {
        $colorA = TestModel::chooseColor('A');
        $colorALower = TestModel::chooseColor('a');

        $this->assertEquals($colorA, $colorALower);
    }

    /** @test */
    public function it_covers_all_letters_of_alphabet(): void
    {
        $alphabet = range('A', 'Z');

        foreach ($alphabet as $letter) {
            $colors = TestModel::chooseColor($letter);

            $this->assertIsArray($colors);
            $this->assertArrayHasKey('dark', $colors);
            $this->assertArrayHasKey('light', $colors);
            $this->assertStringContainsString('dark:bg-', $colors['dark']);
            $this->assertStringContainsString('bg-', $colors['light']);
        }
    }

    /** @test */
    public function it_handles_numbers_and_non_alphabetic_characters_gracefully(): void
    {
        $nonAlphaChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '+', '=', '[', ']', '{', '}', '|', '\\', ';', ':', "'", '"', ',', '.', '<', '>', '/', '?', '~', '`'];

        foreach ($nonAlphaChars as $char) {
            $colors = TestModel::chooseColor($char);

            $this->assertEquals([
                'dark' => 'dark:bg-gray-500',
                'light' => 'bg-gray-800',
            ], $colors);
        }
    }

    /** @test */
    public function it_ensures_all_colors_follow_tailwind_css_naming_convention(): void
    {
        $alphabet = range('A', 'Z');

        foreach ($alphabet as $letter) {
            $colors = TestModel::chooseColor($letter);

            $this->assertMatchesRegularExpression('/^dark:bg-[a-z]+-\d+$/', $colors['dark']);
            $this->assertMatchesRegularExpression('/^bg-[a-z]+-\d+$/', $colors['light']);
        }
    }

    /** @test */
    public function it_provides_unique_colors_for_different_letters(): void
    {
        $colorA = TestModel::chooseColor('A');
        $colorB = TestModel::chooseColor('B');
        $colorC = TestModel::chooseColor('C');

        $this->assertNotEquals($colorA, $colorB);
        $this->assertNotEquals($colorB, $colorC);
        $this->assertNotEquals($colorA, $colorC);
    }

    /** @test */
    public function it_handles_mixed_case_input(): void
    {
        $mixedCaseColors = [
            TestModel::chooseColor('H'),
            TestModel::chooseColor('W'),
            TestModel::chooseColor('T'),
        ];

        // All should use uppercase 'H', 'W', 'T' respectively
        $this->assertEquals(TestModel::chooseColor('H'), $mixedCaseColors[0]);
        $this->assertEquals(TestModel::chooseColor('W'), $mixedCaseColors[1]);
        $this->assertEquals(TestModel::chooseColor('T'), $mixedCaseColors[2]);
    }

    /** @test */
    public function it_can_be_used_in_model_context(): void
    {
        // Test with Email model that uses ColorPicker
        Email::factory()->create(['from_name' => 'John Doe']);

        // This tests that the trait works when used by actual models
        $colors = ColorPicker::chooseColor('J');
        $this->assertArrayHasKey('dark', $colors);
        $this->assertArrayHasKey('light', $colors);
    }

    /** @test */
    public function it_maintains_backward_compatibility(): void
    {
        // Ensure the color mapping remains consistent
        $expectedColors = [
            'A' => ['dark' => 'dark:bg-amber-500', 'light' => 'bg-amber-800'],
            'B' => ['dark' => 'dark:bg-blue-500', 'light' => 'bg-blue-800'],
            'C' => ['dark' => 'dark:bg-cyan-500', 'light' => 'bg-cyan-800'],
            'M' => ['dark' => 'dark:bg-purple-500', 'light' => 'bg-purple-800'],
            'Z' => ['dark' => 'dark:bg-teal-500', 'light' => 'bg-teal-800'],
        ];

        foreach ($expectedColors as $letter => $expectedColor) {
            $this->assertEquals($expectedColor, TestModel::chooseColor($letter));
        }
    }

    /** @test */
    public function it_handles_unicode_characters(): void
    {
        $unicodeChars = ['ñ', 'ç', 'ü', 'ö', 'ä', 'ß'];

        foreach ($unicodeChars as $char) {
            $colors = TestModel::chooseColor($char);

            $this->assertEquals([
                'dark' => 'dark:bg-gray-500',
                'light' => 'bg-gray-800',
            ], $colors);
        }
    }

    /** @test */
    public function it_can_be_called_statically(): void
    {
        // Test both static and instance calling
        $staticResult = TestModel::chooseColor('X');

        $instance = new TestModel;
        $reflection = new ReflectionClass($instance);
        $method = $reflection->getMethod('chooseColor');
        $instanceResult = $method->invoke(null, 'X');

        $this->assertEquals($staticResult, $instanceResult);
    }
}
