"""Rule-based intent routing for assistant mode."""

from __future__ import annotations

import re
import unicodedata
from enum import Enum


class IntentCategory(str, Enum):
    """Supported assistant intent categories."""

    SYSTEM = "SYSTEM"
    TASKS = "TASKS"
    TODOIST = "TASKS"
    ENGAGEMENT = "ENGAGEMENT"
    VAULT = "VAULT"
    GENERAL = "GENERAL"


SYSTEM_PATTERNS = (
    r"\bwhat\s+day\s+is\s+(it|today)\b",
    r"\bwhat(?:s| is)\s+the\s+date\b",
    r"\bcurrent\s+date\b",
    r"\bcurrent\s+time\b",
    r"\bwhat\s+time\s+is\s+it\b",
    r"\btime\s+now\b",
    r"\btodays\s+date\b",
    r"\bque\s+dia\s+es\s+hoy\b",
    r"\bfecha\s+de\s+hoy\b",
    r"\bhora\s+actual\b",
    r"\bque\s+hora\s+es\b",
)

TASK_DIRECT_PATTERNS = (
    r"\btodoist\b",
    r"\bgoogle\s+tasks?\b",
    r"\bmicrosoft\s+to\s+do\b",
    r"\bmicrosoft\s+todo\b",
    r"\btrello\b",
    r"\bgithub\s+issues?\b",
    r"\bissue\b",
    r"\bbirthday\b",
    r"\bcumple\b",
    r"\bcumpleanos\b",
    r"\bwhen\s+is\b",
    r"\bcuando\s+es\b",
)

TASK_ACTION_PHRASES = (
    "task",
    "tasks",
    "create task",
    "add task",
    "new task",
    "mark done",
    "complete task",
    "do i have",
    "what do i have",
    "what should i do",
    "due",
    "tarea",
    "tareas",
    "crear tarea",
    "crea tarea",
    "agrega tarea",
    "anade tarea",
    "completa tarea",
    "que tengo",
    "que debo",
    "que hacer",
    "que hago",
    "que tengo que hacer",
    "para manana",
    "hoy",
)

ENGAGEMENT_PATTERNS = (
    r"\bengagement\b",
    r"\bcoverage\b",
    r"\bphase\b",
    r"\brecon\b",
    r"\benumeration\b",
    r"\binitial\s+access\b",
    r"\bpriv(?:ilege)?\s+esc(?:alation)?\b",
    r"\bpost[-\s]?exploitation\b",
    r"\btimeline\b",
    r"\bfindings?\b",
    r"\bevents?\b",
    r"\brisk\b",
)

VAULT_PATTERNS = (
    r"\bsegun\s+mis\s+notas\b",
    r"\ben\s+mis\s+notas\b",
    r"\ben\s+mi\s+vault\b",
    r"\bbusca\s+en\s+mis\s+(?:notas|apuntes|vault)\b",
    r"\bin\s+my\s+notes\b",
    r"\bfrom\s+my\s+notes\b",
    r"\baccording\s+to\s+my\s+notes\b",
    r"\bsearch\s+my\s+vault\b",
    r"\bmy\s+vault\b",
    r"\bmy\s+notes\b",
)


def normalize_text(text: str) -> str:
    """Normalize text for bilingual, accent-insensitive intent detection."""
    normalized = unicodedata.normalize("NFKD", text.lower())
    without_accents = "".join(ch for ch in normalized if not unicodedata.combining(ch))
    without_punct = re.sub(r"[^\w\s]", " ", without_accents)
    return " ".join(without_punct.split())


def _matches_any(text: str, patterns: tuple[str, ...]) -> bool:
    """Return True if any regex pattern matches."""
    return any(re.search(pattern, text) for pattern in patterns)


def _contains_any_phrase(text: str, phrases: tuple[str, ...]) -> bool:
    """Return True if normalized text contains any phrase."""
    return any(phrase in text for phrase in phrases)


def detect_intent(message: str) -> IntentCategory:
    """Detect one intent category using simple keyword heuristics."""
    text = normalize_text(message)

    if _matches_any(text, SYSTEM_PATTERNS):
        return IntentCategory.SYSTEM

    if _matches_any(text, VAULT_PATTERNS):
        return IntentCategory.VAULT

    if "vault" in text and _contains_any_phrase(text, ("search", "busca", "notes", "notas", "apuntes")):
        return IntentCategory.VAULT

    if _contains_any_phrase(text, ("notion", "github", "notes", "notas", "apuntes")) and _contains_any_phrase(
        text,
        ("search", "busca", "summary", "resumen", "according", "segun", "from"),
    ):
        return IntentCategory.VAULT

    if _matches_any(text, TASK_DIRECT_PATTERNS):
        return IntentCategory.TASKS

    task_match = _contains_any_phrase(text, TASK_ACTION_PHRASES)
    if task_match:
        return IntentCategory.TASKS

    if _matches_any(text, ENGAGEMENT_PATTERNS):
        return IntentCategory.ENGAGEMENT

    if re.search(r"\bengagement\s+#?\d+\b", text):
        return IntentCategory.ENGAGEMENT

    return IntentCategory.GENERAL


def extract_engagement_id(message: str) -> int | None:
    """Extract engagement id from free text if present."""
    text = normalize_text(message)
    match = re.search(r"\bengagement\s+#?(\d+)\b", text)
    if match:
        return int(match.group(1))

    match = re.search(r"\bcoverage\s+#?(\d+)\b", text)
    if match:
        return int(match.group(1))

    return None
