"""DM Schema V1/V2 Converter Base Class."""

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

from .types import MEDIA_TYPE_MAP, SUPPORTED_FILE_TYPES
from .utils import detect_file_type, extract_media_type_info

if TYPE_CHECKING:
    from .tools import ToolProcessor


class BaseDMConverter(ABC):
    """DM Schema Converter Base Class."""

    SUPPORTED_FILE_TYPES = SUPPORTED_FILE_TYPES
    MEDIA_TYPE_MAP = MEDIA_TYPE_MAP

    def __init__(self, file_type: str | None = None) -> None:
        """Initialize the DM schema converter.

        Args:
            file_type: File type to convert (e.g., 'image', 'video'). If None,
                auto-detects from data during conversion.

        Raises:
            ValueError: If file_type is not in SUPPORTED_FILE_TYPES.
        """
        if file_type is not None and file_type not in self.SUPPORTED_FILE_TYPES:
            raise ValueError(
                f'Unsupported file type: {file_type}. Supported types: {", ".join(self.SUPPORTED_FILE_TYPES)}'
            )
        self.file_type = file_type
        self._tool_processors: dict[str, 'ToolProcessor'] = {}
        self._setup_tool_processors()

    @abstractmethod
    def _setup_tool_processors(self) -> None:
        """Register tool processors."""
        ...

    def register_processor(self, processor: 'ToolProcessor') -> None:
        """Register a tool processor."""
        self._tool_processors[processor.tool_name] = processor

    def get_processor(self, tool_name: str) -> 'ToolProcessor | None':
        """Get a registered tool processor."""
        return self._tool_processors.get(tool_name)

    @abstractmethod
    def convert(self, data: dict[str, Any]) -> dict[str, Any]:
        """Perform data conversion."""
        ...

    def _detect_file_type(self, data: dict[str, Any], is_v2: bool = False) -> str:
        """Auto-detect file type from data."""
        if self.file_type:
            return self.file_type
        return detect_file_type(data, is_v2)

    def _extract_media_type_info(self, media_id: str) -> tuple[str, str]:
        """Extract type information from media ID."""
        return extract_media_type_info(media_id)
