#!/usr/bin/env python3
"""Карта: интент joint-модели → вызов tool планшета (smart-home-tablet).

Модель отдаёт (intent, slots) — «что сделать» и «куски текста параметров».
Приведение к боевому tool-call (направление, действие, режим в enum; «15 минут»
→ секунды; «Дани» → daniil) — здесь, на стороне потребителя. Модель конвенций
приложения не знает, она видела только текст запроса.

Это референс для интеграции в app/api/voice/chat/route.ts. На проде логика
переписывается на TypeScript, но соответствие интент→tool берётся отсюда.
"""
import re

# intent → (tool_name, фиксированные аргументы). Слоты домешиваются отдельно.
INTENT_TO_TOOL = {
    "weather_get":            ("get_weather", {}),
    "transport_to_center":    ("get_transport", {"direction": "to_center"}),
    "transport_from_center":  ("get_transport", {"direction": "from_center"}),
    "transport_all":          ("get_transport", {"direction": "all"}),
    "calendar_today":         ("get_today_events", {"range": "today"}),
    "calendar_week":          ("get_today_events", {"range": "week"}),
    "calendar_create":        ("create_event", {}),
    "timer_set":              ("set_timer", {}),
    "timer_add":              ("adjust_timer", {"sign": +1}),
    "timer_subtract":         ("adjust_timer", {"sign": -1}),
    "timer_cancel":           ("cancel_timer", {}),
    "notes_get":              ("get_notes", {}),
    "home_state":             ("get_smart_home_state", {}),
    "purifier_on":            ("control_air_purifier", {"action": "turn_on"}),
    "purifier_off":           ("control_air_purifier", {"action": "turn_off"}),
    "purifier_mode":          ("control_air_purifier", {"action": "set_mode"}),
    "light_on":               ("control_light", {"action": "turn_on"}),   # НОВЫЙ tool
    "light_off":              ("control_light", {"action": "turn_off"}),  # НОВЫЙ tool
    "music_play":             ("control_spotify", {"action": "play"}),
    "music_pause":            ("control_spotify", {"action": "pause"}),
    "music_resume":           ("control_spotify", {"action": "play"}),
    "music_next":             ("control_spotify", {"action": "next"}),
    "music_prev":             ("control_spotify", {"action": "previous"}),
    "music_volume":           ("control_spotify", {"action": "volume"}),
    "now_playing":            ("get_now_playing", {}),
}

OWNER_MAP = {
    "дани": "daniil", "даниил": "daniil", "даниила": "daniil",
    "даниилу": "daniil", "даня": "daniil", "мне": "daniil", "мой": "daniil",
    "света": "sveta", "свете": "sveta", "светы": "sveta", "свету": "sveta",
}

MODE_MAP = {
    "авто": "Auto", "автоматический": "Auto",
    "ночной": "Night", "ночь": "Night",
    "высокий": "High", "максимальный": "High", "турбо": "High",
    "максимум": "High", "тихий": "Night", "низкий": "Night",
}

_NUM_WORDS = {
    "полминуты": 30, "полчаса": 1800, "минуту": 60, "минуты": 60, "минут": 60,
    "полторы": 90, "полтора": 5400, "пару": 120, "несколько": 180,
}


def parse_duration_seconds(text):
    """«15 минут» → 900, «полтора часа» → 5400, «30 секунд» → 30.

    Грубый разбор для set/adjust таймера. На проде можно взять готовую
    JS-либу разбора длительности; здесь — референс.
    """
    t = text.lower().strip()
    if t in ("полчаса",):
        return 1800
    if t in ("полминуты",):
        return 30
    if t in ("полтора часа", "полтора",):
        return 5400
    if t in ("полторы минуты",):
        return 90
    m = re.search(r"(\d+)", t)
    n = int(m.group(1)) if m else 1
    if "сек" in t:
        return n
    if "час" in t:
        return n * 3600
    if "мин" in t:
        return n * 60
    return n * 60   # по умолчанию минуты


def to_tool_call(intent, slots):
    """(intent, slots) → {tool, args} или None для none/неизвестного."""
    if intent not in INTENT_TO_TOOL:
        return None
    tool, args = INTENT_TO_TOOL[intent]
    args = dict(args)

    if intent == "weather_get" and "city" in slots:
        # снять предлог: «в Питере» → «Питере» (город приложение нормализует само)
        args["city"] = re.sub(r"^в\s+", "", slots["city"], flags=re.I)

    elif intent == "calendar_create":
        if "title" in slots:
            args["title"] = slots["title"]
        if "date" in slots:
            args["date"] = slots["date"]     # «25 июля»/«завтра» → YYYY-MM-DD на стороне приложения
        if "time" in slots:
            args["start_time"] = slots["time"]
        args["owner"] = OWNER_MAP.get(slots.get("owner", "").lower().strip(), "daniil")

    elif intent in ("timer_set",):
        if "duration" in slots:
            args["seconds"] = parse_duration_seconds(slots["duration"])
        args.setdefault("label", "таймер")

    elif intent in ("timer_add", "timer_subtract"):
        sign = args.pop("sign", 1)
        secs = parse_duration_seconds(slots.get("duration", "1 минута"))
        args["delta_seconds"] = sign * secs
        args.setdefault("label", "таймер")

    elif intent == "purifier_mode":
        raw = slots.get("mode", "").lower().strip()
        # точное совпадение, затем подстрока (страховка от «ночной режим» и т.п.)
        mode = MODE_MAP.get(raw)
        if mode is None:
            mode = next((v for k, v in MODE_MAP.items() if k in raw), "Auto")
        args["mode"] = mode

    elif intent in ("light_on", "light_off"):
        if "device" in slots:
            args["device"] = slots["device"]   # приложение сопоставит с entity HA

    elif intent == "music_play":
        if "query" in slots:
            args["query"] = slots["query"]

    elif intent == "music_volume":
        m = re.search(r"(\d+)", slots.get("level", ""))
        if m:
            args["volume"] = int(m.group(1))

    return {"tool": tool, "args": args}


if __name__ == "__main__":
    # быстрая проверка карты без модели
    demo = [
        ("timer_set", {"duration": "15 минут"}),
        ("timer_add", {"duration": "5 минут"}),
        ("calendar_create", {"title": "встречу", "date": "25 июля",
                             "time": "13 часов", "owner": "Дани"}),
        ("purifier_mode", {"mode": "ночной"}),
        ("music_volume", {"level": "50 процентов"}),
        ("weather_get", {"city": "в Питере"}),
    ]
    for intent, slots in demo:
        print(f"{intent:16s} {slots}  ->  {to_tool_call(intent, slots)}")
