"""Tests for Brand dataclass and helpers."""
import pytest
from openslides import Brand


class TestBrand:
    """Test Brand dataclass."""

    def test_default_values(self):
        """Brand has sensible defaults."""
        brand = Brand()
        assert brand.primary == "#054dfe"
        assert brand.background == "#ffffff"
        assert brand.text == "#191919"
        assert brand.font_headline == "Inter"
        assert brand.font_body == "Inter"

    def test_custom_values(self):
        """Brand accepts custom values."""
        brand = Brand(
            primary="#ff0000",
            background="#000000",
            text="#ffffff",
            font_headline="Syne",
            font_body="Inter",
            name="TestBrand",
            domain="test.com",
        )
        assert brand.primary == "#ff0000"
        assert brand.background == "#000000"
        assert brand.name == "TestBrand"
        assert brand.domain == "test.com"

    def test_google_fonts_url_single_font(self):
        """Google Fonts URL generated for single font."""
        brand = Brand(font_headline="Inter", font_body="Inter")
        url = brand.google_fonts_url
        assert "fonts.googleapis.com" in url
        assert "Inter" in url
        assert url.count("family=") == 1  # Only one font

    def test_google_fonts_url_two_fonts(self):
        """Google Fonts URL generated for two different fonts."""
        brand = Brand(font_headline="Syne", font_body="Inter")
        url = brand.google_fonts_url
        assert "Syne" in url
        assert "Inter" in url

    def test_google_fonts_url_spaces(self):
        """Font names with spaces are URL-encoded."""
        brand = Brand(font_headline="Space Grotesk", font_body="Inter")
        url = brand.google_fonts_url
        assert "Space+Grotesk" in url

    def test_clearbit_logo_url(self):
        """Clearbit logo URL generated from domain."""
        brand = Brand(domain="stripe.com")
        assert brand.clearbit_logo_url == "https://logo.clearbit.com/stripe.com"

    def test_clearbit_logo_url_strips_www(self):
        """Clearbit logo URL strips www prefix."""
        brand = Brand(domain="www.stripe.com")
        assert brand.clearbit_logo_url == "https://logo.clearbit.com/stripe.com"

    def test_logo_img_uses_clearbit_fallback(self):
        """logo_img uses Clearbit when no logo set."""
        brand = Brand(domain="stripe.com", name="Stripe")
        img = brand.logo_img(size=40)
        assert "logo.clearbit.com/stripe.com" in img
        assert 'height:40px' in img

    def test_logo_img_uses_logo_url(self):
        """logo_img prefers logo_url over Clearbit."""
        brand = Brand(
            domain="stripe.com",
            logo_url="https://example.com/custom-logo.png",
            name="Stripe",
        )
        img = brand.logo_img()
        assert "example.com/custom-logo.png" in img

    def test_logo_img_uses_svg(self):
        """logo_img prefers logo_svg over URL."""
        brand = Brand(
            logo_svg='<svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="40"/></svg>',
            logo_url="https://example.com/logo.png",
        )
        img = brand.logo_img(size=32)
        assert "<svg" in img
        assert 'width="32"' in img

    def test_text_logo(self):
        """text_logo generates styled span."""
        brand = Brand(
            name="Scaile",
            font_headline="Syne",
            text="#191919",
        )
        logo = brand.text_logo(size=24, weight=600)
        assert "Scaile" in logo
        assert "Syne" in logo
        assert "24px" in logo
        assert "600" in logo

    def test_text_logo_uses_domain_fallback(self):
        """text_logo uses domain when name not set."""
        brand = Brand(domain="scaile.tech")
        logo = brand.text_logo()
        assert "scaile" in logo.lower()


class TestBrandValidation:
    """Test Brand field validation."""

    def test_valid_hex_colors(self):
        """Brand accepts valid hex colors."""
        brand = Brand(
            primary="#054dfe",
            secondary="#fff",
            background="#FFFFFF",
            surface="#abc",
            text="#000000",
            muted="#123456",
        )
        assert brand.primary == "#054dfe"

    def test_invalid_hex_color_raises(self):
        """Brand rejects invalid hex colors."""
        with pytest.raises(ValueError, match="must be a valid hex color"):
            Brand(primary="red")

    def test_invalid_hex_no_hash_raises(self):
        """Brand rejects hex without hash."""
        with pytest.raises(ValueError, match="must be a valid hex color"):
            Brand(primary="054dfe")

    def test_invalid_hex_wrong_length_raises(self):
        """Brand rejects wrong-length hex."""
        with pytest.raises(ValueError, match="must be a valid hex color"):
            Brand(primary="#12345")

    def test_invalid_hex_characters_raises(self):
        """Brand rejects non-hex characters."""
        with pytest.raises(ValueError, match="must be a valid hex color"):
            Brand(primary="#gggggg")


class TestBrandExtraction:
    """Test Brand.from_domain (requires aiohttp)."""

    def test_from_domain_requires_aiohttp(self):
        """from_domain raises ImportError without aiohttp."""
        # This test passes if aiohttp is installed (extraction works)
        # or raises ImportError (expected without aiohttp)
        try:
            brand = Brand.from_domain("example.com")
            assert isinstance(brand, Brand)
        except ImportError as e:
            assert "aiohttp" in str(e)
