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

/**
 * TreeView provider for the MCP Grid Marketplace.
 *
 * Displays the full catalog of available servers that can be installed
 * and activated. Each server shows its tools, config options, and install action.
 */
export class MarketplaceTreeProvider
  implements vscode.TreeDataProvider<MarketplaceItem>
{
  private _onDidChangeTreeData = new vscode.EventEmitter<
    MarketplaceItem | undefined | void
  >();
  readonly onDidChangeTreeData = this._onDidChangeTreeData.event;

  private _servers: ServerInfo[] = [];

  constructor(private readonly _client: BridgeClient) {}

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

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

  async getChildren(element?: MarketplaceItem): Promise<MarketplaceItem[]> {
    if (!element) {
      // Root: categories
      try {
        this._servers = await this._client.listServers();
      } catch {
        this._servers = [];
      }

      if (this._servers.length === 0) {
        const notConnected = new MarketplaceItem(
          "Bridge not connected",
          vscode.TreeItemCollapsibleState.None,
          "info"
        );
        notConnected.iconPath = new vscode.ThemeIcon("warning");
        return [notConnected];
      }

      // Group by category
      const categories = new Map<string, ServerInfo[]>();
      for (const server of this._servers) {
        const cat = server.category || "custom";
        if (!categories.has(cat)) {
          categories.set(cat, []);
        }
        categories.get(cat)!.push(server);
      }

      const catIcons: Record<string, string> = {
        "browser-automation": "browser",
        "data-analytics": "database",
        development: "tools",
        "ai-ml": "hubot",
        communication: "comment-discussion",
        "file-systems": "folder-library",
        "search-web": "search",
        utilities: "wrench",
        custom: "package",
      };

      return Array.from(categories.entries())
        .sort(([a], [b]) => a.localeCompare(b))
        .map(([cat, servers]) => {
          const item = new MarketplaceItem(
            `${this._prettyCat(cat)} (${servers.length})`,
            vscode.TreeItemCollapsibleState.Expanded,
            "category",
            undefined,
            cat
          );
          item.iconPath = new vscode.ThemeIcon(catIcons[cat] || "package");
          return item;
        });
    }

    if (element.kind === "category" && element.categoryId) {
      // Servers in this category
      const servers = this._servers.filter(
        (s) => (s.category || "custom") === element.categoryId
      );

      return servers.map((s) => {
        const opts = s.config_options?.length ?? 0;
        const desc = opts > 0 ? `${opts} options` : "ready to use";
        const item = new MarketplaceItem(
          s.name || s.id,
          vscode.TreeItemCollapsibleState.Collapsed,
          "server",
          s
        );
        item.description = `${s.transport} · ${desc}`;
        item.iconPath = s.enabled
          ? new vscode.ThemeIcon(
              "cloud-download",
              new vscode.ThemeColor("charts.green")
            )
          : new vscode.ThemeIcon(
              "circle-slash",
              new vscode.ThemeColor("charts.red")
            );
        item.tooltip = this._tooltip(s);
        item.contextValue = "marketplace-server";
        return item;
      });
    }

    if (element.kind === "server" && element.serverInfo) {
      // Server details: description, config options inline
      const s = element.serverInfo;
      const children: MarketplaceItem[] = [];

      if (s.description) {
        const desc = new MarketplaceItem(
          s.description,
          vscode.TreeItemCollapsibleState.None,
          "detail"
        );
        desc.iconPath = new vscode.ThemeIcon("info");
        children.push(desc);
      }

      // Config options -- render inline under server (no sub-header)
      const opts = s.config_options ?? [];
      for (const opt of opts) {
        const req = opt.required ? " *" : "";
        const label = `${opt.name}${req}`;
        const item = new MarketplaceItem(
          label,
          vscode.TreeItemCollapsibleState.None,
          "config-option",
          s
        );
        item.iconPath = new vscode.ThemeIcon("gear");
        item.description = `${opt.type}${opt.default ? ` = ${opt.default}` : ""}`;
        const tipMd = new vscode.MarkdownString();
        tipMd.appendMarkdown(`**${opt.name}** (\`${opt.type}\`)\n\n`);
        if (opt.description) {
          tipMd.appendMarkdown(`${opt.description}\n\n`);
        }
        if (opt.default) {
          tipMd.appendMarkdown(`Default: \`${opt.default}\`\n`);
        }
        tipMd.appendMarkdown(opt.required ? "**Required**" : "Optional");
        item.tooltip = tipMd;
        children.push(item);
      }

      return children;
    }

    return [];
  }

  private _prettyCat(cat: string): string {
    return cat
      .split("-")
      .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
      .join(" ");
  }

  private _tooltip(s: ServerInfo): vscode.MarkdownString {
    const md = new vscode.MarkdownString();
    md.appendMarkdown(`**${s.name || s.id}**\n\n`);
    if (s.description) {
      md.appendMarkdown(`${s.description}\n\n`);
    }
    md.appendMarkdown(`- **ID:** \`${s.id}\`\n`);
    md.appendMarkdown(`- **Transport:** ${s.transport}\n`);
    md.appendMarkdown(`- **Category:** ${s.category}\n`);
    md.appendMarkdown(
      `- **Status:** ${s.enabled ? "Available" : "Disabled"}\n`
    );

    const opts = s.config_options ?? [];
    if (opts.length > 0) {
      md.appendMarkdown(`\n**Configurable Options:**\n`);
      for (const o of opts) {
        const req = o.required ? " *(required)*" : "";
        md.appendMarkdown(`- \`${o.name}\` (${o.type})${req}`);
        if (o.description) {
          md.appendMarkdown(` — ${o.description}`);
        }
        md.appendMarkdown("\n");
      }
    }

    md.appendMarkdown(`\n---\n*Click to activate and add to your workspace*`);
    return md;
  }
}

export class MarketplaceItem extends vscode.TreeItem {
  constructor(
    label: string,
    collapsibleState: vscode.TreeItemCollapsibleState,
    public readonly kind: string,
    public readonly serverInfo?: ServerInfo,
    public readonly categoryId?: string
  ) {
    super(label, collapsibleState);
  }
}
