import * as vscode from "vscode";
import { BridgeClient, MetricsSummary, RecentCall } from "../bridge/client";

/**
 * TreeView provider for displaying metrics and recent activity.
 * Shows summary stats and recent tool call history.
 */
export class MetricsTreeProvider
  implements vscode.TreeDataProvider<MetricsTreeItem>
{
  private _onDidChangeTreeData = new vscode.EventEmitter<
    MetricsTreeItem | undefined | void
  >();
  readonly onDidChangeTreeData = this._onDidChangeTreeData.event;

  private _summary: MetricsSummary | null = null;
  private _recentCalls: RecentCall[] = [];

  constructor(private readonly _client: BridgeClient) {}

  refresh(): void {
    this._onDidChangeTreeData.fire();
  }

  getTreeItem(element: MetricsTreeItem): vscode.TreeItem {
    return element;
  }

  async getChildren(element?: MetricsTreeItem): Promise<MetricsTreeItem[]> {
    if (!element) {
      // Root level -- show summary and recent calls sections
      try {
        this._summary = await this._client.getMetrics();
        this._recentCalls = await this._client.getRecentCalls(20);
      } catch {
        return [
          new MetricsTreeItem(
            "Bridge not connected",
            vscode.TreeItemCollapsibleState.None,
            "info"
          ),
        ];
      }

      return [
        new MetricsTreeItem(
          "Summary",
          vscode.TreeItemCollapsibleState.Expanded,
          "summary-group"
        ),
        new MetricsTreeItem(
          `Recent Calls (${this._recentCalls.length})`,
          vscode.TreeItemCollapsibleState.Collapsed,
          "calls-group"
        ),
      ];
    }

    if (element.kind === "summary-group" && this._summary) {
      const s = this._summary;
      const totalCalls = s.total_calls ?? 0;
      const successfulCalls = s.successful_calls ?? 0;
      const failedCalls = s.failed_calls ?? 0;
      const avgLatency = s.avg_latency_ms ?? 0;
      const activeInstances = s.active_instances ?? 0;
      const totalServers = s.total_servers ?? 0;

      const successRate =
        totalCalls > 0
          ? ((successfulCalls / totalCalls) * 100).toFixed(1)
          : "0.0";

      return [
        this._statItem(
          "Total Calls",
          String(totalCalls),
          "graph-line"
        ),
        this._statItem(
          "Success Rate",
          `${successRate}%`,
          failedCalls > 0 ? "warning" : "pass"
        ),
        this._statItem(
          "Avg Latency",
          `${avgLatency.toFixed(1)}ms`,
          "clock"
        ),
        this._statItem(
          "Active Instances",
          String(activeInstances),
          "server-process"
        ),
        this._statItem(
          "Registered Servers",
          String(totalServers),
          "database"
        ),
      ];
    }

    if (element.kind === "calls-group") {
      if (this._recentCalls.length === 0) {
        return [
          new MetricsTreeItem(
            "No recent calls",
            vscode.TreeItemCollapsibleState.None,
            "info"
          ),
        ];
      }

      return this._recentCalls.map((call) => {
        const icon = call.success
          ? new vscode.ThemeIcon(
              "pass",
              new vscode.ThemeColor("charts.green")
            )
          : new vscode.ThemeIcon(
              "error",
              new vscode.ThemeColor("charts.red")
            );

        const latency = call.latency_ms ?? 0;
        const item = new MetricsTreeItem(
          call.tool_name || "unknown",
          vscode.TreeItemCollapsibleState.None,
          "call"
        );
        item.iconPath = icon;
        item.description = `${latency.toFixed(0)}ms | ${call.server_id || "?"}`;
        item.tooltip = this._buildCallTooltip(call);
        return item;
      });
    }

    return [];
  }

  private _statItem(
    label: string,
    value: string,
    icon: string
  ): MetricsTreeItem {
    const item = new MetricsTreeItem(
      label,
      vscode.TreeItemCollapsibleState.None,
      "stat"
    );
    item.description = value;
    item.iconPath = new vscode.ThemeIcon(icon);
    return item;
  }

  private _buildCallTooltip(call: RecentCall): vscode.MarkdownString {
    const md = new vscode.MarkdownString();
    md.appendMarkdown(`**${call.tool_name || "unknown"}**\n\n`);
    md.appendMarkdown(
      `- **Status:** ${call.success ? "Success" : "Failed"}\n`
    );
    md.appendMarkdown(`- **Server:** ${call.server_id || "?"}\n`);
    md.appendMarkdown(`- **Latency:** ${(call.latency_ms ?? 0).toFixed(1)}ms\n`);
    md.appendMarkdown(`- **Time:** ${call.timestamp || "?"}\n`);
    if (call.error_message) {
      md.appendMarkdown(`- **Error:** ${call.error_message}\n`);
    }
    return md;
  }
}

export class MetricsTreeItem extends vscode.TreeItem {
  constructor(
    label: string,
    collapsibleState: vscode.TreeItemCollapsibleState,
    public readonly kind: string
  ) {
    super(label, collapsibleState);

    if (kind === "info") {
      this.iconPath = new vscode.ThemeIcon("info");
    } else if (kind === "summary-group") {
      this.iconPath = new vscode.ThemeIcon("graph");
    } else if (kind === "calls-group") {
      this.iconPath = new vscode.ThemeIcon("history");
    }
  }
}
