"""Test ColorFormatter with RGB instances."""

import pytest

from freyja.theme import RGB, ColorFormatter, ThemeStyle


class TestColorFormatterRGB:
    """Test ColorFormatter with RGB instances."""

    def test_apply_style_with_rgb_foreground(self):
        """Test apply_style with RGB foreground color."""
        formatter = ColorFormatter(enable_colors=True)
        rgb_color = RGB.from_rgb(0xFF5733)
        style = ThemeStyle(fg=rgb_color)

        result = formatter.apply_style("test", style)

        # Should contain ANSI escape codes
        assert "\033[38;5;" in result  # Foreground color code
        assert "test" in result
        assert "\033[0m" in result  # Reset code

    def test_apply_style_with_rgb_background(self):
        """Test apply_style with RGB background color."""
        formatter = ColorFormatter(enable_colors=True)
        rgb_color = RGB.from_rgb(0x00FF00)
        style = ThemeStyle(bg=rgb_color)

        result = formatter.apply_style("test", style)

        # Should contain ANSI escape codes for background
        assert "\033[48;5;" in result  # Background color code
        assert "test" in result
        assert "\033[0m" in result  # Reset code

    def test_apply_style_with_rgb_both_colors(self):
        """Test apply_style with RGB foreground and background colors."""
        formatter = ColorFormatter(enable_colors=True)
        fg_color = RGB.from_rgb(0xFF5733)
        bg_color = RGB.from_rgb(0x00FF00)
        style = ThemeStyle(fg=fg_color, bg=bg_color, bold=True)

        result = formatter.apply_style("test", style)

        # Should contain both foreground and background codes
        assert "\033[38;5;" in result  # Foreground color code
        assert "\033[48;5;" in result  # Background color code
        assert "\033[1m" in result  # Bold code
        assert "test" in result
        assert "\033[0m" in result  # Reset code

    def test_apply_style_rgb_consistency(self):
        """Test that equivalent RGB instances produce same output."""
        formatter = ColorFormatter(enable_colors=True)
        rgb_color1 = RGB.from_rgb(0xFF5733)
        r, g, b = rgb_color1.to_ints()
        rgb_color2 = RGB.from_ints(r, g, b)  # Equivalent RGB from ints

        style1 = ThemeStyle(fg=rgb_color1)
        style2 = ThemeStyle(fg=rgb_color2)

        result1 = formatter.apply_style("test", style1)
        result2 = formatter.apply_style("test", style2)

        # Results should be identical
        assert result1 == result2

    def test_apply_style_colors_disabled(self):
        """Test apply_style with colors disabled."""
        formatter = ColorFormatter(enable_colors=False)
        rgb_color = RGB.from_rgb(0xFF5733)
        style = ThemeStyle(fg=rgb_color, bold=True)

        result = formatter.apply_style("test", style)

        # Should return plain text when colors are disabled
        assert result == "test"
        assert "\033[" not in result  # No ANSI codes

    def test_apply_style_invalid_fg_type(self):
        """Test apply_style with invalid foreground color type."""
        formatter = ColorFormatter(enable_colors=True)
        style = ThemeStyle(fg=123)  # Invalid type

        with pytest.raises(
            ValueError, match="Foreground color must be RGB instance or ANSI string"
        ):
            formatter.apply_style("test", style)

    def test_apply_style_invalid_bg_type(self):
        """Test apply_style with invalid background color type."""
        formatter = ColorFormatter(enable_colors=True)
        style = ThemeStyle(bg=123)  # Invalid type

        with pytest.raises(
            ValueError, match="Background color must be RGB instance or ANSI string"
        ):
            formatter.apply_style("test", style)

    def test_apply_style_with_all_text_styles(self):
        """Test apply_style with RGB color and all text styles."""
        formatter = ColorFormatter(enable_colors=True)
        rgb_color = RGB.from_rgb(0xFF5733)
        style = ThemeStyle(fg=rgb_color, bold=True, italic=True, dim=True, underline=True)

        result = formatter.apply_style("test", style)

        # Should contain all style codes
        assert "\033[38;5;" in result  # Foreground color
        assert "\033[1m" in result  # Bold
        assert "\033[3m" in result  # Italic
        assert "\033[2m" in result  # Dim
        assert "\033[4m" in result  # Underline
        assert "test" in result
        assert "\033[0m" in result  # Reset

    def test_mixed_rgb_and_string_styles(self):
        """Test theme with mixed RGB instances and string colors."""
        formatter = ColorFormatter(enable_colors=True)

        # RGB foreground, string background (ANSI code)
        rgb_fg = RGB.from_rgb(0xFF5733)
        ansi_bg = "\033[48;5;46m"  # Direct ANSI code
        style = ThemeStyle(fg=rgb_fg, bg=ansi_bg)

        result = formatter.apply_style("test", style)

        # Should handle both types properly
        assert "\033[38;5;" in result  # RGB foreground
        assert ansi_bg in result  # String background
        assert "test" in result
        assert "\033[0m" in result  # Reset

    def test_empty_text(self):
        """Test apply_style with empty text."""
        formatter = ColorFormatter(enable_colors=True)
        rgb_color = RGB.from_rgb(0xFF5733)
        style = ThemeStyle(fg=rgb_color)

        result = formatter.apply_style("", style)

        # Empty text should return empty string
        assert result == ""

    def test_none_text(self):
        """Test apply_style with None text."""
        formatter = ColorFormatter(enable_colors=True)
        rgb_color = RGB.from_rgb(0xFF5733)
        style = ThemeStyle(fg=rgb_color)

        result = formatter.apply_style(None, style)

        # None text should return None
        assert result is None
