"""
Modular Theme System for Markitect

This module provides a dynamic theme loading system that loads themes from
separate YAML files organized by scope (mode, ui, document, branding).

Architecture:
    themes/
        mode/           # Light/dark color schemes
        ui/             # Interface styling
        document/       # Document formatting
        branding/       # Company/personal styling

Each theme file is a YAML file with metadata and properties.
"""

import os
import yaml
from pathlib import Path
from typing import Dict, Any, List
import logging

logger = logging.getLogger(__name__)

class ThemeRegistry:
    """Registry for dynamically loaded themes."""

    def __init__(self):
        self._themes = {}
        self._loaded = False

    def load_themes(self) -> Dict[str, Dict[str, Any]]:
        """Load all themes from YAML files."""
        if self._loaded:
            return self._themes

        themes_dir = Path(__file__).parent

        # Scan all scope directories
        for scope_dir in themes_dir.iterdir():
            if scope_dir.is_dir() and not scope_dir.name.startswith('__'):
                scope = scope_dir.name
                self._load_scope_themes(scope_dir, scope)

        self._loaded = True
        return self._themes

    def _load_scope_themes(self, scope_dir: Path, scope: str) -> None:
        """Load themes from a specific scope directory."""
        for theme_file in scope_dir.glob('*.yaml'):
            theme_name = theme_file.stem
            try:
                with open(theme_file, 'r', encoding='utf-8') as f:
                    theme_data = yaml.safe_load(f)

                # Validate theme structure
                if not self._validate_theme(theme_data, theme_name, theme_file):
                    continue

                # Store theme in registry
                self._themes[theme_name] = {
                    'scope': theme_data.get('scope', scope),
                    'properties': theme_data.get('properties', {}),
                    'metadata': {
                        'name': theme_data.get('name', theme_name),
                        'description': theme_data.get('description', ''),
                        'author': theme_data.get('author', ''),
                        'version': theme_data.get('version', '1.0.0'),
                        'file': str(theme_file)
                    }
                }

                logger.debug(f"Loaded theme '{theme_name}' from {theme_file}")

            except yaml.YAMLError as e:
                logger.error(f"Failed to parse YAML in {theme_file}: {e}")
            except Exception as e:
                logger.error(f"Failed to load theme from {theme_file}: {e}")

    def _validate_theme(self, theme_data: Dict[str, Any], theme_name: str, theme_file: Path) -> bool:
        """Validate theme structure."""
        if not isinstance(theme_data, dict):
            logger.error(f"Theme {theme_file} must be a dictionary")
            return False

        if 'properties' not in theme_data:
            logger.error(f"Theme {theme_file} missing 'properties' section")
            return False

        if not isinstance(theme_data['properties'], dict):
            logger.error(f"Theme {theme_file} 'properties' must be a dictionary")
            return False

        return True

    def get_theme(self, name: str) -> Dict[str, Any]:
        """Get a specific theme by name."""
        if not self._loaded:
            self.load_themes()
        return self._themes.get(name)

    def list_themes(self, scope: str = None) -> List[str]:
        """List available theme names, optionally filtered by scope."""
        if not self._loaded:
            self.load_themes()

        if scope:
            return [name for name, data in self._themes.items()
                   if data.get('scope') == scope]
        return list(self._themes.keys())

    def get_themes_by_scope(self, scope: str) -> Dict[str, Dict[str, Any]]:
        """Get all themes for a specific scope."""
        if not self._loaded:
            self.load_themes()

        return {name: data for name, data in self._themes.items()
                if data.get('scope') == scope}

# Global theme registry instance
theme_registry = ThemeRegistry()

def get_layered_themes() -> Dict[str, Dict[str, Any]]:
    """
    Get all themes in the format expected by the existing system.

    Returns a dictionary compatible with the old LAYERED_THEMES structure.
    """
    return theme_registry.load_themes()

def get_theme(name: str) -> Dict[str, Any]:
    """Get a specific theme by name."""
    return theme_registry.get_theme(name)

def list_themes(scope: str = None) -> List[str]:
    """List available theme names."""
    return theme_registry.list_themes(scope)

def reload_themes() -> None:
    """Force reload of all themes."""
    theme_registry._loaded = False
    theme_registry._themes.clear()
    theme_registry.load_themes()

# Export main functions
__all__ = ['get_layered_themes', 'get_theme', 'list_themes', 'reload_themes', 'theme_registry']