"""Intelligent routing logic for video generation requests.

Routes to HeyGen for avatar/presenter videos and Veo for creative/cinematic content.

Generated by GRIMLOCK MCP Factory
"""

import re

# Keywords that strongly suggest HeyGen (avatar-based) content
HEYGEN_KEYWORDS = {
    "speak",
    "speaking",
    "present",
    "presenter",
    "presenting",
    "explain",
    "explaining",
    "tutorial",
    "avatar",
    "host",
    "narrator",
    "narrate",
    "narrating",
    "talking",
    "talk",
    "announce",
    "announcing",
    "announcer",
    "introduce",
    "introducing",
    "introduction",
    "walk through",
    "walks through",
    "walkthrough",
    "demo",
    "demonstrate",
    "demonstration",
    "spokesperson",
    "spokesperson",
    "instructor",
    "teacher",
    "guide",
    "guiding",
    "lecture",
    "lecturing",
    "webcam",
    "face",
    "person speaking",
    "talking head",
    "news anchor",
    "reporter",
}

# Keywords that strongly suggest Veo (creative/cinematic) content
VEO_KEYWORDS = {
    "cinematic",
    "scene",
    "scenes",
    "visual",
    "visuals",
    "b-roll",
    "broll",
    "animation",
    "animated",
    "shot",
    "shots",
    "footage",
    "landscape",
    "landscapes",
    "abstract",
    "artistic",
    "dramatic",
    "aerial",
    "drone",
    "timelapse",
    "time-lapse",
    "time lapse",
    "slow motion",
    "slow-motion",
    "dolly",
    "pan",
    "panning",
    "zoom",
    "zooming",
    "tracking shot",
    "establishing shot",
    "wide shot",
    "close-up",
    "closeup",
    "macro",
    "nature",
    "wildlife",
    "cityscape",
    "sunset",
    "sunrise",
    "ocean",
    "forest",
    "mountain",
    "clouds",
    "rain",
    "fire",
    "water",
    "explosion",
    "effects",
    "vfx",
    "cgi",
    "render",
    "3d",
    "motion graphics",
    "particle",
    "ambient",
    "atmospheric",
    "mood",
    "aesthetic",
}


def detect_service(prompt: str) -> str:
    """Detect which service to use based on prompt content.

    Args:
        prompt: The video generation prompt

    Returns:
        'heygen' for avatar/presenter content, 'veo' for creative content
    """
    prompt_lower = prompt.lower()

    # Count keyword matches for each service
    heygen_score = 0
    veo_score = 0

    for keyword in HEYGEN_KEYWORDS:
        if keyword in prompt_lower:
            heygen_score += 1
            # Multi-word keywords get extra weight
            if " " in keyword:
                heygen_score += 1

    for keyword in VEO_KEYWORDS:
        if keyword in prompt_lower:
            veo_score += 1
            if " " in keyword:
                veo_score += 1

    # Check for explicit avatar/person references
    if re.search(r"\b(person|man|woman|human|someone)\s+(speaking|talking|explaining)", prompt_lower):
        heygen_score += 3

    # Check for explicit cinematic references
    if re.search(r"\b(camera\s+(movement|motion|angle)|lens|depth of field|bokeh)", prompt_lower):
        veo_score += 2

    # If prompt mentions specific text to say/speak, it's HeyGen
    if re.search(r'(say|says|saying|speak|speaks|speaking)[:\s]+"', prompt_lower):
        heygen_score += 3

    # If prompt is about creating a script/speech, it's HeyGen
    if re.search(r"\b(script|speech|dialogue|monologue|voiceover)\b", prompt_lower):
        heygen_score += 2

    # Default to Veo if no clear signal (creative content is more common)
    # But if heygen_score is at least 1 and higher than veo, use HeyGen
    if heygen_score > veo_score:
        return "heygen"

    return "veo"


def validate_service_hint(hint: str | None) -> str | None:
    """Validate and normalize service hint.

    Args:
        hint: User-provided service hint

    Returns:
        Normalized hint or None if invalid
    """
    if hint is None:
        return None

    hint_lower = hint.lower().strip()
    if hint_lower in ("heygen", "hey gen", "hey-gen"):
        return "heygen"
    if hint_lower in ("veo", "google veo", "google-veo", "gemini"):
        return "veo"

    return None
