"""Chatmap CLI: read and navigate the conversation message map.

Usage:
    statusline-chatmap read [--session-id <sid>]
    statusline-chatmap update [--session-id <sid>]
    statusline-chatmap update <id> --label "..." --description "..."
"""

import argparse
import json
import sys
from pathlib import Path

from ..discovery import discover_chatmap


def _load(map_file: Path) -> dict:
    try:
        return json.loads(map_file.read_text())
    except Exception:
        print("No chatmap data yet. Is the statusline configured?", file=sys.stderr)
        sys.exit(1)


def _save(map_file: Path, data: dict) -> None:
    map_file.write_text(json.dumps(data))


def _format_message(idx: int, msg) -> str:
    """Format a message for display: N. [label] prefix"""
    if isinstance(msg, str):
        return msg  # legacy format
    label = msg.get("label") or "unlabeled"
    prefix = msg.get("prefix", "")
    return f"{idx}. [{label}] {prefix}"


def _resolve_map_file(session_id=None) -> Path:
    """Find the chatmap.json to use, exiting on failure."""
    result = discover_chatmap(session_id)
    if result is None:
        if session_id:
            print(f"No chatmap.json found for session {session_id}", file=sys.stderr)
        else:
            print("No chatmap data yet. Is the statusline configured?", file=sys.stderr)
        sys.exit(1)
    return result


def cmd_read(args) -> None:
    map_file = _resolve_map_file(args.session_id)
    data = _load(map_file)
    messages = data.get("messages", [])
    last_index = data.get("last_index", 0)
    new = messages[last_index:]
    if not new:
        print("(no new messages)")
    else:
        for i, msg in enumerate(new, start=last_index + 1):
            print(_format_message(i, msg))


def cmd_update(args) -> None:
    map_file = _resolve_map_file(args.session_id)
    data = _load(map_file)

    if args.id is not None:
        messages = data.get("messages", [])
        idx = args.id - 1  # 1-based to 0-based
        if idx < 0 or idx >= len(messages):
            print(f"Invalid message id {args.id}. Valid range: 1-{len(messages)}", file=sys.stderr)
            sys.exit(1)

        msg = messages[idx]
        if isinstance(msg, str):
            msg = {"prefix": msg, "label": "", "description": "", "role": "?"}
            messages[idx] = msg

        if args.label is not None:
            msg["label"] = args.label
        if args.description is not None:
            msg["description"] = args.description

        _save(map_file, data)
        print(f"Updated message {args.id}: label={msg['label']!r} description={msg['description']!r}")
    else:
        data["last_index"] = len(data.get("messages", []))
        _save(map_file, data)
        print(f"Checkpoint set to {data['last_index']}")


def main() -> None:
    parser = argparse.ArgumentParser(prog="statusline-chatmap")
    sub = parser.add_subparsers(dest="command")

    read_p = sub.add_parser("read", help="Show messages since last checkpoint")
    read_p.add_argument("--session-id", type=str, default=None, help="Target a specific session")

    up = sub.add_parser("update", help="Set checkpoint or label a message")
    up.add_argument("id", nargs="?", type=int, default=None, help="Message id (1-based) to label")
    up.add_argument("--label", type=str, default=None, help="Label for the message")
    up.add_argument("--description", type=str, default=None, help="Description for the message")
    up.add_argument("--session-id", type=str, default=None, help="Target a specific session")

    args = parser.parse_args()
    if not args.command:
        parser.print_help()
        sys.exit(1)

    {"read": cmd_read, "update": cmd_update}[args.command](args)


if __name__ == "__main__":
    main()
