"""CLI commands for ticket & sprint management.

Usage:
  proxym ticket list [--status STATUS] [--tool TOOL] [--sprint SPRINT_ID]
  proxym ticket create --title "..." [--type bug] [--priority high] [--sprint SPR-...]
  proxym ticket show TICKET_ID
  proxym ticket update TICKET_ID --status done
  proxym ticket assign TICKET_ID --tool aider [--mode code] [--model google/gemini-3-flash-preview]
  proxym ticket comment TICKET_ID --author aider --content "Fixed the bug"
  proxym ticket delete TICKET_ID
  proxym sprint list [--status active]
  proxym sprint create --name "Sprint 1" [--goal "..."] [--start 2026-03-23] [--end 2026-04-06]
  proxym sprint show SPRINT_ID
  proxym sprint update SPRINT_ID --status active
  proxym sprint delete SPRINT_ID
  proxym sprint board [--sprint SPRINT_ID]
"""

from __future__ import annotations

from proxym.cli._client import make_client, print_json_if_yaml, print_table


def cmd_ticket_list(args):
    """List tickets with optional filters."""
    params = {}
    if getattr(args, "status", None):
        params["status"] = args.status
    if getattr(args, "tool", None):
        params["tool"] = args.tool
    if getattr(args, "sprint", None):
        params["sprint_id"] = args.sprint
    if getattr(args, "priority", None):
        params["priority"] = args.priority
    if getattr(args, "tag", None):
        params["tag"] = args.tag

    with make_client(getattr(args, "proxy", None), getattr(args, "key", None)) as c:
        r = c.get("/dashboard/tickets", params=params)
        data = r.json()

    tickets = data.get("tickets", [])
    if print_json_if_yaml(args, data):
        return

    print(f"\n  Tickets ({len(tickets)})\n")
    if not tickets:
        print("  No tickets found.\n")
        return

    print_table(
        tickets,
        ["id", "title", "status", "priority", "type", "assigned_tool"],
        [12, 35, 14, 10, 10, 20],
    )
    print()


def cmd_ticket_create(args):
    """Create a new ticket."""
    payload = {"title": args.title}
    if getattr(args, "description", None):
        payload["description"] = args.description
    if getattr(args, "type", None):
        payload["type"] = args.type
    if getattr(args, "priority", None):
        payload["priority"] = args.priority
    if getattr(args, "sprint", None):
        payload["sprint_id"] = args.sprint
    if getattr(args, "tags", None):
        payload["tags"] = [t.strip() for t in args.tags.split(",") if t.strip()]
    if getattr(args, "files", None):
        payload["files"] = [f.strip() for f in args.files.split(",") if f.strip()]
    if getattr(args, "hours", None):
        payload["estimated_hours"] = args.hours

    with make_client(getattr(args, "proxy", None), getattr(args, "key", None)) as c:
        r = c.post("/dashboard/tickets", json=payload)
        data = r.json()

    print(f"  ✓ Created ticket {data['id']}: {data['title']}")
    print(f"    Status: {data['status']}  Priority: {data['priority']}  Type: {data['type']}")


def cmd_ticket_show(args):
    """Show ticket details."""
    with make_client(getattr(args, "proxy", None), getattr(args, "key", None)) as c:
        r = c.get(f"/dashboard/tickets/{args.ticket_id}")
        if r.status_code == 404:
            print(f"  Ticket {args.ticket_id} not found.")
            return
        data = r.json()

    print(f"\n  {data['id']}  {data['title']}")
    print(f"  Status: {data['status']}  Priority: {data['priority']}  Type: {data['type']}")
    if data.get("description"):
        print(f"  Description: {data['description']}")
    if data.get("sprint_id"):
        print(f"  Sprint: {data['sprint_id']}")
    if data.get("assigned_tool"):
        t = data["assigned_tool"]
        print(f"  Tool: {t['tool']}" + (f" ({t['agent_mode']})" if t.get("agent_mode") else ""))
    if data.get("tags"):
        print(f"  Tags: {', '.join(data['tags'])}")
    if data.get("files"):
        print(f"  Files: {', '.join(data['files'])}")
    if data.get("comments"):
        print(f"\n  Comments ({len(data['comments'])}):")
        for c in data["comments"]:
            print(f"    [{c.get('author', '?')}] {c['content']}")
    print()


def cmd_ticket_update(args):
    """Update a ticket."""
    payload = {}
    if getattr(args, "title", None):
        payload["title"] = args.title
    if getattr(args, "status", None):
        payload["status"] = args.status
    if getattr(args, "priority", None):
        payload["priority"] = args.priority
    if getattr(args, "type", None):
        payload["type"] = args.type
    if getattr(args, "hours", None):
        payload["actual_hours"] = args.hours

    if not payload:
        print("  No updates specified.")
        return

    with make_client(getattr(args, "proxy", None), getattr(args, "key", None)) as c:
        r = c.put(f"/dashboard/tickets/{args.ticket_id}", json=payload)
        if r.status_code == 404:
            print(f"  Ticket {args.ticket_id} not found.")
            return
        data = r.json()

    print(f"  ✓ Updated {data['id']}: status={data['status']} priority={data['priority']}")


def cmd_ticket_assign(args):
    """Assign a tool to a ticket."""
    payload = {"tool": args.tool}
    if getattr(args, "mode", None):
        payload["agent_mode"] = args.mode
    if getattr(args, "model", None):
        payload["model"] = args.model

    with make_client(getattr(args, "proxy", None), getattr(args, "key", None)) as c:
        r = c.post(f"/dashboard/tickets/{args.ticket_id}/assign", json=payload)
        if r.status_code == 404:
            print(f"  Ticket {args.ticket_id} not found.")
            return
        data = r.json()

    ticket = data.get("ticket", {})
    print(f"  ✓ Assigned {args.tool} to {args.ticket_id} (status: {ticket.get('status')})")


def cmd_ticket_comment(args):
    """Add a comment to a ticket."""
    payload = {"content": args.content}
    if getattr(args, "author", None):
        payload["author"] = args.author

    with make_client(getattr(args, "proxy", None), getattr(args, "key", None)) as c:
        r = c.post(f"/dashboard/tickets/{args.ticket_id}/comment", json=payload)
        if r.status_code == 404:
            print(f"  Ticket {args.ticket_id} not found.")
            return

    print(f"  ✓ Comment added to {args.ticket_id}")


def _delete_entity(args, path: str, entity_id: str, label: str):
    """Delete a ticket/sprint/milestone by ID."""
    with make_client(getattr(args, "proxy", None), getattr(args, "key", None)) as c:
        r = c.delete(path)
        if r.status_code == 404:
            print(f"  {label} {entity_id} not found.")
            return
    print(f"  ✓ Deleted {entity_id}")


def cmd_ticket_delete(args):
    """Delete a ticket."""
    _delete_entity(args, f"/dashboard/tickets/{args.ticket_id}", args.ticket_id, "Ticket")


def cmd_sprint_list(args):
    """List sprints."""
    params = {}
    if getattr(args, "status", None):
        params["status"] = args.status

    with make_client(getattr(args, "proxy", None), getattr(args, "key", None)) as c:
        r = c.get("/dashboard/sprints", params=params)
        data = r.json()

    sprints = data.get("sprints", [])
    if print_json_if_yaml(args, data):
        return

    print(f"\n  Sprints ({len(sprints)})\n")
    if not sprints:
        print("  No sprints found.\n")
        return

    print_table(
        sprints,
        ["id", "name", "status", "tickets_total", "tickets_done", "progress_pct"],
        [12, 30, 12, 8, 8, 10],
    )
    print()


def cmd_sprint_create(args):
    """Create a new sprint."""
    payload = {"name": args.name}
    if getattr(args, "goal", None):
        payload["goal"] = args.goal
    if getattr(args, "start", None):
        payload["start_date"] = args.start
    if getattr(args, "end", None):
        payload["end_date"] = args.end

    with make_client(getattr(args, "proxy", None), getattr(args, "key", None)) as c:
        r = c.post("/dashboard/sprints", json=payload)
        data = r.json()

    print(f"  ✓ Created sprint {data['id']}: {data['name']}")


def cmd_sprint_show(args):
    """Show sprint details."""
    with make_client(getattr(args, "proxy", None), getattr(args, "key", None)) as c:
        r = c.get(f"/dashboard/sprints/{args.sprint_id}")
        if r.status_code == 404:
            print(f"  Sprint {args.sprint_id} not found.")
            return
        data = r.json()

    print(f"\n  {data['id']}  {data['name']}")
    print(f"  Status: {data['status']}  Progress: {data['progress_pct']}%")
    if data.get("goal"):
        print(f"  Goal: {data['goal']}")
    if data.get("start_date"):
        print(f"  Period: {data['start_date']} → {data.get('end_date', '...')}")
    print(
        f"  Tickets: {data['tickets_total']} total, {data['tickets_done']} done, {data['tickets_in_progress']} in progress"
    )

    stats = data.get("stats", {})
    if stats.get("by_tool"):
        print(f"  Tools: {', '.join(f'{k}:{v}' for k, v in stats['by_tool'].items())}")
    print()


def cmd_sprint_update(args):
    """Update a sprint."""
    payload = {}
    if getattr(args, "name", None):
        payload["name"] = args.name
    if getattr(args, "status", None):
        payload["status"] = args.status
    if getattr(args, "goal", None):
        payload["goal"] = args.goal

    if not payload:
        print("  No updates specified.")
        return

    with make_client(getattr(args, "proxy", None), getattr(args, "key", None)) as c:
        r = c.put(f"/dashboard/sprints/{args.sprint_id}", json=payload)
        if r.status_code == 404:
            print(f"  Sprint {args.sprint_id} not found.")
            return
        data = r.json()

    print(f"  ✓ Updated {data['id']}: status={data['status']}")


def cmd_sprint_delete(args):
    """Delete a sprint."""
    _delete_entity(args, f"/dashboard/sprints/{args.sprint_id}", args.sprint_id, "Sprint")


def cmd_ticket_dedup(args):
    """Find and remove duplicate tickets."""
    dry_run = getattr(args, "dry_run", True)
    with make_client(getattr(args, "proxy", None), getattr(args, "key", None)) as c:
        r = c.post("/dashboard/tickets/dedup", json={"dry_run": dry_run})
        data = r.json()

    if print_json_if_yaml(args, data):
        return

    mode = "DRY RUN" if data.get("dry_run") else "EXECUTED"
    print(f"\n  Ticket Deduplication [{mode}]\n")
    print(f"  Duplicate groups found: {data.get('duplicate_groups', 0)}")
    print(f"  Total duplicates:       {data.get('total_duplicates', 0)}")

    kept = data.get("kept", [])
    removed = data.get("removed", [])

    if kept:
        print(f"\n  Kept ({len(kept)}):")
        for tid in kept[:20]:
            print(f"    ✓ {tid}")
        if len(kept) > 20:
            print(f"    ... and {len(kept) - 20} more")

    if removed:
        action = "Would remove" if data.get("dry_run") else "Removed"
        print(f"\n  {action} ({len(removed)}):")
        for tid in removed[:30]:
            print(f"    ✗ {tid}")
        if len(removed) > 30:
            print(f"    ... and {len(removed) - 30} more")

    if not removed:
        print("\n  No duplicates found. ✓")
    elif data.get("dry_run"):
        print(f"\n  Run with --execute to remove {len(removed)} duplicates.")
    else:
        print(f"\n  ✓ Removed {len(removed)} duplicate tickets.")
    print()


def cmd_ticket_analyze(args):
    """Analyze whether a ticket was completed correctly."""
    with make_client(getattr(args, "proxy", None), getattr(args, "key", None)) as c:
        r = c.get(f"/dashboard/tickets/{args.ticket_id}")
        if r.status_code == 404:
            print(f"  Ticket {args.ticket_id} not found.")
            return
        data = r.json()

    tid = data["id"]
    title = data.get("title", data.get("task", ""))
    status = data.get("status", "?")
    priority = data.get("priority", "?")
    ttype = data.get("type", "?")

    status_icons = {
        "done": "\033[32m●\033[0m",
        "in_review": "\033[33m◐\033[0m",
        "in_progress": "\033[36m◐\033[0m",
        "todo": "○",
        "backlog": "○",
        "blocked": "\033[31m⊘\033[0m",
        "cancelled": "\033[31m✗\033[0m",
    }
    icon = status_icons.get(status, "?")

    print(f"\n  {icon} {tid}  {title}")
    print(f"  Status: {status}  Priority: {priority}  Type: {ttype}")

    tool_info = data.get("assigned_tool")
    if tool_info:
        tool_str = tool_info.get("tool", "?")
        if tool_info.get("agent_mode"):
            tool_str += f" ({tool_info['agent_mode']})"
        print(f"  Tool: {tool_str}")

    last_job = data.get("last_job") or data.get("last_execution")
    if not last_job:
        print(f"\n  No execution found — ticket has not been dispatched yet.")
        print(f"\n  Next step:")
        print(f"    proxym tools dispatch --ticket {tid} --tool <tool>")
        print(f"    proxym do \"{title[:50]}\"")
        print()
        return

    job_status = last_job.get("status", "?")
    success = last_job.get("success")
    duration = last_job.get("duration_s", 0)
    job_id = last_job.get("job_id", "?")
    error = last_job.get("error", "")
    files = last_job.get("files_changed", [])
    stdout_tail = last_job.get("stdout_tail", "")
    stderr_tail = last_job.get("stderr_tail", "")

    job_icon = {"done": "✅", "failed": "❌", "running": "⏳", "queued": "○", "cancelled": "🚫"}.get(job_status, "?")
    print(f"\n  Last execution:")
    print(f"    {job_icon} Job: {job_id}  Status: {job_status}  Duration: {duration:.0f}s")

    if last_job.get("tool"):
        model_str = last_job.get("model", "")
        print(f"    Tool: {last_job['tool']}" + (f"  Model: {model_str}" if model_str else ""))

    if files:
        print(f"    Files changed ({len(files)}):")
        for f in files[:10]:
            print(f"      {f}")
        if len(files) > 10:
            print(f"      ... +{len(files) - 10} more")

    if success is True and job_status == "done":
        print(f"\n  \033[32mResult: PASS\033[0m — ticket completed successfully")
        if status != "done":
            print(f"    Ticket status is '{status}', you may want to mark it done:")
            print(f"    proxym ticket update {tid} --status done")
    elif success is False or job_status == "failed":
        print(f"\n  \033[31mResult: FAIL\033[0m — execution failed")
        if error:
            print(f"    Error: {error[:300]}")
        if stderr_tail:
            print(f"\n    stderr (last lines):")
            for line in stderr_tail.strip().splitlines()[-5:]:
                print(f"      {line}")
        print(f"\n    Next steps:")
        print(f"      proxym tools retry {job_id}")
        print(f"      proxym tools repair {job_id}")
    elif job_status in ("queued", "running"):
        print(f"\n  \033[33mResult: PENDING\033[0m — still executing")
        print(f"    proxym tools job {job_id}")
    else:
        print(f"\n  Result: {job_status}")

    if stdout_tail and success:
        print(f"\n    Output (last lines):")
        for line in stdout_tail.strip().splitlines()[-5:]:
            print(f"      {line}")

    print()


def cmd_board(args):
    """Show kanban board."""
    params = {}
    if getattr(args, "sprint", None):
        params["sprint_id"] = args.sprint

    with make_client(getattr(args, "proxy", None), getattr(args, "key", None)) as c:
        r = c.get("/dashboard/tickets/board/view", params=params)
        board = r.json()

    statuses = ["backlog", "todo", "in_progress", "in_review", "done", "cancelled"]
    print("\n  Kanban Board\n")
    for status in statuses:
        tickets = board.get(status, [])
        if not tickets:
            continue
        print(f"  [{status.upper().replace('_', ' ')}] ({len(tickets)})")
        for t in tickets:
            tool = f" @{t['assigned_tool']['tool']}" if t.get("assigned_tool") else ""
            print(f"    {t['id']}  {t['title'][:40]}{tool}")
        print()
