from __future__ import annotations

from dataclasses import dataclass

from app.core.config import settings


@dataclass(frozen=True)
class ModelSpec:
    id: str
    provider: str
    api_model: str
    family: str


class ModelRegistry:
    """Map public model IDs to provider + API model + plan family."""

    @staticmethod
    def resolve(model_id: str | None) -> ModelSpec:
        """Resolve a model ID to provider + API model + plan family.

        Empty / None / unknown IDs fall back to settings.LLM_MODEL (OpenAI).
        """
        if not model_id or not str(model_id).strip():
            return ModelRegistry._openai_spec(settings.LLM_MODEL)

        key = str(model_id).strip()
        lowered = key.lower()

        if lowered.startswith("claude-"):
            return ModelSpec(
                id=key,
                provider="anthropic",
                api_model=key,
                family="anthropic",
            )

        if lowered.startswith("gemini-"):
            return ModelSpec(
                id=key,
                provider="gemini",
                api_model=key,
                family="gemini",
            )

        if lowered.startswith("deepseek-"):
            return ModelSpec(
                id=key,
                provider="deepseek",
                api_model=key,
                family="deepseek",
            )

        if (
            lowered.startswith("gpt-")
            or lowered.startswith("o1")
            or lowered.startswith("o3")
            or (
                lowered.startswith("openai-")
                and lowered.endswith("-series")
            )
        ):
            api_model = key
            if lowered == "openai-4-series":
                api_model = "gpt-4o"
            elif lowered == "openai-5-series":
                api_model = "o1"

            if (
                lowered.startswith(("o1", "o3", "gpt-5"))
                or "openai-5" in lowered
            ):
                family = "openai-5-series"
            else:
                family = "openai-4-series"

            return ModelSpec(
                id=key,
                provider="openai",
                api_model=api_model,
                family=family,
            )

        return ModelRegistry._openai_spec(settings.LLM_MODEL)

    @staticmethod
    def _openai_spec(model: str) -> ModelSpec:
        lowered = model.lower()
        if lowered.startswith(("o1", "o3", "gpt-5")):
            family = "openai-5-series"
        else:
            family = "openai-4-series"
        return ModelSpec(
            id=model,
            provider="openai",
            api_model=model,
            family=family,
        )
