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

/**
 * Agent Repository。封装 agents 表的所有查询。
 *
 * 设计约定：
 * - 返回类型由 drizzle 推断，消费方不再写 `as Record<string, unknown>`
 * - 删除操作用 db.transaction 包裹级联（无 FK）：
 *   SET NULL 其它 agent 的 parent_id → SET NULL channel_permission_links.agent_id
 *   → DELETE agent_skills → DELETE agent
 * - 时间默认值由 schema 的 default 处理，UPDATE 显式刷新用 nowExpr()
 */

export const agentRepo = {
  /** 列出用户的所有 agent，按 is_main 倒序、updated_at 倒序 */
  listByUser(userId: string) {
    return getDb()
      .select()
      .from(agents)
      .where(eq(agents.userId, userId))
      .orderBy(desc(agents.isMain), desc(agents.updatedAt))
      .all()
  },

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

  /** 按 id 查（不限 user，内部流程用） */
  findById(id: string) {
    return getDb().select().from(agents).where(eq(agents.id, id)).get()
  },

  /** 创建 agent，返回新建行 */
  create(data: {
    id: string
    userId: string
    name?: string
    description?: string
    model?: string
    permissionMode?: string
    isMain?: number
    parentId?: string | null
    instructions?: string
    soul?: string
    identity?: string
    toolsConfig?: string
  }) {
    getDb()
      .insert(agents)
      .values({
        id: data.id,
        userId: data.userId,
        name: data.name ?? 'New Agent',
        description: data.description ?? '',
        model: data.model ?? 'claude-sonnet-4-6',
        permissionMode: data.permissionMode ?? 'confirm',
        isMain: data.isMain ?? 0,
        parentId: data.parentId ?? null,
        instructions: data.instructions ?? '',
        soul: data.soul ?? '',
        identity: data.identity ?? '',
        toolsConfig: data.toolsConfig ?? '{}',
      })
      .run()
    return this.findByIdAndUser(data.id, data.userId)
  },

  /** 更新指定字段并刷新 updated_at（WHERE id + user_id），返回更新后行 */
  updateFields(id: string, userId: string, fields: Partial<typeof agents.$inferInsert>) {
    getDb()
      .update(agents)
      .set({ ...fields, updatedAt: nowExpr() })
      .where(and(eq(agents.id, id), eq(agents.userId, userId)))
      .run()
    return this.findByIdAndUser(id, userId)
  },

  /**
   * 删除 agent：事务级联（替代原 FK 的 SET NULL + CASCADE）。
   * 1. SET NULL 其它 agent 的 parent_id（被删 agent 作为父的引用）
   * 2. SET NULL channel_permission_links.agent_id
   * 3. DELETE agent_skills（解绑所有 skill）
   * 4. DELETE agent（WHERE id + user_id）
   */
  deleteById(id: string, userId: string) {
    getDb().transaction((tx) => {
      tx.update(agents).set({ parentId: null }).where(eq(agents.parentId, id)).run()
      tx.update(channelPermissionLinks)
        .set({ agentId: null })
        .where(eq(channelPermissionLinks.agentId, id))
        .run()
      tx.delete(agentSkills).where(eq(agentSkills.agentId, id)).run()
      tx.delete(agents)
        .where(and(eq(agents.id, id), eq(agents.userId, userId)))
        .run()
    })
  },
}
