from __future__ import annotations

from typing import Final


DEFAULT_FAST_MODEL: Final[str] = "claude-haiku-4-5-20251001"
DEFAULT_COMPLEX_MODEL: Final[str] = "claude-sonnet-4-20250514"

FAST_REPAIR_STEPS: Final[set[str]] = {
    "json_repair",
    "section_json_repair",
}

ADAPTIVE_STEPS: Final[set[str]] = {
    "planner",
    "planner_retry",
    "planner_quality_retry",
    "section_append",
    "section_regeneration",
    "feedback_plan_revision",
    "feedback_plan_revision_retry",
}

COMPLEX_KEYWORDS: Final[tuple[str, ...]] = (
    "scenario model",
    "financial model",
    "what-if",
    "interactive calculator",
    "3d",
    "three.js",
    "canvas animation",
    "particle",
    "globe",
    "webgl",
    "multi-section",
    "scroll story",
    "parallax",
    "immersive",
    "mckinsey",
    "consulting",
    "detailed analysis",
    "comprehensive",
    "claim_map",
    "narrative_spine",
    "uploaded_content",
    "structured_data",
)

SIMPLE_KEYWORDS: Final[tuple[str, ...]] = (
    "hello world",
    "simple",
    "basic",
    "card",
    "counter",
    "list",
    "table",
    "faq",
    "checklist",
    "pricing page",
    "one section",
    "single section",
)


def route_anthropic_model(
    *,
    step_name: str,
    user_message: str,
    default_model: str | None = None,
    fast_model: str | None = None,
) -> tuple[str, str]:
    fallback_model = (default_model or DEFAULT_COMPLEX_MODEL).strip() or DEFAULT_COMPLEX_MODEL
    routed_fast_model = (fast_model or DEFAULT_FAST_MODEL).strip() or DEFAULT_FAST_MODEL
    normalized_step = (step_name or "").strip().lower()
    lower_message = (user_message or "").lower()
    message_len = len(user_message or "")

    if normalized_step in FAST_REPAIR_STEPS:
        return routed_fast_model, "fast_json_repair"

    if normalized_step not in ADAPTIVE_STEPS:
        return fallback_model, "default_model"

    if any(keyword in lower_message for keyword in COMPLEX_KEYWORDS):
        return fallback_model, "complex_keyword_match"

    if message_len > 12000:
        return fallback_model, "message_too_large"

    if normalized_step in {"feedback_plan_revision", "feedback_plan_revision_retry"}:
        if message_len > 7000 or "<feedback_notes>" in lower_message:
            return fallback_model, "feedback_revision_complexity"
        return routed_fast_model, "feedback_revision_compact"

    if normalized_step in {"section_append", "section_regeneration"}:
        if message_len > 5000:
            return fallback_model, "section_prompt_too_large"
        if any(keyword in lower_message for keyword in SIMPLE_KEYWORDS):
            return routed_fast_model, "simple_section_prompt"
        return fallback_model, "section_quality_bias"

    if any(keyword in lower_message for keyword in SIMPLE_KEYWORDS) and message_len < 2500:
        return routed_fast_model, "simple_prompt"

    if message_len < 1800 and "<structured_data>" not in lower_message and "<uploaded_content>" not in lower_message:
        return routed_fast_model, "compact_prompt"

    return fallback_model, "default_complex_path"
