#!/usr/bin/env python3
"""
UserPromptSubmit hook — memory recall + team comments from plan-feed.

Two context sources, both printed to stdout (Claude Code injects them):
  1. semantic memory matches for the user's prompt (/memory/search)
  2. unseen @claude comments in this room (/mentions) — injected once as
     background context, then acked; Claude weighs them into its normal work
     instead of being interrupted to answer them.

Fails open: on timeout / error it prints nothing and never blocks the prompt.

Env overrides:
  PLAN_MEMORY_SEARCH_URL   full search endpoint URL (may carry ?site=&pw=)
  PLAN_MENTIONS_URL        full mentions URL, e.g.
                           https://host/mentions?site=X&room=Y&pw=token
                           (unset = comment injection off)
  PLAN_RECALL_MIN_SCORE    similarity floor, default 0.40
  PLAN_RECALL_LIMIT        max memories injected, default 3
"""

import json
import os
import sys
import urllib.parse
import urllib.request

SEARCH_URL = os.environ.get(
    "PLAN_MEMORY_SEARCH_URL",
    "https://vercel-server-jinyossatron11s-projects.vercel.app/memory/search",
)
MENTIONS_URL = (os.environ.get("PLAN_MENTIONS_URL") or "").strip()
MIN_SCORE = float(os.environ.get("PLAN_RECALL_MIN_SCORE", "0.40"))
LIMIT = int(os.environ.get("PLAN_RECALL_LIMIT", "3"))


def team_comments():
    """Fetch unseen @claude comments and ack them. Returns printable lines."""
    if not MENTIONS_URL:
        return []
    try:
        with urllib.request.urlopen(MENTIONS_URL, timeout=2) as r:
            rows = json.loads(r.read())
        if not isinstance(rows, list) or not rows:
            return []
        # ack so they are injected exactly once ("รับเรื่องแล้ว" on the feed)
        parsed = urllib.parse.urlparse(MENTIONS_URL)
        qs = urllib.parse.parse_qs(parsed.query)
        ack_url = f"{parsed.scheme}://{parsed.netloc}/mentions/ack"
        payload = json.dumps({
            "site": (qs.get("site") or ["default"])[0],
            "room": (qs.get("room") or ["general"])[0],
            "password": (qs.get("pw") or [""])[0],
            "ids": [m.get("id") for m in rows],
        }).encode("utf-8")
        req = urllib.request.Request(
            ack_url, data=payload, headers={"Content-Type": "application/json"})
        urllib.request.urlopen(req, timeout=2)
    except Exception:
        return []

    lines = ["💬 คอมเมนต์ใหม่จากทีมใน plan-feed (แนบให้ครั้งเดียว — นำไปพิจารณาประกอบงาน"
             " ถ้าเกี่ยวข้องกับสิ่งที่กำลังทำ หรือแตะประเด็นนั้นในคำตอบถัดไป):"]
    for m in rows:
        ctx = " ".join((m.get("question") or m.get("msg") or "").split())[:100]
        ctx = f' (บนข้อความเรื่อง: "{ctx}")' if ctx else ""
        lines.append(f"- {m.get('user') or 'someone'}: {m.get('text', '')}{ctx}")
    return lines


def main():
    try:
        payload = json.loads(sys.stdin.read())
    except Exception:
        return

    prompt = (payload.get("prompt") or "").strip()
    # Slash commands, shell passthroughs, and one-word prompts carry no
    # searchable intent — stay silent.
    if len(prompt) < 8 or prompt.startswith(("/", "!")):
        return

    out = team_comments()

    q = urllib.parse.quote_plus(prompt[:200])
    sep = "&" if "?" in SEARCH_URL else "?"   # URL may carry site=&pw= already
    url = f"{SEARCH_URL}{sep}q={q}&limit={LIMIT}"
    try:
        with urllib.request.urlopen(url, timeout=3) as r:
            rows = json.loads(r.read())
        hits = [r for r in rows
                if isinstance(r.get("score"), (int, float)) and r["score"] >= MIN_SCORE]
    except Exception:
        hits = []   # cold start or network issue — skip memories this turn

    if hits:
        if out:
            out.append("")
        out.append("🧠 ความจำที่เกี่ยวข้องจาก plan-feed (แนบอัตโนมัติ — ใช้เฉพาะที่ตรงประเด็น):")
        for r in hits:
            content = " ".join((r.get("content") or "").split())[:300]
            where = f"{r.get('site', '')}/{r.get('room', '')}"
            out.append(f"- [{r.get('time', '')}] ({where}, score {r['score']}) {content}")

    if out:
        print("\n".join(out))


if __name__ == "__main__":
    main()
    sys.exit(0)
