"""
transcript.py — Parse Claude Code JSONL transcripts into the messages table.

Claude Code transcript format (one JSON object per line):
  type "user"      → message.role=user,      message.content = str | list[block]
  type "assistant" → message.role=assistant,  message.content = list[block]

Content blocks:
  {"type": "text",        "text": "..."}
  {"type": "thinking",    "thinking": "..."}   (skip)
  {"type": "tool_use",    "id": "...", "name": "...", "input": {...}}
  {"type": "tool_result", "tool_use_id": "...", "content": str | list}
"""

from __future__ import annotations

import json
from pathlib import Path
from typing import Optional


def process_transcript(
    transcript_path: str,
    session_id: Optional[str] = None,
    offset: int = 0,
) -> tuple[int, int]:
    """
    Parse the JSONL transcript starting from line `offset` and insert new messages.
    Returns (inserted, new_offset) where new_offset is the total lines read.
    Pass offset=0 to process from the beginning (full index).
    """
    from . import db

    path = Path(transcript_path)
    if not path.exists():
        return 0, offset

    inserted = 0
    line_num  = 0
    with open(path, encoding="utf-8") as f:
        for raw in f:
            if line_num < offset:
                line_num += 1
                continue

            raw = raw.strip()
            line_num += 1
            if not raw:
                continue
            try:
                entry = json.loads(raw)
            except json.JSONDecodeError:
                continue

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

            msg  = entry.get("message", {})
            uuid = entry.get("uuid")
            if not uuid:
                continue

            sid   = entry.get("sessionId") or session_id
            ts    = entry.get("timestamp")
            cwd   = entry.get("cwd")
            model = msg.get("model")

            content = msg.get("content", "")
            text, tool_calls, tool_results = _parse_content(content)

            db.insert_message(
                uuid=uuid,
                role=role,
                session_id=sid,
                parent_uuid=entry.get("parentUuid"),
                text=text or None,
                tool_calls=tool_calls or [],
                tool_results=tool_results or [],
                timestamp=ts,
                cwd=cwd,
                model=model,
            )
            inserted += 1

    return inserted, line_num


def _parse_content(content) -> tuple[str, list, list]:
    """Extract (text, tool_calls, tool_results) from a content value."""
    text_parts: list[str] = []
    tool_calls:  list[dict] = []
    tool_results: list[dict] = []

    if isinstance(content, str):
        return content, [], []

    if not isinstance(content, list):
        return "", [], []

    for block in content:
        if not isinstance(block, dict):
            continue
        btype = block.get("type")
        if btype == "text":
            t = block.get("text", "").strip()
            if t:
                text_parts.append(t)
        elif btype == "tool_use":
            tool_calls.append({
                "id":    block.get("id"),
                "name":  block.get("name"),
                "input": block.get("input", {}),
            })
        elif btype == "tool_result":
            result_content = block.get("content", "")
            if isinstance(result_content, list):
                result_text = " ".join(
                    b.get("text", "") for b in result_content
                    if isinstance(b, dict) and b.get("type") == "text"
                )
            else:
                result_text = str(result_content)
            tool_results.append({
                "tool_use_id": block.get("tool_use_id"),
                "content":     result_text[:500],  # truncate large outputs
            })
        # skip "thinking" blocks

    return "\n".join(text_parts), tool_calls, tool_results
