#!/usr/bin/env python3
"""Statusline plugin: build conversation message map.

Writes $STATUSLINE_SESSION_DIR/chatmap.json with role/prefix/label/description
for each user/assistant message in the transcript.

Standalone executable AND importable. No imports from the statusline package —
this file is self-contained when copied to statusline.d/.
"""
import json
import os
import sys
from pathlib import Path

PREFIX_LEN = 40


def extract_prefix(entry):
    msg = entry.get("message", {})
    content = msg.get("content")

    if isinstance(content, str):
        return content

    if isinstance(content, list):
        parts = []
        for block in content:
            if not isinstance(block, dict):
                continue
            btype = block.get("type")
            if btype == "text":
                parts.append(block.get("text", ""))
            elif btype == "tool_use":
                parts.append(f"[{block.get('name', 'tool')}]")
            elif btype == "tool_result":
                rc = block.get("content", "")
                if isinstance(rc, list):
                    rc = " ".join(
                        item.get("text", "") for item in rc if isinstance(item, dict)
                    )
                parts.append(str(rc))
        return " ".join(p for p in parts if p)

    return ""


def role_for(entry):
    etype = entry.get("type")
    if etype == "user":
        return "user"
    if etype == "assistant":
        return "asst"
    return etype or "?"


def run(session_data, session_dir):
    """Build chatmap.json from session_data dict into session_dir.

    Importable entry point for testing.
    """
    transcript = session_data.get("transcript_path")
    if not transcript:
        return

    out_dir = Path(session_dir)
    out_dir.mkdir(parents=True, exist_ok=True)
    map_file = out_dir / "chatmap.json"

    # Load existing data to preserve labels/descriptions
    existing_messages = []
    last_index = 0
    try:
        existing = json.loads(map_file.read_text())
        existing_messages = existing.get("messages", [])
        last_index = existing.get("last_index", 0)
    except Exception:
        pass

    messages = []
    try:
        with open(transcript, "r") as f:
            for raw in f:
                raw = raw.strip()
                if not raw:
                    continue
                try:
                    entry = json.loads(raw)
                except json.JSONDecodeError:
                    continue

                etype = entry.get("type")
                if etype not in ("user", "assistant"):
                    continue

                prefix = extract_prefix(entry).replace("\n", " ").strip()
                if len(prefix) > PREFIX_LEN:
                    prefix = prefix[: PREFIX_LEN - 1] + "\u2026"

                idx = len(messages)
                label = ""
                description = ""
                if idx < len(existing_messages):
                    prev = existing_messages[idx]
                    if isinstance(prev, dict):
                        label = prev.get("label", "")
                        description = prev.get("description", "")

                messages.append({
                    "role": role_for(entry),
                    "prefix": prefix,
                    "label": label,
                    "description": description,
                })
    except Exception:
        return

    map_file.write_text(json.dumps({
        "messages": messages,
        "last_index": last_index,
        "transcript_path": transcript,
    }))


def main():
    session_dir = os.environ.get("STATUSLINE_SESSION_DIR")
    if not session_dir:
        return

    try:
        session_data = json.load(sys.stdin)
    except Exception:
        return

    run(session_data, session_dir)


if __name__ == "__main__":
    main()
