from datetime import datetime
from pathlib import Path

STATUS_ICON = {"running": "\U0001f504", "done": "\u2705", "error": "\u274c", "paused": "\u23f8\ufe0f", "waiting": "\U0001f514"}
TYPE_ICON = {
    "claude": "\U0001f7e3", "codex": "\U0001f7e2", "gemini": "\U0001f535",
    "gpt": "\u2b1c", "copilot": "\U0001f7e0", "cursor": "\U0001f7e1",
    "aider": "\U0001f534", "other": "\u26aa",
}
STATUS_LABEL = {
    "running": "running",
    "done": "done",
    "error": "error",
    "paused": "paused",
    "waiting": "idle?",
}


def _format_duration(created_at):
    try:
        start = datetime.strptime(created_at, "%Y-%m-%d %H:%M:%S")
        delta = datetime.now() - start
        total_secs = int(delta.total_seconds())
        if total_secs < 0:
            return "-"
        if total_secs < 60:
            return "{}s".format(total_secs)
        mins = total_secs // 60
        if mins < 60:
            return "{}m".format(mins)
        hours = mins // 60
        remaining_mins = mins % 60
        if hours < 24:
            return "{}h{}m".format(hours, remaining_mins)
        days = hours // 24
        remaining_hours = hours % 24
        return "{}d{}h".format(days, remaining_hours)
    except (ValueError, TypeError):
        return "-"


def format_agents(db):
    agents = db.execute(
        "SELECT * FROM agents ORDER BY (status = 'waiting') DESC, (status = 'running') DESC, (status = 'done'), id DESC"
    ).fetchall()

    if not agents:
        return "  No agents found.\n"

    todos = {}
    for row in db.execute(
        "SELECT agent_id, COUNT(*) as total, SUM(completed) as done FROM todos GROUP BY agent_id"
    ):
        todos[row["agent_id"]] = (int(row["done"] or 0), int(row["total"]))

    total = len(agents)
    running = sum(1 for a in agents if a["status"] == "running")
    done = sum(1 for a in agents if a["status"] == "done")
    errors = sum(1 for a in agents if a["status"] == "error")
    waiting = sum(1 for a in agents if a["status"] == "waiting")

    lines = []

    parts = ["Total: {}".format(total)]
    if waiting:
        parts.append("\U0001f514 Idle?: {}".format(waiting))
    if running:
        parts.append("Running: {}".format(running))
    if done:
        parts.append("Done: {}".format(done))
    if errors:
        parts.append("Errors: {}".format(errors))
    sep = " \u2502 "
    ts = datetime.now().strftime("%H:%M:%S")
    lines.append("\n  {}  [{}]".format(sep.join(parts), ts))
    lines.append("")

    dash = "\u2500\u2500"
    lines.append("  {:>4}  {:<10} {:<24} {:<12} {:<6} {:<7} {}".format(
        "ID", "Type", "Name", "Status", "TTY", "Uptime", "CWD"))
    lines.append("  {:>4}  {:<10} {:<24} {:<12} {:<6} {:<7} {}".format(
        dash, dash, dash, dash, dash, dash, dash))

    for a in agents:
        icon_t = TYPE_ICON.get(a["type"], "\u26aa")
        icon_s = STATUS_ICON.get(a["status"], "\u2753")

        status_str = STATUS_LABEL.get(a["status"], a["status"])
        tty_str = a["tty"] if a["tty"] else "-"
        uptime = _format_duration(a["created_at"])

        cwd_short = ""
        if a["cwd"]:
            cwd_short = str(a["cwd"]).replace(str(Path.home()), "~")

        lines.append("  {:>4}  {} {:<8} {:<24} {} {:<9} {:<6} {:<7} {}".format(
            a["id"], icon_t, a["type"], a["name"], icon_s, status_str, tty_str, uptime, cwd_short))

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


def format_bar(db):
    agents = db.execute(
        "SELECT status, COUNT(*) as cnt FROM agents WHERE status != 'done' OR "
        "(status = 'done' AND updated_at > datetime('now', '-1 hour')) "
        "GROUP BY status"
    ).fetchall()

    counts = {}
    for row in agents:
        counts[row["status"]] = row["cnt"]

    parts = []
    if counts.get("running", 0):
        parts.append("\U0001f504 {} running".format(counts["running"]))
    if counts.get("waiting", 0):
        parts.append("\U0001f514 {} idle?".format(counts["waiting"]))
    if counts.get("done", 0):
        parts.append("\u2705 {} done".format(counts["done"]))
    if counts.get("error", 0):
        parts.append("\u274c {} error".format(counts["error"]))

    if not parts:
        return "wooster: no agents"

    return "wooster: " + " | ".join(parts)


def print_agents(db):
    print(format_agents(db))
