"""
Great Wiring Sprint: Observability MCP Plugin.

Wires dark-matter observability modules into MCP:
  - analytics.py — agent performance BI
  - metrics_collector.py (Phase 54) — time-series metrics
  - health_monitor.py (Phase 40) — health checks & alerting
  - platform_analytics.py (Phase 28) — CEO dashboard metrics
"""

import asyncio
import json

from mcp.types import TextContent, Tool, ToolAnnotations

_SAFE_READ = ToolAnnotations(
    readOnlyHint=True, destructiveHint=False,
    idempotentHint=True, openWorldHint=False,
)
_SAFE_WRITE = ToolAnnotations(
    readOnlyHint=False, destructiveHint=False,
    idempotentHint=False, openWorldHint=False,
)

TOOLS = [
    # ── Analytics ──
    Tool(
        name="analytics_messages",
        description="Get message volume and activity stats for the last N hours.",
        inputSchema={
            "type": "object",
            "properties": {
                "hours": {"type": "integer", "default": 24},
            },
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="analytics_tasks",
        description="Get task completion stats: pending, completed, failed, avg completion time.",
        inputSchema={"type": "object", "properties": {}},
        annotations=_SAFE_READ,
    ),
    Tool(
        name="analytics_leaderboard",
        description="Agent leaderboard ranked by a metric (tasks_completed, messages_sent, xp, etc.).",
        inputSchema={
            "type": "object",
            "properties": {
                "metric": {"type": "string", "default": "tasks_completed"},
                "limit": {"type": "integer", "default": 10},
            },
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="analytics_agent_activity",
        description="Detailed activity report for a specific agent session.",
        inputSchema={
            "type": "object",
            "properties": {
                "session_id": {"type": "string"},
                "hours": {"type": "integer", "default": 24},
            },
            "required": ["session_id"],
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="analytics_system_health",
        description="Overall system health: active sessions, queue depth, error rate.",
        inputSchema={"type": "object", "properties": {}},
        annotations=_SAFE_READ,
    ),
    Tool(
        name="analytics_snapshot",
        description="Take a point-in-time analytics snapshot for later comparison.",
        inputSchema={"type": "object", "properties": {}},
        annotations=_SAFE_WRITE,
    ),

    # ── Metrics Collector ──
    Tool(
        name="metrics_record",
        description="Record a numeric metric value with optional tags. Stored as time series.",
        inputSchema={
            "type": "object",
            "properties": {
                "name": {"type": "string", "description": "Metric name (e.g., 'api_latency', 'queue_depth')"},
                "value": {"type": "number"},
                "tags": {"type": "object", "description": "Key-value tags for filtering"},
            },
            "required": ["name", "value"],
        },
        annotations=_SAFE_WRITE,
    ),
    Tool(
        name="metrics_get",
        description="Query a metric's time series data with optional time range.",
        inputSchema={
            "type": "object",
            "properties": {
                "name": {"type": "string"},
                "since": {"type": "string", "description": "ISO-8601 start time"},
                "until": {"type": "string", "description": "ISO-8601 end time"},
            },
            "required": ["name"],
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="metrics_latest",
        description="Get the most recent value of a metric.",
        inputSchema={
            "type": "object",
            "properties": {"name": {"type": "string"}},
            "required": ["name"],
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="metrics_list",
        description="List all tracked metric names.",
        inputSchema={"type": "object", "properties": {}},
        annotations=_SAFE_READ,
    ),
    Tool(
        name="metrics_aggregate",
        description="Aggregate a metric over a time period (avg, min, max, sum, count).",
        inputSchema={
            "type": "object",
            "properties": {
                "name": {"type": "string"},
                "period_hours": {"type": "integer", "default": 24},
                "fn": {"type": "string", "description": "avg, min, max, sum, or count", "default": "avg"},
            },
            "required": ["name"],
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="metrics_dashboard",
        description="Get a pre-built dashboard view of key platform metrics.",
        inputSchema={"type": "object", "properties": {}},
        annotations=_SAFE_READ,
    ),

    # ── Health Monitor ──
    Tool(
        name="health_check",
        description="Run a comprehensive health check on all platform subsystems.",
        inputSchema={"type": "object", "properties": {}},
        annotations=_SAFE_READ,
    ),
    Tool(
        name="health_alerts",
        description="Get current active alerts, optionally filtered by severity.",
        inputSchema={
            "type": "object",
            "properties": {
                "severity": {"type": "string", "description": "Filter: info, warning, critical"},
            },
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="health_acknowledge_alert",
        description="Acknowledge an alert to mark it as seen.",
        inputSchema={
            "type": "object",
            "properties": {"alert_id": {"type": "string"}},
            "required": ["alert_id"],
        },
        annotations=_SAFE_WRITE,
    ),
    Tool(
        name="health_sla_report",
        description="Get SLA compliance report for the last N hours.",
        inputSchema={
            "type": "object",
            "properties": {"hours": {"type": "integer", "default": 24}},
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="health_history",
        description="Get health check history over time.",
        inputSchema={
            "type": "object",
            "properties": {
                "hours": {"type": "integer", "default": 24},
                "limit": {"type": "integer", "default": 100},
            },
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="health_trend",
        description="Get health trend analysis (improving/degrading/stable).",
        inputSchema={"type": "object", "properties": {}},
        annotations=_SAFE_READ,
    ),

    # ── Platform Analytics ──
    Tool(
        name="platform_metrics",
        description="Collect and return all platform metrics: agents, channels, tasks, profiles, social, economy, federation.",
        inputSchema={"type": "object", "properties": {}},
        annotations=_SAFE_READ,
    ),
    Tool(
        name="platform_snapshot",
        description="Take a comprehensive platform metrics snapshot.",
        inputSchema={"type": "object", "properties": {}},
        annotations=_SAFE_WRITE,
    ),
    Tool(
        name="platform_snapshots_list",
        description="List recent platform snapshots.",
        inputSchema={
            "type": "object",
            "properties": {"limit": {"type": "integer", "default": 20}},
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="platform_compare",
        description="Compare two snapshots to see what changed.",
        inputSchema={
            "type": "object",
            "properties": {
                "snapshot_a": {"type": "string"},
                "snapshot_b": {"type": "string"},
            },
            "required": ["snapshot_a", "snapshot_b"],
        },
        annotations=_SAFE_READ,
    ),
]


# ── Handlers ──────────────────────────────────────────────────────────────

async def _handle_analytics_messages(args: dict) -> list[TextContent]:
    from brynq.analytics import get_message_stats
    try:
        stats = await asyncio.to_thread(get_message_stats, hours=args.get("hours", 24))
        return [TextContent(type="text", text=json.dumps(stats, indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_analytics_tasks(args: dict) -> list[TextContent]:
    from brynq.analytics import get_task_stats
    try:
        stats = await asyncio.to_thread(get_task_stats)
        return [TextContent(type="text", text=json.dumps(stats, indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_analytics_leaderboard(args: dict) -> list[TextContent]:
    from brynq.analytics import get_leaderboard
    try:
        lb = await asyncio.to_thread(get_leaderboard, metric=args.get("metric", "tasks_completed"), limit=args.get("limit", 10))
        if not lb:
            return [TextContent(type="text", text="No leaderboard data.")]
        lines = [f"Leaderboard ({args.get('metric', 'tasks_completed')}):"]
        for i, entry in enumerate(lb, 1):
            lines.append(f"  {i}. {entry.get('name', entry.get('session_id', '?'))}: {entry.get('value', '?')}")
        return [TextContent(type="text", text="\n".join(lines))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_analytics_agent_activity(args: dict) -> list[TextContent]:
    from brynq.analytics import get_agent_activity
    try:
        activity = await asyncio.to_thread(get_agent_activity, session_id=args["session_id"], hours=args.get("hours", 24))
        return [TextContent(type="text", text=json.dumps(activity, indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_analytics_system_health(args: dict) -> list[TextContent]:
    from brynq.analytics import get_system_health
    try:
        health = await asyncio.to_thread(get_system_health)
        return [TextContent(type="text", text=json.dumps(health, indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_analytics_snapshot(args: dict) -> list[TextContent]:
    from brynq.analytics import take_snapshot
    try:
        snap = await asyncio.to_thread(take_snapshot)
        return [TextContent(type="text", text=f"Analytics snapshot taken: {snap.get('snapshot_id', 'ok')}")]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_metrics_record(args: dict) -> list[TextContent]:
    from brynq.metrics_collector import record_metric
    try:
        await asyncio.to_thread(record_metric, name=args["name"], value=args["value"], tags=args.get("tags"))
        return [TextContent(type="text", text=f"Metric recorded: {args['name']} = {args['value']}")]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_metrics_get(args: dict) -> list[TextContent]:
    from brynq.metrics_collector import get_metric
    try:
        data = await asyncio.to_thread(get_metric, name=args["name"], since=args.get("since"), until=args.get("until"))
        if not data:
            return [TextContent(type="text", text=f"No data for metric '{args['name']}'.")]
        return [TextContent(type="text", text=json.dumps(data, indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_metrics_latest(args: dict) -> list[TextContent]:
    from brynq.metrics_collector import get_latest
    try:
        val = await asyncio.to_thread(get_latest, name=args["name"])
        if val is None:
            return [TextContent(type="text", text=f"No data for metric '{args['name']}'.")]
        return [TextContent(type="text", text=json.dumps(val, indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_metrics_list(args: dict) -> list[TextContent]:
    from brynq.metrics_collector import list_metrics
    try:
        metrics = await asyncio.to_thread(list_metrics)
        if not metrics:
            return [TextContent(type="text", text="No metrics tracked yet.")]
        return [TextContent(type="text", text=f"Tracked metrics ({len(metrics)}):\n" + "\n".join(f"  {m}" for m in metrics))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_metrics_aggregate(args: dict) -> list[TextContent]:
    from brynq.metrics_collector import aggregate
    try:
        result = await asyncio.to_thread(aggregate, name=args["name"], period_hours=args.get("period_hours", 24), fn=args.get("fn", "avg"))
        return [TextContent(type="text", text=json.dumps(result, indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_metrics_dashboard(args: dict) -> list[TextContent]:
    from brynq.metrics_collector import get_dashboard_data
    try:
        data = await asyncio.to_thread(get_dashboard_data)
        return [TextContent(type="text", text=json.dumps(data, indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_health_check(args: dict) -> list[TextContent]:
    from brynq.health_monitor import run_health_check
    try:
        result = await asyncio.to_thread(run_health_check)
        return [TextContent(type="text", text=json.dumps(result, indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_health_alerts(args: dict) -> list[TextContent]:
    from brynq.health_monitor import get_active_alerts, get_alerts
    try:
        if args.get("severity"):
            alerts = await asyncio.to_thread(get_alerts, severity=args["severity"])
        else:
            alerts = await asyncio.to_thread(get_active_alerts)
        if not alerts:
            return [TextContent(type="text", text="No active alerts.")]
        lines = [f"Active alerts ({len(alerts)}):"]
        for a in alerts:
            lines.append(f"  [{a.get('severity', '?').upper()}] {a.get('message', a.get('name', '?'))}")
        return [TextContent(type="text", text="\n".join(lines))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_health_acknowledge_alert(args: dict) -> list[TextContent]:
    from brynq.health_monitor import acknowledge_alert
    try:
        await asyncio.to_thread(acknowledge_alert, alert_id=args["alert_id"])
        return [TextContent(type="text", text=f"Alert '{args['alert_id']}' acknowledged.")]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_health_sla_report(args: dict) -> list[TextContent]:
    from brynq.health_monitor import get_sla_report
    try:
        report = await asyncio.to_thread(get_sla_report, hours=args.get("hours", 24))
        return [TextContent(type="text", text=json.dumps(report, indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_health_history(args: dict) -> list[TextContent]:
    from brynq.health_monitor import get_health_history
    try:
        history = await asyncio.to_thread(get_health_history, hours=args.get("hours", 24), limit=args.get("limit", 100))
        if not history:
            return [TextContent(type="text", text="No health history.")]
        return [TextContent(type="text", text=json.dumps(history[-10:], indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_health_trend(args: dict) -> list[TextContent]:
    from brynq.health_monitor import get_health_trend
    try:
        trend = await asyncio.to_thread(get_health_trend)
        return [TextContent(type="text", text=json.dumps(trend, indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_platform_metrics(args: dict) -> list[TextContent]:
    from brynq.platform_analytics import collect_all_metrics
    try:
        metrics = await asyncio.to_thread(collect_all_metrics)
        return [TextContent(type="text", text=json.dumps(metrics, indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_platform_snapshot(args: dict) -> list[TextContent]:
    from brynq.platform_analytics import take_snapshot
    try:
        snap = await asyncio.to_thread(take_snapshot)
        return [TextContent(type="text", text=f"Platform snapshot taken: {snap.get('snapshot_id', 'ok')}")]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_platform_snapshots_list(args: dict) -> list[TextContent]:
    from brynq.platform_analytics import list_snapshots
    try:
        snaps = await asyncio.to_thread(list_snapshots, limit=args.get("limit", 20))
        if not snaps:
            return [TextContent(type="text", text="No snapshots taken yet.")]
        lines = [f"Platform snapshots ({len(snaps)}):"]
        for s in snaps:
            lines.append(f"  {s.get('snapshot_id', '?')} — {s.get('timestamp', '?')[:19]}")
        return [TextContent(type="text", text="\n".join(lines))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]

async def _handle_platform_compare(args: dict) -> list[TextContent]:
    from brynq.platform_analytics import compare_snapshots
    try:
        diff = await asyncio.to_thread(compare_snapshots, snapshot_a=args["snapshot_a"], snapshot_b=args["snapshot_b"])
        return [TextContent(type="text", text=json.dumps(diff, indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]


# ── Handler Registry ─────────────────────────────────────────────────────

HANDLERS = {
    "analytics_messages": _handle_analytics_messages,
    "analytics_tasks": _handle_analytics_tasks,
    "analytics_leaderboard": _handle_analytics_leaderboard,
    "analytics_agent_activity": _handle_analytics_agent_activity,
    "analytics_system_health": _handle_analytics_system_health,
    "analytics_snapshot": _handle_analytics_snapshot,
    "metrics_record": _handle_metrics_record,
    "metrics_get": _handle_metrics_get,
    "metrics_latest": _handle_metrics_latest,
    "metrics_list": _handle_metrics_list,
    "metrics_aggregate": _handle_metrics_aggregate,
    "metrics_dashboard": _handle_metrics_dashboard,
    "health_check": _handle_health_check,
    "health_alerts": _handle_health_alerts,
    "health_acknowledge_alert": _handle_health_acknowledge_alert,
    "health_sla_report": _handle_health_sla_report,
    "health_history": _handle_health_history,
    "health_trend": _handle_health_trend,
    "platform_metrics": _handle_platform_metrics,
    "platform_snapshot": _handle_platform_snapshot,
    "platform_snapshots_list": _handle_platform_snapshots_list,
    "platform_compare": _handle_platform_compare,
}
