"""
Depth Classifier для Степана.

classify_depth(text, has_doc_context, last_topic, user_profile) → "light" | "deep"

Без залежності від crewai — чистий Python.
Fail-closed: помилка → "deep".
"""

from __future__ import annotations

import logging
import re
from typing import Literal

from crews.agromatrix_crew.telemetry import tlog

logger = logging.getLogger(__name__)

# ─── Patterns ────────────────────────────────────────────────────────────────

_DEEP_ACTION_RE = re.compile(
    r'\b(зроби|зробити|перевір|перевірити|порахуй|порахувати|підготуй|підготувати'
    r'|онови|оновити|створи|створити|запиши|записати|зафіксуй|зафіксувати'
    r'|внеси|внести|проаналізуй|проаналізувати|порівняй|порівняти'
    r'|розрахуй|розрахувати|сплануй|спланувати|покажи|показати'
    r'|заплануй|запланувати|закрий|закрити|відкрий|відкрити)\b',
    re.IGNORECASE | re.UNICODE,
)

_DEEP_URGENT_RE = re.compile(
    r'\b(аварія|терміново|критично|тривога|невідкладно|alert|alarm|critical)\b',
    re.IGNORECASE | re.UNICODE,
)

_DEEP_DATA_RE = re.compile(
    r'\b(\d[\d.,]*)\s*(га|кг|л|т|мм|°c|°f|%|гектар|літр|тонн)',
    re.IGNORECASE | re.UNICODE,
)

_LIGHT_GREET_RE = re.compile(
    r'^(привіт|добрий\s+\w+|доброго\s+\w+|hello|hi|hey|ок|окей|добре|зрозумів|зрозуміла'
    r'|дякую|дякуй|спасибі|чудово|супер|ясно|зрозуміло|вітаю|вітання)[\W]*$',
    re.IGNORECASE | re.UNICODE,
)

_DEEP_INTENTS = frozenset({
    'plan_week', 'plan_day', 'plan_vs_fact', 'show_critical_tomorrow', 'close_plan'
})

# ─── Intent detection (inline, no crewai dependency) ─────────────────────────

def _detect_intent(text: str) -> str:
    t = text.lower()
    if 'сплануй' in t and 'тиж' in t:
        return 'plan_week'
    if 'сплануй' in t:
        return 'plan_day'
    if 'критично' in t or 'на завтра' in t:
        return 'show_critical_tomorrow'
    if 'план/факт' in t or 'план факт' in t:
        return 'plan_vs_fact'
    if 'закрий план' in t:
        return 'close_plan'
    return 'general'


# ─── Public API ───────────────────────────────────────────────────────────────

def classify_depth(
    text: str,
    has_doc_context: bool = False,
    last_topic: str | None = None,
    user_profile: dict | None = None,
    session: dict | None = None,
) -> Literal["light", "deep"]:
    """
    Визначає глибину обробки запиту.

      light — Степан відповідає сам, без запуску під-агентів
      deep  — повний orchestration flow з делегуванням

    v3: session — SessionContext; якщо last_depth=="light" і короткий follow-up
        без action verbs → stability_guard повертає "light" без подальших перевірок.

    Правило fail-closed: при будь-якій помилці повертає "deep".
    """
    try:
        t = text.strip()

        # ── Intent Stability Guard (v3) ────────────────────────────────────────
        # Якщо попередня взаємодія була light і поточне повідомлення ≤6 слів
        # без action verbs / urgent → утримуємо в light без зайвих перевірок.
        if (
            session
            and session.get("last_depth") == "light"
            and not _DEEP_ACTION_RE.search(t)
            and not _DEEP_URGENT_RE.search(t)
        ):
            word_count_guard = len(t.split())
            if word_count_guard <= 6:
                tlog(logger, "stability_guard_triggered", chat_id="n/a",
                     words=word_count_guard, last_depth="light")
                return "light"

        # Explicit greetings / social acks → always light
        if _LIGHT_GREET_RE.match(t):
            tlog(logger, "depth", depth="light", reason="greeting")
            return "light"

        word_count = len(t.split())

        # Follow-up heuristic: ≤6 words + last_topic + no action verbs + no urgent → light
        # Handles: "а на завтра?", "а по полю 12?", "а якщо дощ?" etc.
        if (
            word_count <= 6
            and last_topic is not None
            and not _DEEP_ACTION_RE.search(t)
            and not _DEEP_URGENT_RE.search(t)
        ):
            tlog(logger, "depth", depth="light", reason="short_followup_last_topic",
                 words=word_count, last_topic=last_topic)
            return "light"

        # Very short follow-ups without last_topic → light (≤4 words, no verbs)
        if word_count <= 4 and not _DEEP_ACTION_RE.search(t) and not _DEEP_URGENT_RE.search(t):
            tlog(logger, "depth", depth="light", reason="short_followup", words=word_count)
            return "light"

        # Active doc context → deep
        if has_doc_context:
            tlog(logger, "depth", depth="deep", reason="has_doc_context")
            return "deep"

        # Urgency keywords → always deep
        if _DEEP_URGENT_RE.search(t):
            tlog(logger, "depth", depth="deep", reason="urgent_keyword")
            return "deep"

        # Explicit action verbs → deep
        if _DEEP_ACTION_RE.search(t):
            tlog(logger, "depth", depth="deep", reason="action_verb")
            return "deep"

        # Numeric measurements → deep
        if _DEEP_DATA_RE.search(t):
            tlog(logger, "depth", depth="deep", reason="numeric_data")
            return "deep"

        # Intent-based deep trigger
        detected = _detect_intent(t)
        if detected in _DEEP_INTENTS:
            tlog(logger, "depth", depth="deep", reason="intent", intent=detected)
            return "deep"

        tlog(logger, "depth", depth="light", reason="no_deep_signal")
        return "light"

    except Exception as exc:
        logger.warning("classify_depth error, defaulting to deep: %s", exc)
        return "deep"
