/**
 * MCP Client Sampling Example (Node)
 *
 * Shows how to:
 * 1. Create an MCP client with an onSampling callback
 * 2. Connect to a server that uses sampling
 * 3. Call tools that request LLM completions
 *
 * Run:
 *   pnpm run example:client:sampling
 *   pnpm run example:sampling   (starts server then client)
 *
 * Manually:
 *   1. Start the sampling server: pnpm run example:server:sampling
 *   2. Run: tsx examples/client/node/communication/sampling-client.ts
 */

import { MCPClient, type OnSamplingCallback } from "mcp-use";

const SERVER_URL = process.env.MCP_SERVER_URL ?? "http://localhost:3000/mcp";

async function mockLLM(prompt: string): Promise<string> {
  await new Promise((resolve) => setTimeout(resolve, 100));

  if (prompt.includes("sentiment")) {
    if (
      prompt.toLowerCase().includes("love") ||
      prompt.toLowerCase().includes("great")
    ) {
      return "positive";
    }
    if (
      prompt.toLowerCase().includes("hate") ||
      prompt.toLowerCase().includes("terrible")
    ) {
      return "negative";
    }
    return "neutral";
  }

  if (prompt.includes("Summarize")) {
    return "This is a mock summary of the provided text. In a real implementation, this would be generated by your LLM.";
  }

  if (prompt.includes("Translate")) {
    if (prompt.includes("Spanish")) return "Hola, mundo!";
    return "Translation would appear here";
  }

  return "Mock LLM response";
}

const onSampling: OnSamplingCallback = async (params) => {
  console.log("📥 Received sampling request:");
  console.log("   Messages:", params.messages?.length ?? 0);
  console.log("   Model preferences:", params.modelPreferences);

  const lastMessage = params.messages?.[params.messages.length - 1];
  const content = Array.isArray(lastMessage?.content)
    ? lastMessage.content[0]
    : lastMessage?.content;

  if (
    !content ||
    typeof content !== "object" ||
    !("type" in content) ||
    content.type !== "text"
  ) {
    throw new Error("Only text content is supported in this example");
  }

  const text = "text" in content ? (content as { text: string }).text : "";
  const response = await mockLLM(text);

  console.log("📤 Sending sampling response:", response);

  return {
    role: "assistant",
    content: { type: "text", text: response },
    model: "mock-llm-v1",
    stopReason: "endTurn",
  };
};

async function main() {
  console.log("🚀 Starting Sampling Client Example\n");

  const client = new MCPClient(
    {
      mcpServers: {
        sampling: {
          url: SERVER_URL,
          clientInfo: { name: "sampling-client", version: "1.0.0" },
        },
      },
    },
    { onSampling }
  );

  try {
    console.log("📡 Connecting to sampling server...");
    await client.createAllSessions();
    console.log("✅ Connected!\n");

    const session = client.getSession("sampling");
    if (!session) {
      throw new Error("Failed to get session");
    }

    const connector = session.connector;
    const tools = connector.tools;
    console.log("🔧 Available tools:");
    tools.forEach((tool) => {
      console.log(`   - ${tool.name}: ${tool.description}`);
    });
    console.log();

    console.log("🧪 Testing analyze-sentiment tool...");
    const sentimentResult = await connector.callTool("analyze-sentiment", {
      text: "I love this product! It's amazing!",
    });
    console.log(
      "   Result:",
      (sentimentResult.content[0] as { text: string }).text
    );
    console.log();

    console.log("🧪 Testing summarize-text tool...");
    const summaryResult = await connector.callTool("summarize-text", {
      text: "This is a long piece of text that needs to be summarized. It contains multiple sentences and ideas that should be condensed into a shorter form while preserving the key information.",
      maxLength: 20,
    });
    console.log(
      "   Result:",
      (summaryResult.content[0] as { text: string }).text
    );
    console.log();

    console.log("🧪 Testing translate-text tool...");
    const translateResult = await connector.callTool("translate-text", {
      text: "Hello, world!",
      targetLanguage: "Spanish",
    });
    console.log(
      "   Result:",
      (translateResult.content[0] as { text: string }).text
    );
    console.log();

    console.log("✅ All tests completed successfully!");
  } catch (error: any) {
    console.error("❌ Error:", error.message);
    if (error.stack) {
      console.error(error.stack);
    }
    process.exit(1);
  } finally {
    await client.closeAllSessions();
    console.log("\n👋 Client disconnected");
  }
}

main().catch(console.error);
