import "server-only"

import { and, desc, eq, or, type SQL } from "drizzle-orm"

import { db } from "@/shared/db"
import { aiProviders } from "@/shared/db/schema"
import { getSession } from "@/shared/lib/session"
import { Permissions } from "@/shared/types/permissions"

import { decryptAiApiKey } from "./api-key-crypto"

export type AiProviderConfig = {
  apiKey: string
  baseUrl?: string
  model: string
  /** Provider 类型标识（用于客户端特殊处理，如 Ollama 本地部署） */
  provider?: string
}

type ProviderAccessRow = {
  apiKeyEncrypted: string
  baseUrl: string | null
  model: string
  provider: string
  visibility: "public" | "private"
  createdBy: string | null
}

type UserContext = { userId: string; isAdmin: boolean }

/**
 * 解析当前用户上下文，用于可见性校验
 *
 * @returns 用户上下文，或 null（无 session 时）
 */
async function resolveUserContext(): Promise<UserContext | null> {
  const session = await getSession()
  const userId = session?.user?.id
  if (!userId) return null
  const permissions = (session.user.permissions ?? []) as string[]
  return {
    userId,
    isAdmin: permissions.includes(Permissions.AI_CONFIGURE),
  }
}

/**
 * 校验当前用户是否有权访问指定 Provider
 *
 * 规则：
 *   - 无 session（系统路径）：允许（向后兼容）
 *   - 管理员（AI_CONFIGURE）：允许访问任意 Provider
 *   - 普通用户：仅允许访问 public Provider 或自己创建的 private Provider
 */
function canAccessProvider(
  provider: { visibility: "public" | "private"; createdBy: string | null },
  userCtx: UserContext | null
): boolean {
  if (!userCtx) return true
  if (userCtx.isAdmin) return true
  if (provider.visibility === "public") return true
  if (provider.createdBy === userCtx.userId) return true
  return false
}

/**
 * 构造可见性过滤条件
 *
 * 管理员或无 session 时返回 undefined（不过滤）；
 * 普通用户返回 (visibility = public OR createdBy = userId)。
 */
function buildVisibilityFilter(userCtx: UserContext | null): SQL | undefined {
  if (!userCtx || userCtx.isAdmin) return undefined
  return or(
    eq(aiProviders.visibility, "public"),
    eq(aiProviders.createdBy, userCtx.userId)
  ) ?? undefined
}

/** Ollama 默认 baseUrl（OpenAI 兼容端点） */
const OLLAMA_DEFAULT_BASE_URL = "http://localhost:11434/v1"

/** Ollama 占位符 API Key（本地部署无需真实密钥，OpenAI SDK 需要非空值） */
const OLLAMA_PLACEHOLDER_API_KEY = "ollama"

function toConfig(row: ProviderAccessRow): AiProviderConfig {
  const isOllama = row.provider === "ollama"
  const apiKey = isOllama
    ? OLLAMA_PLACEHOLDER_API_KEY
    : decryptAiApiKey(row.apiKeyEncrypted)
  const baseUrl = row.baseUrl ?? (isOllama ? OLLAMA_DEFAULT_BASE_URL : undefined)
  return {
    apiKey,
    baseUrl,
    model: row.model,
    provider: row.provider,
  }
}

const selectColumns = {
  apiKeyEncrypted: aiProviders.apiKeyEncrypted,
  baseUrl: aiProviders.baseUrl,
  model: aiProviders.model,
  provider: aiProviders.provider,
  visibility: aiProviders.visibility,
  createdBy: aiProviders.createdBy,
} as const

export const getAiProviderConfig = async (providerId?: string): Promise<AiProviderConfig> => {
  const userCtx = await resolveUserContext()

  if (providerId) {
    const [selected] = await db
      .select(selectColumns)
      .from(aiProviders)
      .where(eq(aiProviders.id, providerId))
      .limit(1)
    if (!selected) throw new Error("AI provider not configured")
    if (!canAccessProvider(selected, userCtx)) {
      throw new Error("AI provider access denied")
    }
    return toConfig(selected)
  }

  const visibilityFilter = buildVisibilityFilter(userCtx)

  const defaultWhere = visibilityFilter
    ? and(eq(aiProviders.isDefault, true), visibilityFilter)
    : eq(aiProviders.isDefault, true)

  const [active] = await db
    .select(selectColumns)
    .from(aiProviders)
    .where(defaultWhere)
    .orderBy(desc(aiProviders.updatedAt))
    .limit(1)
  if (active) return toConfig(active)

  const [fallback] = await db
    .select(selectColumns)
    .from(aiProviders)
    .where(visibilityFilter ?? undefined)
    .orderBy(desc(aiProviders.updatedAt))
    .limit(1)
  if (!fallback) throw new Error("AI provider not configured")

  return toConfig(fallback)
}
