import pytest
from app.services.theme import (
    hex_to_rgb, rgb_to_hex, adjust_lightness, get_contrast_text,
    detect_mood, generate_theme_config, generate_theme_css,
)


class TestHexToRgb:
    def test_standard_hex(self):
        assert hex_to_rgb("#FF0000") == (255, 0, 0)

    def test_without_hash(self):
        assert hex_to_rgb("00FF00") == (0, 255, 0)

    def test_shorthand_hex(self):
        assert hex_to_rgb("#FFF") == (255, 255, 255)

    def test_lowercase(self):
        assert hex_to_rgb("#4f46e5") == (79, 70, 229)

    def test_invalid_returns_default(self):
        result = hex_to_rgb("not-a-color")
        assert result == (79, 70, 229)


class TestRgbToHex:
    def test_black(self):
        assert rgb_to_hex(0, 0, 0) == "#000000"

    def test_white(self):
        assert rgb_to_hex(255, 255, 255) == "#ffffff"

    def test_red(self):
        assert rgb_to_hex(255, 0, 0) == "#ff0000"


class TestAdjustLightness:
    def test_darken(self):
        result = adjust_lightness("#FFFFFF", 0.5)
        r, g, b = hex_to_rgb(result)
        assert r < 255 and g < 255 and b < 255

    def test_lighten_non_black(self):
        result = adjust_lightness("#333333", 2.0)
        r_orig, _, _ = hex_to_rgb("#333333")
        r_new, _, _ = hex_to_rgb(result)
        assert r_new > r_orig

    def test_no_change(self):
        result = adjust_lightness("#808080", 1.0)
        r, g, b = hex_to_rgb(result)
        assert 120 <= r <= 140


class TestGetContrastText:
    def test_dark_background_returns_white(self):
        assert get_contrast_text("#000000") == "#ffffff"

    def test_light_background_returns_dark(self):
        assert get_contrast_text("#FFFFFF") == "#1a1a2e"

    def test_medium_dark(self):
        result = get_contrast_text("#4F46E5")
        assert result in ("#ffffff", "#1a1a2e")


class TestDetectMood:
    def test_playful_tone(self):
        assert detect_mood(brand_tone="playful and creative") == "creative"

    def test_bold_tone(self):
        assert detect_mood(brand_tone="bold and powerful") == "bold"

    def test_warm_tone(self):
        assert detect_mood(brand_tone="warm and friendly") == "warm"

    def test_minimal_tone(self):
        assert detect_mood(brand_tone="clean and minimal") == "minimal"

    def test_professional_tone(self):
        assert detect_mood(brand_tone="professional and corporate") == "professional"

    def test_empty_defaults_to_professional(self):
        assert detect_mood() == "professional"

    def test_niche_fallback(self):
        result = detect_mood(niche="technology startup")
        assert isinstance(result, str)


class TestGenerateThemeConfig:
    def test_returns_dict(self):
        config = generate_theme_config()
        assert isinstance(config, dict)

    def test_has_colors_dict(self):
        config = generate_theme_config(primary="#4F46E5", secondary="#7C3AED", accent="#06B6D4")
        assert "colors" in config
        colors = config["colors"]
        assert "primary" in colors
        assert "secondary" in colors
        assert "accent" in colors

    def test_custom_colors_reflected(self):
        config = generate_theme_config(primary="#FF0000")
        assert config["colors"]["primary"] == "#FF0000"

    def test_mood_detected(self):
        config = generate_theme_config(brand_tone="playful creative")
        assert config.get("mood") == "creative"

    def test_has_required_keys(self):
        config = generate_theme_config()
        assert "mood" in config
        assert "colors" in config
        assert "card_style" in config


class TestGenerateThemeCss:
    def test_returns_css_string(self):
        config = generate_theme_config()
        css = generate_theme_css(config)
        assert isinstance(css, str)
        assert len(css) > 50

    def test_contains_custom_properties(self):
        config = generate_theme_config()
        css = generate_theme_css(config)
        assert "--" in css

    def test_contains_root_selector(self):
        config = generate_theme_config()
        css = generate_theme_css(config)
        assert ":root" in css
