"""
Soft Proactivity Layer — Humanized Stepan v3.

Додає РІВНО 1 коротке речення в кінець deep-відповіді за суворих умов.
Rule-based, без LLM.

Умови спрацювання (всі мають виконуватись одночасно):
  1. depth == "deep"
  2. reflection is None OR reflection["confidence"] >= 0.7
  3. interaction_count % 10 == 0  (кожна 10-та взаємодія)
  4. В known_intents один intent зустрівся >= 3 рази
  5. НЕ (preferred_style == "brief" AND response вже містить "?")

Речення ≤ 120 символів, без "!".

Telemetry:
  AGX_STEPAN_METRIC proactivity_added user_id=h:... intent=... style=...
  AGX_STEPAN_METRIC proactivity_skipped reason=... (якщо умови не пройдені)
"""

from __future__ import annotations

import logging
import random
from typing import Any

from crews.agromatrix_crew.telemetry import tlog

logger = logging.getLogger(__name__)

# ─── Phrase banks ─────────────────────────────────────────────────────────────

_PROACTIVE_GENERIC = [
    "За потреби можу швидко зібрати план/факт за вчора.",
    "Якщо хочеш, можу підготувати короткий чек-лист на ранок.",
    "Можу також порівняти з попереднім тижнем — скажи якщо потрібно.",
    "Якщо зміниться пріоритет — одразу скажи, скорегуємо.",
    "Якщо потрібна деталізація по конкретному полю — кажи.",
    "Готовий зібрати зведення по полях якщо буде потреба.",
    "Можу також перевірити статуси по відкритих задачах.",
]

_PROACTIVE_IOT = [
    "Якщо хочеш, перевірю датчики по ключових полях.",
    "Можу також відслідкувати вологість по полях у реальному часі.",
    "За потреби — швидкий звіт по датчиках.",
    "Якщо є аномалії на датчиках — дам знати одразу.",
]

_PROACTIVE_PLAN = [
    "За потреби можу оновити план після нових даних.",
    "Якщо хочеш — зведу всі задачі на тиждень в один список.",
    "Можу ще раз пройтись по пріоритетах якщо щось зміниться.",
    "Якщо план зміниться — оновлю фільтри автоматично.",
]

_PROACTIVE_SUSTAINABILITY = [
    "Можу також подивитись показники сталості за вибраний період.",
    "Якщо потрібно — порівняємо з нормою по регіону.",
]

# intent → bank mapping
_INTENT_BANK: dict[str, list[str]] = {
    "iot_sensors":   _PROACTIVE_IOT,
    "plan_day":      _PROACTIVE_PLAN,
    "plan_week":     _PROACTIVE_PLAN,
    "plan_vs_fact":  _PROACTIVE_PLAN,
    "sustainability": _PROACTIVE_SUSTAINABILITY,
}


def _top_intent(known_intents: list | None) -> tuple[str | None, int]:
    """
    Знаходить intent з найвищою частотою у known_intents.
    known_intents = list[str]  (повторення дозволені, кожен запис = 1 взаємодія).
    Повертає (intent, count) або (None, 0).
    """
    if not known_intents:
        return None, 0
    freq: dict[str, int] = {}
    for item in known_intents:
        if isinstance(item, str):
            freq[item] = freq.get(item, 0) + 1
    if not freq:
        return None, 0
    top = max(freq, key=lambda k: freq[k])
    return top, freq[top]


def maybe_add_proactivity(
    response: str,
    user_profile: dict,
    depth: str,
    reflection: dict | None = None,
) -> tuple[str, bool]:
    """
    Можливо додає 1 проактивне речення до відповіді.

    Аргументи:
      response      — поточна відповідь Степана
      user_profile  — UserProfile dict
      depth         — "light" або "deep"
      reflection    — результат reflect_on_response або None

    Повертає:
      (new_response, was_added: bool)
    """
    user_id = user_profile.get("user_id", "")

    try:
        # Умова 1: тільки deep
        if depth != "deep":
            tlog(logger, "proactivity_skipped", user_id=user_id, reason="not_deep")
            return response, False

        # Умова 2: confidence >= 0.7 або reflection відсутній
        if reflection is not None:
            confidence = reflection.get("confidence", 1.0)
            if confidence < 0.7:
                tlog(logger, "proactivity_skipped", user_id=user_id,
                     reason="low_confidence", confidence=round(confidence, 2))
                return response, False

        # Умова 3: interaction_count % 10 == 0
        count = user_profile.get("interaction_count", 0)
        if count == 0 or count % 10 != 0:
            tlog(logger, "proactivity_skipped", user_id=user_id,
                 reason="not_tenth", interaction_count=count)
            return response, False

        # Умова 4: top intent зустрічався >= 3 рази
        known_intents = user_profile.get("known_intents", [])
        top_intent, top_count = _top_intent(known_intents)
        if top_count < 3:
            tlog(logger, "proactivity_skipped", user_id=user_id,
                 reason="intent_freq_low", top_intent=top_intent, top_count=top_count)
            return response, False

        # Умова 5: не нав'язувати якщо brief і вже є питання
        preferred_style = user_profile.get("preferences", {}).get("report_format", "")
        style = user_profile.get("style", "")
        is_brief = preferred_style == "brief" or style == "concise"
        if is_brief and "?" in response:
            tlog(logger, "proactivity_skipped", user_id=user_id,
                 reason="brief_with_question", style=style)
            return response, False

        # Обрати банк фраз за intent
        bank = _INTENT_BANK.get(top_intent or "", _PROACTIVE_GENERIC)
        seed = hash(f"{user_id}:{count}") % (2**32)
        rng = random.Random(seed)
        phrase = rng.choice(bank)

        # Гарантуємо ≤ 120 символів і без "!"
        phrase = phrase[:120].replace("!", "")

        new_response = response.rstrip() + "\n\n" + phrase
        tlog(logger, "proactivity_added", user_id=user_id,
             intent=top_intent, style=style)
        return new_response, True

    except Exception as exc:
        logger.warning("maybe_add_proactivity error (no-op): %s", exc)
        return response, False
