"""Claude Code hook: logs conversation turns to the active work folder.

Invoked by Claude Code hooks on UserPromptSubmit and Stop events.
Reads JSON from stdin, appends timestamped entries to logs/conversation.log
in the active work folder.

Usage: python3 -m mixersystem.hooks.conversation_logger
"""

import json
import sys
from datetime import datetime
from pathlib import Path


def _find_project_root(start: Path) -> Path | None:
    """Walk up from start to find the nearest directory containing .mixer/."""
    current = start.resolve()
    while True:
        if (current / ".mixer").is_dir():
            return current
        parent = current.parent
        if parent == current:
            return None
        current = parent


def _get_active_work_folder(project_root: Path) -> str | None:
    """Read the active work folder from .mixer/active-work-folder."""
    state_file = project_root / ".mixer" / "active-work-folder"
    if not state_file.is_file():
        return None
    content = state_file.read_text().strip()
    return content if content else None


def _append_log(work_folder: Path, role: str, text: str) -> None:
    """Append a timestamped entry to logs/conversation.log."""
    log_dir = work_folder / "logs"
    log_dir.mkdir(parents=True, exist_ok=True)
    log_file = log_dir / "conversation.log"

    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    entry = f"[{timestamp}] {role}\n{text}\n\n"

    with open(log_file, "a") as f:
        f.write(entry)


def _extract_last_assistant_text(transcript_path: str) -> str | None:
    """Read transcript JSONL and extract text from the last assistant message."""
    path = Path(transcript_path)
    if not path.is_file():
        return None

    last_assistant = None
    for line in path.read_text().splitlines():
        line = line.strip()
        if not line:
            continue
        try:
            entry = json.loads(line)
        except json.JSONDecodeError:
            continue
        if entry.get("type") == "assistant":
            last_assistant = entry

    if not last_assistant:
        return None

    # Extract text content blocks only (skip tool_use blocks)
    message = last_assistant.get("message", {})
    content = message.get("content", [])
    text_parts = []
    for block in content:
        if isinstance(block, dict) and block.get("type") == "text":
            text_parts.append(block.get("text", ""))
        elif isinstance(block, str):
            text_parts.append(block)

    return "\n".join(text_parts).strip() if text_parts else None


def main() -> None:
    raw = sys.stdin.read()
    if not raw.strip():
        return

    try:
        data = json.loads(raw)
    except json.JSONDecodeError:
        return

    cwd = data.get("cwd", "")
    if not cwd:
        return

    project_root = _find_project_root(Path(cwd))
    if not project_root:
        return

    active = _get_active_work_folder(project_root)
    if not active:
        return

    work_folder = Path(active)
    if not work_folder.is_dir():
        return

    event = data.get("hook_event_name", "")

    if event == "UserPromptSubmit":
        prompt = data.get("prompt", "")
        if prompt:
            _append_log(work_folder, "USER", prompt)

    elif event == "Stop":
        transcript_path = data.get("transcript_path", "")
        if transcript_path:
            text = _extract_last_assistant_text(transcript_path)
            if text:
                _append_log(work_folder, "ASSISTANT", text)


if __name__ == "__main__":
    main()
