import { type EncodeOptions, encodeUrlPayload } from '@protocol-launcher/shared'

/**
 * MCP Server definition.
 *
 * Represents a resolved MCP server configuration used by the client
 * for discovery, display, and runtime communication.
 *
 * @link https://github.com/CherryHQ/cherry-studio/blob/main/src/renderer/src/types/mcp.ts
 * @link https://github.com/CherryHQ/cherry-studio/blob/main/src/renderer/src/types/index.ts#L693
 */
export type MCPServer = {
  /**
   * Server internal ID.
   *
   * Optional unique identifier used internally to distinguish servers.
   * This value is usually generated by the system.
   */
  id?: string

  /**
   * Server name.
   *
   * Optional human-readable name used for identification and display.
   */
  name?: string

  /**
   * Server description.
   *
   * Optional text describing the server’s purpose, capabilities,
   * or supported features.
   */
  description?: string

  /**
   * Server communication type.
   *
   * Defines how the MCP client communicates with the server:
   * - `stdio`: Standard input/output based communication
   * - `streamableHttp`: HTTP-based streaming communication
   * - `sse`: Server-Sent Events (SSE) communication
   */
  type: 'stdio' | 'streamableHttp' | 'sse'

  /**
   * Command used to start the server.
   *
   * Examples: `npx`, `uvx`
   */
  command?: string

  /**
   * Arguments passed to the command.
   *
   * Typically, includes the package name or script path.
   */
  args?: string[]

  /**
   * Registry URL.
   *
   * Optional registry address used to resolve or install the server package.
   */
  registryUrl?: string

  /**
   * Environment variables injected when starting the server.
   *
   * Key-value pairs where both key and value are strings.
   */
  env?: Record<string, string>

  /**
   * Base URL of the server.
   *
   * The primary access address used to communicate with the server.
   * This field takes precedence over any raw URL or alias configuration.
   */
  baseUrl?: string

  /**
   * Custom request headers.
   *
   * Optional key-value pairs that will be sent as HTTP headers
   * when making requests to the server.
   */
  headers?: Record<string, string>

  /**
   * Provider name.
   *
   * Identifies the organization or individual that provides
   * or maintains this MCP server.
   */
  provider?: string

  /**
   * Provider URL.
   *
   * Optional link to the provider’s official website
   * or documentation page.
   */
  providerUrl?: string

  /**
   * Logo URL.
   *
   * Optional URL pointing to the server’s logo image,
   * typically used for UI display.
   */
  logoUrl?: string

  /**
   * Server tags.
   *
   * Optional list of tags used for categorization,
   * filtering, or search indexing.
   */
  tags?: string[]

  /**
   * Request timeout.
   *
   * Optional timeout duration (in seconds) for requests
   * made to this server.
   *
   * @default 60
   */
  timeout?: number

  /**
   * Whether the server is long-running.
   *
   * Indicates whether the server process
   * should remain running continuously.
   */
  longRunning?: boolean

  /**
   * Reference link.
   *
   * Optional documentation, repository, or homepage URL
   * for additional information about the server.
   */
  reference?: string

  /**
   * Search keyword.
   *
   * Keyword used to improve server discoverability
   * in search or filtering scenarios.
   */
  searchKey?: string

  /**
   * Version of the DXT package.
   *
   * Optional version identifier of the installed DXT package.
   */
  dxtVersion?: string

  /**
   * Path where the DXT package was extracted.
   *
   * Optional filesystem path of the extracted DXT package.
   */
  dxtPath?: string

  /**
   * Disabled tools list.
   *
   * Optional list of tool names that are disabled on this server.
   * Disabled tools will not be available for invocation.
   */
  disabledTools?: string[]

  /**
   * Disabled auto-approval tools list.
   *
   * Optional list of tool names for which auto-approval is disabled.
   * These tools will always require explicit user confirmation
   * before execution.
   */
  disabledAutoApproveTools?: string[]
}

/**
 * MCP Server definition.
 *
 * Represents a resolved MCP server configuration used by the client
 * for discovery, display, and runtime communication.
 *
 * @link https://github.com/CherryHQ/cherry-studio/blob/main/src/renderer/src/types/mcp.ts
 */
export type MCPServerWithName = Omit<MCPServer, 'name'> & {
  /**
   * Server name.
   *
   * human-readable name used for identification and display.
   */
  name: string
}

/**
 * Install MCP Server
 * @param payload MCP Server definition
 * @param options Encode options
 * @returns Install MCP Server URL
 * @example
 * installMCP([
 *   {
 *     name: 'server-everything',
 *     type: 'stdio',
 *     command: 'npx',
 *     args: ['-y', '@modelcontextprotocol/server-everything'],
 *   },
 *   {
 *     name: '企查查企业信息 MCP',
 *     description: '企业信息 MCP 提供全面的企业画像分析与企业信息洞察服务，助您快速验证企业真实性、评估其稳定性和发展轨迹，为您的商业行动提供坚实的数据支撑。',
 *     type: 'streamableHttp',
 *     baseUrl: 'https://mcp.qcc.com/basic/stream',
 *     headers: {
 *       Authorization: 'REPLACE_WITH_YOUR_TOKEN',
 *     },
 *     provider: 'QCC',
 *     providerUrl: 'https://openapi.qcc.com/',
 *     logoUrl: 'https://openapi.qcc.com/favicon.ico',
 *     tags: ['企业信息'],
 *     timeout: 30,
 *   },
 *   {
 *     name: '企查查企业信息 MCP',
 *     description: '企业信息 MCP 提供全面的企业画像分析与企业信息洞察服务，助您快速验证企业真实性、评估其稳定性和发展轨迹，为您的商业行动提供坚实的数据支撑。',
 *     type: 'sse',
 *     baseUrl: 'https://mcp.qcc.com/basic/sse',
 *     headers: {
 *       Authorization: 'REPLACE_WITH_YOUR_TOKEN',
 *     },
 *     provider: 'QCC',
 *     providerUrl: 'https://openapi.qcc.com/',
 *     logoUrl: 'https://openapi.qcc.com/favicon.ico',
 *     tags: ['企业信息'],
 *     timeout: 30,
 *   },
 * })
 * // => 'cherrystudio://mcp/install?servers=xxx'
 * @link https://github.com/CherryHQ/cherry-studio/blob/main/src/main/services/urlschema/mcp-install.ts#L39
 */
export function installMCP(
  payload: MCPServerWithName | MCPServerWithName[] | { mcpServers: Record<string, MCPServer> },
  options?: EncodeOptions,
) {
  const encodedPayload = encodeUrlPayload(payload, options)
  return `cherrystudio://mcp/install?servers=${encodedPayload}`
}
