"""Unit tests for CellColorExtractor."""

import pytest
from src.extraction_v2.color_extractor import CellColorExtractor, ColorExtractionResult


class TestCellColorExtractor:
    """Test suite for CellColorExtractor functionality."""

    def test_rgb_to_hex_conversion(self):
        """Test RGB color conversion to hex format."""
        extractor = CellColorExtractor()

        # Test 6-digit RGB
        assert extractor._rgb_to_hex("FF0000") == "#FF0000"
        assert extractor._rgb_to_hex("00FF00") == "#00FF00"

        # Test 8-digit ARGB (should strip alpha)
        assert extractor._rgb_to_hex("FFFF0000") == "#FF0000"
        assert extractor._rgb_to_hex("8000FF00") == "#00FF00"

    def test_indexed_color_to_hex(self):
        """Test indexed color palette mapping."""
        extractor = CellColorExtractor()

        # Test standard palette colors
        assert extractor._indexed_color_to_hex(0) == "#000000"  # Black
        assert extractor._indexed_color_to_hex(1) == "#FFFFFF"  # White
        assert extractor._indexed_color_to_hex(2) == "#FF0000"  # Red
        assert extractor._indexed_color_to_hex(64) == "#000000"  # Automatic = black

    def test_rgb_to_hsl_conversion(self):
        """Test RGB to HSL color space conversion."""
        extractor = CellColorExtractor()

        # Test pure colors
        h, l, s = extractor._rgb_to_hsl(1.0, 0.0, 0.0)  # Pure red
        assert abs(h - 0) < 1  # Hue should be near 0
        assert abs(l - 0.5) < 0.01  # Lightness should be 0.5
        assert abs(s - 1.0) < 0.01  # Saturation should be 1.0

        # Test white
        h, l, s = extractor._rgb_to_hsl(1.0, 1.0, 1.0)
        assert abs(l - 1.0) < 0.01  # White has lightness 1.0
        assert abs(s - 0.0) < 0.01  # White has saturation 0.0

        # Test black
        h, l, s = extractor._rgb_to_hsl(0.0, 0.0, 0.0)
        assert abs(l - 0.0) < 0.01  # Black has lightness 0.0
        assert abs(s - 0.0) < 0.01  # Black has saturation 0.0

    def test_hsl_to_rgb_conversion(self):
        """Test HSL to RGB color space conversion."""
        extractor = CellColorExtractor()

        # Test pure red (H=0, L=0.5, S=1.0)
        r, g, b = extractor._hsl_to_rgb(0, 0.5, 1.0)
        assert abs(r - 1.0) < 0.01
        assert abs(g - 0.0) < 0.01
        assert abs(b - 0.0) < 0.01

        # Test white (H=0, L=1.0, S=0.0)
        r, g, b = extractor._hsl_to_rgb(0, 1.0, 0.0)
        assert abs(r - 1.0) < 0.01
        assert abs(g - 1.0) < 0.01
        assert abs(b - 1.0) < 0.01

        # Test black (H=0, L=0.0, S=0.0)
        r, g, b = extractor._hsl_to_rgb(0, 0.0, 0.0)
        assert abs(r - 0.0) < 0.01
        assert abs(g - 0.0) < 0.01
        assert abs(b - 0.0) < 0.01

    def test_theme_color_without_tint(self):
        """Test theme color resolution without tint."""
        extractor = CellColorExtractor()

        # Test default theme colors (using DEFAULT_THEME_COLORS)
        assert extractor._theme_color_to_hex(0, 0.0) == "#FFFFFF"  # lt1 (Background 1)
        assert extractor._theme_color_to_hex(1, 0.0) == "#000000"  # dk1 (Text 1)
        assert extractor._theme_color_to_hex(4, 0.0) == "#4F81BD"  # accent1

    def test_theme_color_with_positive_tint(self):
        """Test theme color resolution with positive tint (lighter)."""
        extractor = CellColorExtractor()

        # Pure blue with 50% tint (should get lighter)
        result = extractor._theme_color_to_hex(4, 0.5)  # accent1 with tint
        # Verify it's a valid hex color
        assert result.startswith("#")
        assert len(result) == 7

    def test_theme_color_with_negative_tint(self):
        """Test theme color resolution with negative tint (darker)."""
        extractor = CellColorExtractor()

        # Pure blue with -50% tint (should get darker)
        result = extractor._theme_color_to_hex(4, -0.5)  # accent1 with negative tint
        # Verify it's a valid hex color
        assert result.startswith("#")
        assert len(result) == 7

    def test_is_default_color_white_black(self):
        """Test default color detection for white background and black text."""
        extractor = CellColorExtractor()

        # White bg + black text = default
        assert extractor._is_default_color("#FFFFFF", "#000000") is True

        # White bg + None text = default
        assert extractor._is_default_color("#FFFFFF", None) is True

        # None bg + black text = default
        assert extractor._is_default_color(None, "#000000") is True

        # None bg + None text = default
        assert extractor._is_default_color(None, None) is True

    def test_is_default_color_non_default(self):
        """Test default color detection for non-default colors."""
        extractor = CellColorExtractor()

        # Red background = not default
        assert extractor._is_default_color("#FF0000", "#000000") is False

        # White text = not default
        assert extractor._is_default_color("#FFFFFF", "#FFFFFF") is False

        # Both non-default
        assert extractor._is_default_color("#FF0000", "#00FF00") is False

    def test_col_letter_to_index_single_letter(self):
        """Test column letter to index conversion for single letters."""
        extractor = CellColorExtractor()

        assert extractor._col_letter_to_index("A") == 0
        assert extractor._col_letter_to_index("B") == 1
        assert extractor._col_letter_to_index("Z") == 25

    def test_col_letter_to_index_double_letter(self):
        """Test column letter to index conversion for double letters."""
        extractor = CellColorExtractor()

        assert extractor._col_letter_to_index("AA") == 26
        assert extractor._col_letter_to_index("AB") == 27
        assert extractor._col_letter_to_index("AZ") == 51
        assert extractor._col_letter_to_index("BA") == 52

    def test_col_letter_to_index_triple_letter(self):
        """Test column letter to index conversion for triple letters."""
        extractor = CellColorExtractor()

        assert extractor._col_letter_to_index("AAA") == 702

    def test_extract_colors_invalid_file(self):
        """Test color extraction from invalid/non-existent file."""
        extractor = CellColorExtractor()

        # Non-existent file
        result = extractor.extract_colors("/tmp/nonexistent_file.xlsx")
        assert result.status == "failed"
        assert result.cells_processed == 0
        assert result.cells_with_colors == 0
        assert result.error_message is not None

    def test_color_extraction_result_structure(self):
        """Test ColorExtractionResult dataclass structure."""
        result = ColorExtractionResult(
            color_map={"Sheet1": {"0,0": {"bg_color": "#FF0000", "font_color": "#FFFFFF"}}},
            status="success",
            cells_processed=100,
            cells_with_colors=5,
            warnings=["test warning"]
        )

        assert result.status == "success"
        assert result.cells_processed == 100
        assert result.cells_with_colors == 5
        assert len(result.warnings) == 1
        assert result.error_message is None
        assert "Sheet1" in result.color_map
        assert "0,0" in result.color_map["Sheet1"]


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
