"""Game integration configuration storage using SQLite.

Provides CRUD operations for GameIntegrationConfig entities with
name uniqueness validation and write-through caching.
"""

from typing import Any, List, Optional

from wled_controller.storage.base_sqlite_store import BaseSqliteStore
from wled_controller.storage.database import Database
from wled_controller.storage.game_integration import EventMapping, GameIntegrationConfig
from wled_controller.utils import get_logger

logger = get_logger(__name__)


class GameIntegrationStore(BaseSqliteStore[GameIntegrationConfig]):
    """Storage for game integration configurations.

    All configs are persisted to the database with write-through caching.
    """

    _table_name = "game_integrations"
    _entity_name = "Game integration"
    _version = "1.0.0"

    def __init__(self, db: Database) -> None:
        super().__init__(db, GameIntegrationConfig.from_dict)

    # Backward-compatible aliases
    get_all_integrations = BaseSqliteStore.get_all
    get_integration = BaseSqliteStore.get
    delete_integration = BaseSqliteStore.delete

    def create_integration(
        self,
        name: str,
        adapter_type: str,
        enabled: bool = True,
        adapter_config: Optional[dict[str, Any]] = None,
        event_mappings: Optional[List[EventMapping]] = None,
        description: Optional[str] = None,
        tags: Optional[List[str]] = None,
    ) -> GameIntegrationConfig:
        """Create a new game integration config.

        Args:
            name: Human-readable name (must be unique).
            adapter_type: Registered adapter type string.
            enabled: Whether integration is active.
            adapter_config: Adapter-specific settings.
            event_mappings: Event-to-effect mappings.
            description: Optional description.
            tags: User-defined tags.

        Returns:
            The newly created config.

        Raises:
            ValueError: If name is empty or already taken.
        """
        with self._lock:
            self._check_name_unique(name)

            config = GameIntegrationConfig.create_from_kwargs(
                name=name,
                adapter_type=adapter_type,
                enabled=enabled,
                adapter_config=adapter_config,
                event_mappings=event_mappings,
                description=description,
                tags=tags,
            )

            self._items[config.id] = config
            self._save_item(config.id, config)

        logger.info(f"Created game integration: {name} ({config.id})")
        return config

    def update_integration(
        self,
        integration_id: str,
        name: Optional[str] = None,
        adapter_type: Optional[str] = None,
        enabled: Optional[bool] = None,
        adapter_config: Optional[dict[str, Any]] = None,
        event_mappings: Optional[List[EventMapping]] = None,
        description: Optional[str] = None,
        tags: Optional[List[str]] = None,
    ) -> GameIntegrationConfig:
        """Update an existing game integration config.

        Args:
            integration_id: Config ID to update.
            name: New name (must be unique if changed).
            adapter_type: New adapter type.
            enabled: New enabled state.
            adapter_config: New adapter-specific settings.
            event_mappings: New event-to-effect mappings.
            description: New description.
            tags: New tags.

        Returns:
            The updated config.

        Raises:
            EntityNotFoundError: If integration_id not found.
            ValueError: If new name conflicts with an existing config.
        """
        with self._lock:
            existing = self.get(integration_id)

            if name is not None:
                self._check_name_unique(name, exclude_id=integration_id)

            updated = existing.apply_update(
                name=name,
                adapter_type=adapter_type,
                enabled=enabled,
                adapter_config=adapter_config,
                event_mappings=event_mappings,
                description=description,
                tags=tags,
            )

            self._items[integration_id] = updated
            self._save_item(integration_id, updated)

        logger.info(f"Updated game integration: {integration_id}")
        return updated

    def get_references(self, integration_id: str) -> List[str]:
        """Return names of entities that reference this integration.

        Currently game integrations are not referenced by other entities,
        but this method is provided for future cascade prevention.
        """
        return []
