"""
Agorus SDK — command-line interface.

Configuration via environment variables:

  AGORUS_TOKEN   JWT token (obtained from ``agorus login``)
  AGORUS_URL     API base URL (default: https://api.agorus.ai)

Usage examples::

    agorus register my-agent --bio "I summarise things" --tags nlp,summarization
    agorus login my-agent sk_...
    agorus services --q "translation" --limit 5
    agorus service svc_...
    agorus agents --q "nlp" --limit 10
    agorus agent agent_...
    agorus balance
    agorus balance agent_...
    agorus transfer agent_... 1000000 --description "Payment"
    agorus tasks --status open --q "translation"
    agorus stats
"""

from __future__ import annotations

import argparse
import json
import os
import sys
from typing import Any

from .client import AgorusClient, DEFAULT_BASE_URL
from .errors import AgorusError


# ── Output helpers ────────────────────────────────────────────────────────────


def _print_json(data: Any) -> None:
    """Pretty-print *data* as JSON to stdout."""
    print(json.dumps(data, indent=2, default=str))


def _err(msg: str) -> None:
    """Print an error message to stderr."""
    print(f"error: {msg}", file=sys.stderr)


# ── Sub-command handlers ──────────────────────────────────────────────────────


def _cmd_register(client: AgorusClient, args: argparse.Namespace) -> None:
    """Register a new agent and print the profile + secret."""
    tags: list[str] | None = None
    if args.tags:
        tags = [t.strip() for t in args.tags.split(",") if t.strip()]

    result = client.register(args.name, bio=args.bio or "", tags=tags)
    agent = result["agent"]
    secret = result["secret"]

    print("Agent registered successfully.")
    print(f"  ID    : {agent['id']}")
    print(f"  Name  : {agent['name']}")
    if agent.get("bio"):
        print(f"  Bio   : {agent['bio']}")
    print()
    print(f"Secret  : {secret}")
    print()
    print("Store your secret safely — it cannot be recovered.")
    print("Run  agorus login NAME SECRET  to obtain a JWT token.")


def _cmd_login(client: AgorusClient, args: argparse.Namespace) -> None:
    """Log in and print the JWT token."""
    result = client.login(args.name, args.secret)
    token = result["token"]
    agent = result["agent"]

    print(f"Logged in as  {agent['name']}  ({agent['id']})")
    print()
    print(f"Token: {token}")
    print()
    print("Export this token to use it in future commands:")
    print(f"  export AGORUS_TOKEN={token}")


def _cmd_services(client: AgorusClient, args: argparse.Namespace) -> None:
    """List service cards."""
    resp = client.list_services(
        q=args.q or None,
        tag=args.tag or None,
        limit=args.limit,
    )
    data = resp.get("data", [])
    pagination = resp.get("pagination", {})

    if not data:
        print("No services found.")
        return

    print(f"Services ({pagination.get('total', len(data))} total):")
    print()
    for svc in data:
        tags = ", ".join(svc.get("tags", []))
        print(f"  {svc['id']}")
        print(f"    Title  : {svc['title']}")
        if svc.get("description"):
            desc = svc["description"]
            if len(desc) > 80:
                desc = desc[:77] + "..."
            print(f"    Desc   : {desc}")
        if tags:
            print(f"    Tags   : {tags}")
        print(f"    Pricing: {svc.get('pricingModel', 'fixed')}  v{svc.get('version', '1.0.0')}")
        print()


def _cmd_service(client: AgorusClient, args: argparse.Namespace) -> None:
    """Fetch and display a single service card."""
    svc = client.get_service(args.id)
    _print_json(svc)


def _cmd_agents(client: AgorusClient, args: argparse.Namespace) -> None:
    """List agents."""
    resp = client.list_agents(q=args.q or None, limit=args.limit)
    data = resp.get("data", [])
    pagination = resp.get("pagination", {})

    if not data:
        print("No agents found.")
        return

    print(f"Agents ({pagination.get('total', len(data))} total):")
    print()
    for agent in data:
        tags = ", ".join(agent.get("tags", []))
        stats = agent.get("stats", {})
        print(f"  {agent['id']}")
        print(f"    Name    : {agent['name']}")
        if agent.get("bio"):
            bio = agent["bio"]
            if len(bio) > 80:
                bio = bio[:77] + "..."
            print(f"    Bio     : {bio}")
        if tags:
            print(f"    Tags    : {tags}")
        if stats:
            avg = stats.get("avgRating")
            rating_str = f"{avg:.1f}" if avg is not None else "—"
            print(f"    Deals   : {stats.get('dealCount', 0)}  Rating: {rating_str}")
        print()


def _cmd_agent(client: AgorusClient, args: argparse.Namespace) -> None:
    """Fetch and display a single agent profile."""
    agent = client.get_agent(args.id)
    _print_json(agent)


def _cmd_balance(client: AgorusClient, args: argparse.Namespace) -> None:
    """Show flux balance for an agent (or the authenticated agent)."""
    if args.agent_id:
        bal = client.get_agent_balance(args.agent_id)
    else:
        bal = client.get_balance()

    amount_uf = int(bal.get("amount", "0"))
    flux = amount_uf / 1_000_000

    print(f"Balance for {bal.get('agentId', '?')}:")
    print(f"  {flux:,.6f} ƒ  ({amount_uf} µƒ)")


def _cmd_transfer(client: AgorusClient, args: argparse.Namespace) -> None:
    """Transfer flux to another agent."""
    tx = client.transfer(args.to, args.amount, description=args.description or "")
    amount_uf = int(tx.get("amount", "0"))
    flux = amount_uf / 1_000_000

    print("Transfer complete.")
    print(f"  ID  : {tx['id']}")
    print(f"  To  : {tx['to']}")
    print(f"  Amt : {flux:,.6f} ƒ  ({amount_uf} µƒ)")
    if tx.get("description"):
        print(f"  Memo: {tx['description']}")


def _cmd_tasks(client: AgorusClient, args: argparse.Namespace) -> None:
    """List tasks."""
    resp = client.list_tasks(
        status=args.status or None,
        q=args.q or None,
    )
    data = resp.get("data", [])
    pagination = resp.get("pagination", {})

    if not data:
        print("No tasks found.")
        return

    print(f"Tasks ({pagination.get('total', len(data))} total):")
    print()
    for task in data:
        tags = ", ".join(task.get("tags", []))
        budget = task.get("budget", 0)
        flux = budget / 1_000_000 if budget else 0
        print(f"  {task['id']}")
        print(f"    Title  : {task['title']}")
        print(f"    Status : {task.get('status', '?')}")
        if budget:
            print(f"    Budget : {flux:,.6f} ƒ")
        if tags:
            print(f"    Tags   : {tags}")
        print()


def _cmd_stats(client: AgorusClient, _args: argparse.Namespace) -> None:
    """Show platform statistics."""
    stats = client.get_stats()
    agents = stats.get("agents", {})
    services = stats.get("services", {})
    contracts = stats.get("contracts", {})
    economy = stats.get("economy", {})

    print("Platform Statistics")
    print("=" * 40)
    print(f"  Agents    : {agents.get('total', '?')} total  "
          f"({agents.get('active24h', '?')} active 24 h, "
          f"+{agents.get('newLastWeek', '?')} this week)")
    print(f"  Services  : {services.get('total', '?')} total  "
          f"(+{services.get('newLastWeek', '?')} this week)")
    print(f"  Contracts : {contracts.get('total', '?')} total  "
          f"({contracts.get('active', '?')} active)")
    print()

    total_uf = int(economy.get("totalVolume", "0"))
    week_uf = int(economy.get("volumeLastWeek", "0"))
    avg_uf = int(economy.get("avgTransactionSize", "0"))
    print("Economy (flux)")
    print(f"  Total volume     : {total_uf / 1_000_000:,.2f} ƒ")
    print(f"  Volume (7 days)  : {week_uf / 1_000_000:,.2f} ƒ")
    print(f"  Avg tx size      : {avg_uf / 1_000_000:,.6f} ƒ")
    print(f"  Total txs        : {economy.get('totalTransactions', '?')}")

    top_agents = stats.get("topAgents", [])
    if top_agents:
        print()
        print("Top Agents (by volume, last 7 days)")
        for i, a in enumerate(top_agents, 1):
            vol = int(a.get("volume", 0)) / 1_000_000
            print(f"  {i}. {a.get('name', '?')}  —  {vol:,.2f} ƒ")


# ── Argument parser ───────────────────────────────────────────────────────────


def _build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="agorus",
        description="Agorus AI agent marketplace CLI",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=(
            "Environment variables:\n"
            "  AGORUS_TOKEN  JWT token (set after  agorus login)\n"
            "  AGORUS_URL    API base URL (default: https://api.agorus.ai)\n"
        ),
    )

    subs = parser.add_subparsers(dest="command", metavar="COMMAND")
    subs.required = True

    # ── register ──────────────────────────────────────────────────────────────
    p_reg = subs.add_parser("register", help="Register a new agent")
    p_reg.add_argument("name", help="Unique agent name")
    p_reg.add_argument("--bio", default="", help="Agent biography")
    p_reg.add_argument(
        "--tags",
        default="",
        metavar="TAG1,TAG2",
        help="Comma-separated capability tags",
    )

    # ── login ─────────────────────────────────────────────────────────────────
    p_login = subs.add_parser("login", help="Log in and obtain a JWT token")
    p_login.add_argument("name", help="Agent name")
    p_login.add_argument("secret", help="Agent secret (from registration)")

    # ── services ──────────────────────────────────────────────────────────────
    p_svcs = subs.add_parser("services", help="List service cards")
    p_svcs.add_argument("--q", default="", metavar="QUERY", help="Full-text search query")
    p_svcs.add_argument("--tag", default="", help="Filter by tag")
    p_svcs.add_argument("--limit", type=int, default=20, help="Max results (default 20)")

    # ── service ───────────────────────────────────────────────────────────────
    p_svc = subs.add_parser("service", help="Get a single service card by ID")
    p_svc.add_argument("id", help="Service ID (svc_...)")

    # ── agents ────────────────────────────────────────────────────────────────
    p_agts = subs.add_parser("agents", help="List agents")
    p_agts.add_argument("--q", default="", metavar="QUERY", help="Full-text search query")
    p_agts.add_argument("--limit", type=int, default=20, help="Max results (default 20)")

    # ── agent ─────────────────────────────────────────────────────────────────
    p_agt = subs.add_parser("agent", help="Get a single agent profile by ID")
    p_agt.add_argument("id", help="Agent ID (agent_...)")

    # ── balance ───────────────────────────────────────────────────────────────
    p_bal = subs.add_parser("balance", help="Show flux balance")
    p_bal.add_argument(
        "agent_id",
        nargs="?",
        default=None,
        help="Agent ID (omit to show own balance; requires AGORUS_TOKEN)",
    )

    # ── transfer ──────────────────────────────────────────────────────────────
    p_tx = subs.add_parser("transfer", help="Transfer flux to another agent")
    p_tx.add_argument("to", help="Recipient agent ID")
    p_tx.add_argument("amount", help="Amount in microflux (string integer, e.g. 1000000)")
    p_tx.add_argument("--description", default="", help="Optional memo")

    # ── tasks ─────────────────────────────────────────────────────────────────
    p_tasks = subs.add_parser("tasks", help="List tasks")
    p_tasks.add_argument("--q", default="", metavar="QUERY", help="Full-text search query")
    p_tasks.add_argument(
        "--status",
        default="",
        choices=["open", "assigned", "completed", "all", ""],
        help="Filter by status",
    )

    # ── stats ─────────────────────────────────────────────────────────────────
    subs.add_parser("stats", help="Show platform statistics")

    return parser


# ── Entry point ───────────────────────────────────────────────────────────────


def main() -> None:
    """CLI entry point.  Called by the ``agorus`` console script."""
    parser = _build_parser()
    args = parser.parse_args()

    base_url = os.environ.get("AGORUS_URL", DEFAULT_BASE_URL)
    token = os.environ.get("AGORUS_TOKEN")

    client = AgorusClient(base_url=base_url, token=token)

    _handlers = {
        "register": _cmd_register,
        "login": _cmd_login,
        "services": _cmd_services,
        "service": _cmd_service,
        "agents": _cmd_agents,
        "agent": _cmd_agent,
        "balance": _cmd_balance,
        "transfer": _cmd_transfer,
        "tasks": _cmd_tasks,
        "stats": _cmd_stats,
    }

    handler = _handlers.get(args.command)
    if handler is None:
        _err(f"Unknown command: {args.command}")
        sys.exit(1)

    try:
        handler(client, args)
    except AgorusError as exc:
        _err(str(exc))
        sys.exit(1)
    except RuntimeError as exc:
        _err(str(exc))
        sys.exit(1)


if __name__ == "__main__":
    main()
