import "server-only"

import {
  getSystemSetting,
  upsertSystemSetting,
} from "./data-access-system-settings"

/**
 * 2FA (TOTP) 数据访问层
 *
 * 复用 system_settings 表（category = "security_policy"），通过用户 ID 限定键名作用域。
 * 避免新增数据库表，保持 schema 稳定。
 *
 * 键命名约定：
 * - twoFactorEnabled:${userId}        — "true" | "false"
 * - twoFactorMethod:${userId}         — "totp"
 * - twoFactorEnabledAt:${userId}      — ISO 时间戳
 * - totpSecret:${userId}              — base32 密钥（仅在 setup 阶段写入，verify 后保留）
 * - totpBackupCodes:${userId}         — JSON 数组（bcrypt 哈希后的备份码列表）
 */

const CATEGORY = "security_policy" as const

function k(name: string, userId: string): string {
  return `${name}:${userId}`
}

// --- 2FA 开关状态 ---

export async function getTwoFactorEnabled(userId: string): Promise<boolean> {
  const record = await getSystemSetting(CATEGORY, k("twoFactorEnabled", userId))
  return record?.value === "true"
}

export async function setTwoFactorEnabled(
  userId: string,
  enabled: boolean,
): Promise<void> {
  await upsertSystemSetting({
    category: CATEGORY,
    key: k("twoFactorEnabled", userId),
    value: enabled ? "true" : "false",
    valueType: "boolean",
    updatedBy: userId,
  })
}

export async function getTwoFactorEnabledAt(
  userId: string,
): Promise<string | null> {
  const record = await getSystemSetting(CATEGORY, k("twoFactorEnabledAt", userId))
  return record?.value || null
}

export async function setTwoFactorEnabledAt(
  userId: string,
  iso: string,
): Promise<void> {
  await upsertSystemSetting({
    category: CATEGORY,
    key: k("twoFactorEnabledAt", userId),
    value: iso,
    valueType: "string",
    updatedBy: userId,
  })
}

// --- TOTP 密钥 ---

export async function getTotpSecret(userId: string): Promise<string | null> {
  const record = await getSystemSetting(CATEGORY, k("totpSecret", userId))
  return record?.value ?? null
}

export async function setTotpSecret(
  userId: string,
  secret: string,
): Promise<void> {
  await upsertSystemSetting({
    category: CATEGORY,
    key: k("totpSecret", userId),
    value: secret,
    valueType: "string",
    updatedBy: userId,
  })
}

export async function deleteTotpSecret(userId: string): Promise<void> {
  // 用空字符串表示已删除（system_settings 无删除 API，空值等同无密钥）
  await upsertSystemSetting({
    category: CATEGORY,
    key: k("totpSecret", userId),
    value: "",
    valueType: "string",
    updatedBy: userId,
  })
}

// --- 备份码 ---

export async function getBackupCodesHashed(
  userId: string,
): Promise<string | null> {
  const record = await getSystemSetting(CATEGORY, k("totpBackupCodes", userId))
  return record?.value ?? null
}

export async function setBackupCodesHashed(
  userId: string,
  hashedJson: string,
): Promise<void> {
  await upsertSystemSetting({
    category: CATEGORY,
    key: k("totpBackupCodes", userId),
    value: hashedJson,
    valueType: "json",
    updatedBy: userId,
  })
}

export async function deleteBackupCodes(userId: string): Promise<void> {
  await upsertSystemSetting({
    category: CATEGORY,
    key: k("totpBackupCodes", userId),
    value: "[]",
    valueType: "json",
    updatedBy: userId,
  })
}
