/**
 * MCP Server entity types
 *
 * Defines Zod schemas and inferred types for MCP server entities.
 * DTO/Query/API schemas live in `@shared/data/api/schemas/mcpServers`.
 */

import * as z from 'zod'

// ============================================================================
// Shared Sub-Schemas
// ============================================================================

/** MCP server configuration sample */
export const McpConfigSampleSchema = z.object({
  command: z.string(),
  args: z.array(z.string()),
  env: z.record(z.string(), z.string()).optional()
})
export type McpConfigSample = z.infer<typeof McpConfigSampleSchema>

/** MCP Server communication protocol */
export const McpServerTypeSchema = z.enum(['stdio', 'sse', 'streamableHttp', 'inMemory'])
export type McpServerType = z.infer<typeof McpServerTypeSchema>

/** MCP Server install source */
export const McpServerInstallSourceSchema = z.enum(['builtin', 'manual', 'protocol', 'unknown'])
export type McpServerInstallSource = z.infer<typeof McpServerInstallSourceSchema>

// ============================================================================
// McpServer Entity
// ============================================================================

/**
 * Complete MCP Server entity as stored in database.
 *
 * Nullable DB columns are represented as optional (`?`) — the service layer
 * converts SQL NULL to `undefined` so consumers don't need to handle `null`.
 */
export const McpServerSchema = z.strictObject({
  /** Server ID (UUID v4, auto-generated by database) */
  id: z.uuidv4(),
  /** Server name */
  name: z.string().min(1),
  /** Communication type */
  type: McpServerTypeSchema.optional(),
  /** Server description */
  description: z.string().optional(),
  /** Server URL address */
  baseUrl: z.string().optional(),
  /** Command to start the server */
  command: z.string().optional(),
  /** Registry URL */
  registryUrl: z.string().optional(),
  /** Arguments passed to the command */
  args: z.array(z.string()).optional(),
  /** Environment variables */
  env: z.record(z.string(), z.string()).optional(),
  /** Custom request headers */
  headers: z.record(z.string(), z.string()).optional(),
  /** Provider name */
  provider: z.string().optional(),
  /** Provider URL */
  providerUrl: z.string().optional(),
  /** Logo URL */
  logoUrl: z.string().optional(),
  /** Tags for categorization */
  tags: z.array(z.string()).optional(),
  /** Whether the server is long running */
  longRunning: z.boolean().optional(),
  /** Timeout in seconds */
  timeout: z.number().optional(),
  /** DXT package version */
  dxtVersion: z.string().optional(),
  /** DXT package extracted path */
  dxtPath: z.string().optional(),
  /** Reference link */
  reference: z.string().optional(),
  /** Search key */
  searchKey: z.string().optional(),
  /** Configuration sample */
  configSample: McpConfigSampleSchema.optional(),
  /** Disabled tools */
  disabledTools: z.array(z.string()).optional(),
  /** Disabled auto-approve tools */
  disabledAutoApproveTools: z.array(z.string()).optional(),
  /** Whether the server needs configuration */
  shouldConfig: z.boolean().optional(),
  /** Sort order for display */
  sortOrder: z.number().optional(),
  /** Whether the server is active */
  isActive: z.boolean(),
  /** Install source */
  installSource: McpServerInstallSourceSchema.optional(),
  /** Whether the server is trusted */
  isTrusted: z.boolean().optional(),
  /** Timestamp when trusted */
  trustedAt: z.number().optional(),
  /** Timestamp when installed */
  installedAt: z.number().optional(),
  /** Creation timestamp (ISO string) */
  createdAt: z.iso.datetime().optional(),
  /** Last update timestamp (ISO string) */
  updatedAt: z.iso.datetime().optional()
})

export type McpServer = z.infer<typeof McpServerSchema>
