import { getDb } from '../client'
import { mcpServers } from '../schema'
import { eq, and, desc, sql } from 'drizzle-orm'
import { nowExpr } from '../shared/dialect-helpers'

/**
 * McpServer Repository。封装 mcp_servers 表的所有查询。
 *
 * 设计约定：
 * - 用户隔离：所有写操作和单点查询都带 user_id 条件（与原 route SQL 一致）
 * - status 单字段更新不刷新 updated_at（保持与原 POST /api/mcp、test route 语义等价）
 * - 多字段 PATCH 显式刷新 updated_at（保持与原 PATCH route 语义等价）
 * - 唯一索引 idx_mcp_servers_user_name(user_id, name) 支撑 findByNameAndUser
 */
export const mcpServerRepo = {
  /** 列出用户的所有 MCP server，按 updated_at 倒序 */
  listByUser(userId: string) {
    return getDb()
      .select()
      .from(mcpServers)
      .where(eq(mcpServers.userId, userId))
      .orderBy(desc(mcpServers.updatedAt))
      .all()
  },

  /** 按 id + user 查单个 server */
  findByIdAndUser(id: string, userId: string) {
    return getDb()
      .select()
      .from(mcpServers)
      .where(and(eq(mcpServers.id, id), eq(mcpServers.userId, userId)))
      .get()
  },

  /** 按 name + user 查（命中唯一索引 idx_mcp_servers_user_name） */
  findByNameAndUser(name: string, userId: string) {
    return getDb()
      .select()
      .from(mcpServers)
      .where(and(eq(mcpServers.name, name), eq(mcpServers.userId, userId)))
      .get()
  },

  /** 列出用户启用的 server（mcp-loader 用：仅取连接所需字段） */
  listEnabledByUser(userId: string) {
    return getDb()
      .select({
        id: mcpServers.id,
        name: mcpServers.name,
        protocol: mcpServers.protocol,
        config: mcpServers.config,
      })
      .from(mcpServers)
      .where(and(eq(mcpServers.enabled, 1), eq(mcpServers.userId, userId)))
      .all()
  },

  /** 列出全局匿名用户（user_id=''）启用的 server */
  listEnabledAnonymous() {
    return getDb()
      .select({
        id: mcpServers.id,
        name: mcpServers.name,
        protocol: mcpServers.protocol,
        config: mcpServers.config,
      })
      .from(mcpServers)
      .where(and(eq(mcpServers.enabled, 1), eq(mcpServers.userId, '')))
      .all()
  },

  /** 创建 server（其余字段走 schema 默认值：enabled=1, status='disconnected'） */
  create(data: {
    id: string
    name: string
    protocol: string
    config: string
    userId: string
  }) {
    getDb()
      .insert(mcpServers)
      .values({
        id: data.id,
        name: data.name,
        protocol: data.protocol,
        config: data.config,
        userId: data.userId,
      })
      .run()
  },

  /** 更新 status 单字段（不刷新 updated_at，保持原 route 语义） */
  updateStatus(id: string, userId: string, status: string) {
    getDb()
      .update(mcpServers)
      .set({ status })
      .where(and(eq(mcpServers.id, id), eq(mcpServers.userId, userId)))
      .run()
  },

  /**
   * 多字段更新并刷新 updated_at（保持原 PATCH route 语义）。
   * 仅接受 route 中可更新的字段；enabled 转为 0/1 整数。
   */
  updateFields(
    id: string,
    userId: string,
    fields: {
      name?: string
      protocol?: string
      config?: string
      enabled?: boolean
      status?: string
    },
  ) {
    const set: Record<string, unknown> = { updatedAt: nowExpr() }
    if (fields.name !== undefined) set.name = fields.name
    if (fields.protocol !== undefined) set.protocol = fields.protocol
    if (fields.config !== undefined) set.config = fields.config
    if (fields.enabled !== undefined) set.enabled = fields.enabled ? 1 : 0
    if (fields.status !== undefined) set.status = fields.status

    getDb()
      .update(mcpServers)
      .set(set)
      .where(and(eq(mcpServers.id, id), eq(mcpServers.userId, userId)))
      .run()
  },

  /** 删除 server（按 id + user） */
  deleteByIdAndUser(id: string, userId: string) {
    getDb()
      .delete(mcpServers)
      .where(and(eq(mcpServers.id, id), eq(mcpServers.userId, userId)))
      .run()
  },

  /** 统计用户的 server 数（用于配额/上限检查） */
  countByUser(userId: string): number {
    const row = getDb()
      .select({ c: sql<number>`count(*)` })
      .from(mcpServers)
      .where(eq(mcpServers.userId, userId))
      .get()
    return row?.c ?? 0
  },
}
