"""Pretty terminal output for poc — inspired by tokei/scc style."""
import sys


# Box drawing characters
HEAVY_H = "━"
HEAVY_V = "┃"
LIGHT_H = "─"
LIGHT_V = "│"
TL = "┏"
TR = "┓"
BL = "┗"
BR = "┛"
ML = "┠"
MR = "┨"
T_DOWN = "┯"
T_UP = "┷"
CROSS = "┼"
ML_LIGHT = "├"
MR_LIGHT = "┤"

# ANSI colors
BOLD = "\033[1m"
DIM = "\033[2m"
CYAN = "\033[36m"
GREEN = "\033[32m"
YELLOW = "\033[33m"
MAGENTA = "\033[35m"
WHITE = "\033[37m"
RESET = "\033[0m"

TOOL_COLORS = {
    "claude": CYAN,
    "codex": GREEN,
    "cursor": MAGENTA,
}

TOOL_LABELS = {
    "claude": "Claude Code",
    "codex": "Codex CLI",
    "cursor": "Cursor",
}


def _supports_color() -> bool:
    return hasattr(sys.stdout, "isatty") and sys.stdout.isatty()


def _c(color: str, text: str) -> str:
    if not _supports_color():
        return text
    return f"{color}{text}{RESET}"


def render(project_path: str, result: dict) -> str:
    """Render prompt counts as a pretty table.

    result: output of aggregator.count_all()
    """
    color = _supports_color()
    lines = []

    col_w = [18, 10, 10, 10]  # Tool, Prompts, Sessions, Details
    total_w = sum(col_w) + len(col_w) + 1  # +1 per column separator + edges

    # Header
    lines.append("")
    title = f" aipoc — Prompts of Codebase "
    lines.append(_c(BOLD, f"  {title}"))
    lines.append(_c(DIM, f"  {project_path}"))
    lines.append("")

    # Table header
    sep = LIGHT_H * (total_w - 2)
    lines.append(f"  {ML_LIGHT}{sep}{MR_LIGHT}")

    header = (
        f"  {LIGHT_V}"
        f" {'Tool':<{col_w[0]-1}}"
        f"{LIGHT_V}"
        f" {'Prompts':>{col_w[1]-1}}"
        f"{LIGHT_V}"
        f" {'Sessions':>{col_w[2]-1}}"
        f"{LIGHT_V}"
        f" {'Details':<{col_w[3]-1}}"
        f"{LIGHT_V}"
    )
    lines.append(_c(BOLD, header))
    lines.append(f"  {ML_LIGHT}{sep}{MR_LIGHT}")

    # Tool rows
    by_tool = result.get("by_tool", {})
    for tool_name in ["claude", "codex", "cursor"]:
        data = by_tool.get(tool_name)
        if not data:
            continue
        prompts = data.get("prompts", 0)
        if prompts == 0:
            continue

        sessions = data.get("sessions", data.get("composer_sessions", 0))
        label = TOOL_LABELS.get(tool_name, tool_name)
        tc = TOOL_COLORS.get(tool_name, WHITE)

        # Build details string
        details = ""
        if tool_name == "cursor":
            cs = data.get("composer_sessions", 0)
            cp = data.get("chat_prompts", 0)
            parts = []
            if cs:
                parts.append(f"{cs} agent")
            if cp:
                parts.append(f"{cp} chat")
            details = ", ".join(parts)
        elif tool_name == "claude":
            details = data.get("source", "")

        label_str = label.ljust(col_w[0] - 1)
        prompt_str = str(prompts).rjust(col_w[1] - 1)
        session_str = str(sessions).rjust(col_w[2] - 1)
        detail_str = details.ljust(col_w[3] - 1)
        row = (
            f"  {LIGHT_V}"
            f" {_c(tc, label_str)}"
            f"{LIGHT_V}"
            f" {_c(BOLD, prompt_str)}"
            f"{LIGHT_V}"
            f" {session_str}"
            f"{LIGHT_V}"
            f" {_c(DIM, detail_str)}"
            f"{LIGHT_V}"
        )
        lines.append(row)

    # Total row
    lines.append(f"  {ML_LIGHT}{sep}{MR_LIGHT}")
    total = result.get("total", 0)
    total_label = "TOTAL".ljust(col_w[0] - 1)
    total_val = str(total).rjust(col_w[1] - 1)
    empty2 = "".rjust(col_w[2] - 1)
    empty3 = "".ljust(col_w[3] - 1)
    total_row = (
        f"  {LIGHT_V}"
        f" {_c(BOLD + YELLOW, total_label)}"
        f"{LIGHT_V}"
        f" {_c(BOLD + YELLOW, total_val)}"
        f"{LIGHT_V}"
        f" {empty2}"
        f"{LIGHT_V}"
        f" {empty3}"
        f"{LIGHT_V}"
    )
    lines.append(total_row)
    lines.append(f"  {ML_LIGHT}{sep}{MR_LIGHT}")
    lines.append("")

    return "\n".join(lines)


def render_chats(chats: list[dict], limit: int = 10) -> str:
    """Render a list of chat sessions as a pretty list.

    Each chat has: tool, first_prompt or name, and date fields.
    """
    lines = []
    shown = chats[:limit]

    if not shown:
        lines.append(_c(DIM, "  No chat sessions found."))
        return "\n".join(lines)

    lines.append(_c(BOLD, "  Recent chats"))
    lines.append("")

    for i, chat in enumerate(shown, 1):
        tool = chat.get("tool", "?")
        tc = TOOL_COLORS.get(tool, WHITE)
        tool_tag = _c(tc, TOOL_LABELS.get(tool, tool))

        # Get the display title
        title = chat.get("first_prompt", chat.get("name", "Untitled"))
        # Clean up XML/command tags from Claude firstPrompt
        if title.startswith("<"):
            import re
            cleaned = re.sub(r"<[^>]+>", "", title).strip()
            if cleaned:
                title = cleaned
        # Clean up agent-injected prompts
        if title.startswith("You are doing"):
            title = _c(DIM, "[agent task]")
        # Truncate long prompts
        if len(title) > 60:
            title = title[:57] + "..."

        # Get date
        from datetime import datetime, timezone
        modified = chat.get("modified", chat.get("timestamp", ""))
        date_str = ""
        if isinstance(modified, (int, float)) and modified > 0:
            dt = datetime.fromtimestamp(modified / 1000, tz=timezone.utc)
            date_str = dt.strftime("%b %d")
        elif isinstance(modified, str) and modified:
            try:
                dt = datetime.fromisoformat(modified.replace("Z", "+00:00"))
                date_str = dt.strftime("%b %d")
            except ValueError:
                pass

        # Get message/prompt count
        count = chat.get("message_count", chat.get("prompts", ""))
        count_str = f"{count}p" if count else ""

        num = _c(DIM, str(i).rjust(3) + ".")
        date_part = _c(DIM, date_str.ljust(7))
        count_part = _c(DIM, count_str.rjust(5))

        lines.append(f"  {num} {tool_tag}  {date_part} {count_part}  {title}")

    remaining = len(chats) - limit
    if remaining > 0:
        lines.append("")
        lines.append(_c(DIM, f"  ... and {remaining} more. Run with --deep to see all."))

    lines.append("")
    return "\n".join(lines)
