#!/usr/bin/env python3

import json
from pathlib import Path
from typing import Any


def is_noise_text(text: str) -> bool:
    normalized = text.strip().lower()
    if not normalized:
        return True
    noise_markers = (
        "<system-reminder>",
        "request interrupted by user",
        "todowrite was not called yet",
        "todo list updated",
        "tool execution cancelled by user",
    )
    return any(marker in normalized for marker in noise_markers)


def extract_text(value: Any) -> list[str]:
    texts: list[str] = []
    if isinstance(value, str):
        if value.strip() and not is_noise_text(value):
            texts.append(value)
        return texts
    if isinstance(value, list):
        for item in value:
            texts.extend(extract_text(item))
        return texts
    if isinstance(value, dict):
        for key in ("text", "content", "message", "value"):
            if key in value:
                texts.extend(extract_text(value[key]))
        return texts
    return texts


def role_of(obj: dict[str, Any]) -> str | None:
    for key in ("role", "speaker", "author", "type"):
        value = obj.get(key)
        if isinstance(value, str):
            return value.lower()
    return None


def collect_messages(transcript_path: Path) -> list[dict[str, str]]:
    if not transcript_path.exists():
        return []

    messages: list[dict[str, str]] = []

    with transcript_path.open("r", encoding="utf-8") as handle:
        for raw_line in handle:
            line = raw_line.strip()
            if not line:
                continue
            try:
                entry = json.loads(line)
            except json.JSONDecodeError:
                continue

            candidates: list[dict[str, Any]] = []
            if isinstance(entry, dict):
                candidates.append(entry)
                for key in ("message", "payload", "data"):
                    nested = entry.get(key)
                    if isinstance(nested, dict):
                        candidates.append(nested)

            for candidate in candidates:
                role = role_of(candidate)
                if role not in {"user", "assistant", "model"}:
                    continue
                texts = extract_text(candidate)
                merged = "\n".join(
                    part.strip() for part in texts if part.strip()
                ).strip()
                if merged and not is_noise_text(merged):
                    messages.append({"role": role, "text": merged})

    return messages


def find_last_assistant_text(transcript_path: Path) -> str | None:
    last_text: str | None = None
    for message in collect_messages(transcript_path):
        if message["role"] in {"assistant", "model"}:
            last_text = message["text"]
    return last_text
