"""
sessions.py — List, view, and manage agent/chat sessions.
"""
import os
import re
from datetime import datetime
from pathlib import Path

from rich.console import Console
from rich.table import Table
from rich.panel import Panel
from rich.rule import Rule
from rich import box

from onefirewall_ai.config import SESSIONS_DIR

console = Console(force_terminal=True)


def _parse_session(path: Path) -> dict:
    """Extract metadata from a session file."""
    try:
        text = path.read_text(encoding="utf-8", errors="replace")
    except Exception:
        text = ""

    turns = 0
    first_user = ""
    last_user = ""
    last_assistant = ""

    for line in text.splitlines():
        if line.startswith("**User:** "):
            msg = line[len("**User:** "):].strip()
            turns += 1
            if not first_user:
                first_user = msg
            last_user = msg
        elif line.startswith("**Assistant:** "):
            last_assistant = line[len("**Assistant:** "):].strip()

    mtime = path.stat().st_mtime
    return {
        "id": path.stem,
        "mtime": mtime,
        "mtime_str": datetime.fromtimestamp(mtime).strftime("%Y-%m-%d %H:%M"),
        "turns": turns,
        "first_user": first_user,
        "last_user": last_user,
        "last_assistant": last_assistant,
        "is_agent": path.stem.startswith("agent_"),
    }


def _truncate(s: str, n: int) -> str:
    return s if len(s) <= n else s[:n - 1] + "…"


def list_sessions() -> None:
    """List all sessions in a rich table with resume instructions."""
    if not SESSIONS_DIR.exists() or not any(SESSIONS_DIR.glob("*.md")):
        console.print(Panel(
            "[dim]No sessions yet.[/dim]\n\n"
            "Start one:\n"
            "  [cyan]onefirewall-ai agent \"build me a todo app\"[/cyan]\n"
            "  [cyan]onefirewall-ai --session my-project agent \"create a REST API\"[/cyan]",
            title="Sessions",
            border_style="dim",
        ))
        return

    files = sorted(SESSIONS_DIR.glob("*.md"), key=lambda f: f.stat().st_mtime, reverse=True)
    sessions = [_parse_session(f) for f in files[:20]]

    table = Table(
        box=box.ROUNDED,
        show_header=True,
        header_style="bold cyan",
        border_style="dim",
        expand=False,
        min_width=90,
    )
    table.add_column("#", style="dim", width=3, justify="right")
    table.add_column("Session ID", style="cyan", no_wrap=True, min_width=28)
    table.add_column("Type", style="dim", width=5)
    table.add_column("Turns", justify="right", style="dim", width=6)
    table.add_column("Last Updated", style="magenta", width=16)
    table.add_column("Last Message", style="white")

    for i, s in enumerate(sessions, 1):
        type_icon = "🤖" if s["is_agent"] else "💬"
        last_msg = _truncate(s["last_user"] or s["first_user"] or "(empty)", 55)
        table.add_row(
            str(i),
            s["id"],
            type_icon,
            str(s["turns"]),
            s["mtime_str"],
            last_msg,
        )

    console.print()
    console.print(table)
    console.print()

    # Show resume instructions
    if sessions:
        latest = sessions[0]["id"]
        console.print("  [bold]Resume a session:[/bold]")
        console.print(f"  [cyan]onefirewall-ai --session {latest} agent \"continue where we left off\"[/cyan]")
        console.print()
        console.print("  [bold]Start a named session:[/bold]")
        console.print(f"  [cyan]onefirewall-ai --session my-project agent \"add unit tests\"[/cyan]")
        console.print()


def view_session(session_id: str) -> None:
    """Print the full history of a session."""
    path = SESSIONS_DIR / f"{session_id}.md"
    if not path.exists():
        console.print(f"[red]Session not found:[/red] {session_id}")
        console.print(f"  Run [cyan]onefirewall-ai sessions[/cyan] to see available sessions.")
        return

    text = path.read_text(encoding="utf-8", errors="replace")
    console.print()
    console.print(Rule(f"[bold cyan]Session: {session_id}[/bold cyan]", style="cyan"))
    console.print()

    # Parse and display turns
    turn = 0
    for block in text.split("---"):
        block = block.strip()
        if not block:
            continue
        user_msg = ""
        asst_msg = ""
        timestamp = ""
        for line in block.splitlines():
            if line.startswith("## ["):
                timestamp = line[4:-1] if line.endswith("]") else ""
            elif line.startswith("**User:** "):
                user_msg = line[len("**User:** "):]
            elif line.startswith("**Assistant:** "):
                asst_msg = line[len("**Assistant:** "):]
        if user_msg:
            turn += 1
            ts = f"[dim]{timestamp}[/dim]  " if timestamp else ""
            console.print(f"  {ts}[bold white]You:[/bold white] {user_msg}")
            if asst_msg:
                preview = _truncate(asst_msg, 200)
                console.print(f"  [dim]Agent:[/dim] {preview}")
            console.print()

    if turn == 0:
        console.print("[dim](Session is empty)[/dim]")

    console.print(Rule(style="dim"))
    console.print(
        f"  [dim]Resume:[/dim] [cyan]onefirewall-ai --session {session_id} agent \"continue\"[/cyan]"
    )
    console.print()
