"""Abstract base class for game adapters.

Every game adapter (built-in, community YAML, or generic webhook) implements
this interface. The adapter is responsible for:
  - Parsing a raw JSON payload into standardized GameEvent instances
  - Validating authentication (webhook secret, etc.)
  - Describing its configuration schema for UI auto-generation
  - Providing setup instructions for the game
"""

from abc import ABC, abstractmethod
from typing import Any, ClassVar

from wled_controller.core.game_integration.events import GameEvent


class GameAdapter(ABC):
    """Base class for all game integration adapters."""

    ADAPTER_TYPE: ClassVar[str] = "base"
    DISPLAY_NAME: ClassVar[str] = "Base Adapter"
    GAME_NAME: ClassVar[str] = "Unknown"
    SUPPORTED_EVENTS: ClassVar[list[str]] = []

    @classmethod
    @abstractmethod
    def parse_payload(
        cls,
        payload: dict[str, Any],
        adapter_config: dict[str, Any],
        prev_state: dict[str, Any],
    ) -> tuple[list[GameEvent], dict[str, Any]]:
        """Parse a game payload into standardized events.

        Args:
            payload: Raw JSON payload from the game.
            adapter_config: Adapter-specific configuration (secrets, mappings).
            prev_state: Previous adapter state for diff-based trigger detection.

        Returns:
            Tuple of (list of GameEvent instances, updated state dict).
        """

    @classmethod
    @abstractmethod
    def validate_auth(
        cls,
        headers: dict[str, str],
        payload: dict[str, Any],
        adapter_config: dict[str, Any],
    ) -> bool:
        """Validate that the incoming request is authentic.

        Args:
            headers: HTTP request headers.
            payload: Raw JSON payload.
            adapter_config: Adapter-specific configuration (may contain secrets).

        Returns:
            True if the request is authenticated, False otherwise.
        """

    @classmethod
    def get_config_schema(cls) -> dict[str, Any]:
        """Return a JSON Schema describing adapter-specific config fields.

        Override in subclasses to expose configuration options in the UI.
        Default implementation returns an empty schema.
        """
        return {"type": "object", "properties": {}}

    @classmethod
    def get_setup_instructions(cls) -> str:
        """Return Markdown setup instructions for this game adapter.

        Override in subclasses to provide game-specific setup guidance.
        """
        return f"No setup instructions available for {cls.DISPLAY_NAME}."

    @classmethod
    def supports_auto_setup(cls) -> bool:
        """Whether this adapter supports automatic GSI config file setup.

        Override in subclasses that can write game config files.
        """
        return False

    @classmethod
    def auto_setup(
        cls,
        integration_id: str,
        adapter_config: dict[str, Any],
        server_url: str,
    ) -> dict[str, Any]:
        """Automatically write game config files for this adapter.

        Args:
            integration_id: The integration ID (used in the callback URL).
            adapter_config: Current adapter configuration (may be updated).
            server_url: Base URL of the WLED controller server.

        Returns:
            Dict with keys: success (bool), file_path (str), message (str),
            token_generated (bool), adapter_config (dict, possibly updated).

        Raises:
            NotImplementedError: If auto-setup is not supported.
        """
        raise NotImplementedError(f"{cls.DISPLAY_NAME} does not support auto setup.")
