"""Tests for theme loading and switching."""

from pathlib import Path
from tempfile import TemporaryDirectory

import pytest

from cleave.tui.themes.loader import ThemeLoader
from cleave.tui.themes.registry import ThemeRegistry


class TestThemeLoader:
    """Test theme loading from TCSS files."""

    def test_load_theme_from_file(self, tmp_path):
        """Test loading a theme from a TCSS file."""
        theme_file = tmp_path / "test.tcss"
        theme_content = """
        /* Test Theme */
        Screen {
            background: #000000;
            color: #ffffff;
        }
        """
        theme_file.write_text(theme_content)

        loader = ThemeLoader()
        content = loader.load_theme_file(theme_file)

        assert content is not None
        assert "background: #000000" in content

    def test_load_theme_metadata(self, tmp_path):
        """Test loading theme metadata from YAML."""
        metadata_file = tmp_path / "test-metadata.yaml"
        metadata_content = """
name: Test Theme
description: A test theme
author: styrene-lab
colors:
  primary: "#ff0000"
  background: "#000000"
"""
        metadata_file.write_text(metadata_content)

        loader = ThemeLoader()
        metadata = loader.load_metadata(metadata_file)

        assert metadata["name"] == "Test Theme"
        assert metadata["description"] == "A test theme"
        assert metadata["colors"]["primary"] == "#ff0000"

    def test_load_nonexistent_theme(self):
        """Test loading a theme that doesn't exist."""
        loader = ThemeLoader()
        content = loader.load_theme_file(Path("/nonexistent/theme.tcss"))
        assert content is None


class TestThemeRegistry:
    """Test theme registry functionality."""

    def test_register_builtin_themes(self):
        """Test that built-in themes are registered."""
        registry = ThemeRegistry()
        registry.load_builtin_themes()

        themes = registry.list_themes()
        assert "retro-purple" in themes
        assert "cyberpunk-green" in themes
        assert "solarized-dark" in themes
        assert "nord" in themes
        assert "high-contrast" in themes

    def test_get_theme(self):
        """Test retrieving a theme by name."""
        registry = ThemeRegistry()
        registry.load_builtin_themes()

        theme = registry.get_theme("retro-purple")
        assert theme is not None
        assert "retro" in theme["name"].lower()

    def test_get_nonexistent_theme(self):
        """Test retrieving a theme that doesn't exist."""
        registry = ThemeRegistry()
        theme = registry.get_theme("nonexistent")
        assert theme is None

    def test_register_custom_theme(self, tmp_path):
        """Test registering a custom theme."""
        theme_file = tmp_path / "custom.tcss"
        theme_file.write_text("Screen { background: #123456; }")

        registry = ThemeRegistry()
        registry.register_theme("custom", theme_file)

        theme = registry.get_theme("custom")
        assert theme is not None
        assert "background: #123456" in theme["content"]

    def test_load_user_themes(self, tmp_path, monkeypatch):
        """Test loading themes from user directory."""
        user_themes_dir = tmp_path / ".cleave" / "themes"
        user_themes_dir.mkdir(parents=True)

        custom_theme = user_themes_dir / "custom.tcss"
        custom_theme.write_text("Screen { background: #abcdef; }")

        # Mock the user themes directory
        monkeypatch.setattr(
            "cleave.tui.themes.registry.get_user_themes_dir",
            lambda: user_themes_dir
        )

        registry = ThemeRegistry()
        registry.load_user_themes()

        theme = registry.get_theme("custom")
        assert theme is not None

    def test_cycle_themes(self):
        """Test cycling through themes."""
        registry = ThemeRegistry()
        registry.load_builtin_themes()

        # Start with retro-purple
        current = "retro-purple"
        next_theme = registry.get_next_theme(current)

        assert next_theme is not None
        assert next_theme != current

        # Cycling through all themes should eventually return to start
        visited = {current}
        for _ in range(10):  # More than number of themes
            next_theme = registry.get_next_theme(next_theme)
            if next_theme in visited:
                break
            visited.add(next_theme)

        assert "retro-purple" in visited


class TestThemeIntegration:
    """Test theme integration with settings."""

    def test_save_theme_preference(self, tmp_path, monkeypatch):
        """Test saving theme preference to settings."""
        from cleave.core.settings import CleaveSettings, save_settings

        # Mock settings directory
        settings_dir = tmp_path / ".cleave"
        settings_dir.mkdir(parents=True)
        monkeypatch.setattr("cleave.core.settings.SETTINGS_DIR", settings_dir)
        monkeypatch.setattr(
            "cleave.core.settings.SETTINGS_FILE",
            settings_dir / "settings.yaml"
        )

        settings = CleaveSettings()
        settings.theme = "cyberpunk-green"
        save_settings(settings)

        # Reload and verify
        from cleave.core.settings import load_settings
        loaded = load_settings()
        assert loaded.theme == "cyberpunk-green"

    def test_load_theme_from_settings(self, tmp_path, monkeypatch):
        """Test loading theme preference from settings."""
        from cleave.core.settings import CleaveSettings, save_settings, load_settings

        settings_dir = tmp_path / ".cleave"
        settings_dir.mkdir(parents=True)
        monkeypatch.setattr("cleave.core.settings.SETTINGS_DIR", settings_dir)
        monkeypatch.setattr(
            "cleave.core.settings.SETTINGS_FILE",
            settings_dir / "settings.yaml"
        )

        settings = CleaveSettings()
        settings.theme = "nord"
        save_settings(settings)

        loaded = load_settings()
        assert loaded.theme == "nord"
