#!/usr/bin/env python3
"""Share Recap: turn one Diary conversation into a plain-text recap for the native macOS share
sheet (Messages / Mail / AirDrop / Notes / any installed NSSharingService).

Privacy design (per the fleet Shareability retrofit, 2026-07-14): the recipient gets an
ALLOWLISTED summary only — title, when, who with, the AI summary, and action items (as text, not
a count-only preview, since this travels over a private channel the user explicitly chose, not a
public link preview). It NEVER includes the raw transcript, audio, or any other conversation's
data. This is a per-conversation, explicit, opt-in action (the user clicks "Share" on one specific
card); nothing is shared automatically or in bulk.

This mirrors crm_export.py's text-building shape (same allowlisted fields) but frames the output
for a human recipient instead of a CRM note field, and adds the "Shared from RecapMuse" breadcrumb
that is the fleet's minimum badge/breadcrumb convention for a shared artifact.

Pure stdlib (system /usr/bin/python3). The Swift shell hands the returned `text` to
NSSharingServicePicker — never a link, since there is no web backend for recaps today
(see docs/shareability-spec.md).

  share_export.py --rec-dir DIR --conv-key "2026-06-16_09-08-54.aac"   # JSON: {ok, text, title}
"""
import json
import os
import sys


def _find_conv(diary, key):
    """Return (conversation, day) for the conversation whose first clip file == key."""
    for day in diary.get("days", []):
        for cv in day.get("conversations", []):
            clips = cv.get("clips") or []
            if clips and clips[0].get("file") == key:
                return cv, day
    return None, None


def _clean(s):
    return " ".join(str(s or "").split())


def format_share(cv, day):
    """Build the recipient-facing recap text. Deterministic, offline, no model call.
    Allowlisted fields only: title, who/when, summary, action items. No transcript."""
    lines = []
    title = _clean(cv.get("title")) or "Conversation recap"
    lines.append(title)

    ctx = []
    who = _clean(cv.get("who_with"))
    if who and who.lower() not in ("", "unclear", "no one / working solo"):
        ctx.append(who)
    when = _clean(cv.get("time_range"))
    heading = _clean(day.get("heading")) if day else ""
    if heading:
        ctx.append(heading + (" " + when if when else ""))
    elif when:
        ctx.append(when)
    if ctx:
        lines.append(" · ".join(ctx))

    summary = _clean(cv.get("summary"))
    if summary:
        lines.append("")
        lines.append(summary)

    steps = [a for a in (cv.get("action_items") or []) if _clean(a)]
    if steps:
        lines.append("")
        lines.append("Action items:")
        for a in steps:
            lines.append("- " + _clean(a))

    lines.append("")
    lines.append("— Shared from RecapMuse (Mac), a private meeting recap app.")
    return "\n".join(lines).strip() + "\n"


def run(rec_dir, key):
    diary_path = os.path.join(os.path.expanduser(rec_dir), "diary.json")
    if not os.path.exists(diary_path):
        return {"ok": False, "error": "no diary yet (organize your recordings first)"}
    try:
        diary = json.load(open(diary_path))
    except Exception as e:  # noqa: BLE001
        return {"ok": False, "error": "could not read diary.json: %s" % (str(e)[:120])}
    cv, day = _find_conv(diary, key)
    if not cv:
        return {"ok": False, "error": "conversation not found: %s" % key}
    text = format_share(cv, day)
    return {"ok": True, "text": text, "title": _clean(cv.get("title")) or "Conversation recap"}


def main(argv):
    rec_dir, key = "", ""
    if "--rec-dir" in argv:
        rec_dir = argv[argv.index("--rec-dir") + 1]
    if "--conv-key" in argv:
        key = argv[argv.index("--conv-key") + 1]
    if not rec_dir or not key:
        sys.stdout.write(json.dumps({"ok": False, "error": "usage: --rec-dir DIR --conv-key KEY"}))
        return
    sys.stdout.write(json.dumps(run(rec_dir, key)))


if __name__ == "__main__":
    main(sys.argv[1:])
