import "server-only"

import { cache } from "react"
import { eq, and } from "drizzle-orm"

import { db } from "@/shared/db"
import { systemSettings } from "@/shared/db/schema"

/**
 * 选课模块配置化设置（P2-4 新增）。
 *
 * 设计原则：
 * - 复用全局 `system_settings` 表（category="elective"），避免新增独立表
 * - 支持按年级覆盖（key=`creditLimit:grade:<gradeId>`），fallback 到全局（key=`creditLimit:default`）
 * - 用 React `cache()` 包装，单次请求内去重
 * - 配置缺失时使用默认值（向后兼容）
 *
 * 配置项：
 * - `creditLimit:default` / `creditLimit:grade:<gradeId>`：学期学分上限（默认 10）
 * - `capacityNotifyThreshold`：容量阈值通知比例 0-1（默认 0.9）
 */

const SETTINGS_CATEGORY = "elective"

/** 默认学期学分上限（K12 选修课） */
const DEFAULT_MAX_CREDIT_PER_TERM = 10
/** 默认容量阈值通知比例（90%） */
const DEFAULT_CAPACITY_NOTIFY_THRESHOLD = 0.9

/**
 * 读取 system_settings 中指定 key 的值。
 * 失败或未配置时返回 null（不抛错，保证向后兼容）。
 */
async function readSettingValue(key: string): Promise<string | null> {
  const [row] = await db
    .select({ value: systemSettings.value, valueType: systemSettings.valueType })
    .from(systemSettings)
    .where(
      and(
        eq(systemSettings.category, SETTINGS_CATEGORY),
        eq(systemSettings.key, key)
      )
    )
    .limit(1)
  return row?.value ?? null
}

/**
 * 获取学期学分上限（P2-4 新增）。
 *
 * 查询顺序：
 * 1. 若传入 gradeId，先查 `creditLimit:grade:<gradeId>`
 * 2. 若未配置或未传入 gradeId，fallback 到 `creditLimit:default`
 * 3. 都未配置则返回默认值 10
 *
 * @param gradeId 学生所在年级 ID（可选）
 */
export const getElectiveCreditLimit = cache(
  async (gradeId?: string | null): Promise<number> => {
    if (gradeId) {
      const gradeValue = await readSettingValue(`creditLimit:grade:${gradeId}`)
      if (gradeValue !== null) {
        const parsed = Number(gradeValue)
        if (!Number.isNaN(parsed) && parsed > 0) return parsed
      }
    }
    const defaultValue = await readSettingValue("creditLimit:default")
    if (defaultValue !== null) {
      const parsed = Number(defaultValue)
      if (!Number.isNaN(parsed) && parsed > 0) return parsed
    }
    return DEFAULT_MAX_CREDIT_PER_TERM
  }
)

/**
 * 获取容量阈值通知比例（P2-4 新增）。
 *
 * 当课程 `enrolledCount >= capacity * threshold` 时触发管理员通知。
 * 默认 0.9（90%）。
 */
export const getCapacityNotifyThreshold = cache(
  async (): Promise<number> => {
    const value = await readSettingValue("capacityNotifyThreshold")
    if (value !== null) {
      const parsed = Number(value)
      if (!Number.isNaN(parsed) && parsed > 0 && parsed <= 1) return parsed
    }
    return DEFAULT_CAPACITY_NOTIFY_THRESHOLD
  }
)

/** 导出默认值常量（供测试与文档引用） */
export const ELECTIVE_DEFAULTS = {
  MAX_CREDIT_PER_TERM: DEFAULT_MAX_CREDIT_PER_TERM,
  CAPACITY_NOTIFY_THRESHOLD: DEFAULT_CAPACITY_NOTIFY_THRESHOLD,
} as const
