import type { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3'
import Database from 'better-sqlite3'
import { getDialect } from './dialect'
import { schema } from './schema'
import { getDbPath } from './sqlite-path'
import { getDb as getMigratedDb } from '../db'

/**
 * 统一 db 单例。env DB_DIALECT 路由到对应 driver。
 *
 * P0：仅 sqlite 分支。
 * P2：增加 pg 分支（动态 import，类型 NodePgDatabase）。
 * P3：增加 mysql 分支（动态 import，类型 MySql2Database）。
 */

let _db: BetterSQLite3Database<typeof schema> | null = null

/** drizzle db 实例类型，消费方按此引用避免 ReturnType<typeof getDb>。 */
export type Database = BetterSQLite3Database<typeof schema>
export function getDb(): Database {
  if (_db) return _db

  const dialect = getDialect()
  if (dialect !== 'sqlite') {
    throw new Error(
      `[database] Dialect "${dialect}" not implemented yet. P0 supports sqlite only. ` +
        `Set DB_DIALECT=sqlite or leave it unset.`,
    )
  }

  // 复用 db.ts 的 sqlite 实例：该实例在 getDb() 时已跑完所有
  // CREATE TABLE / migration / ensureColumn，避免 drizzle 连接查询到
  // 不存在的表（h5_pages 等新增表只在 db.ts 的 migration 路径里建）。
  const sqlite = getMigratedDb() as Database.Database

  _db = drizzleWrap(sqlite)
  return _db
}

/** 暴露底层 better-sqlite3 实例，供 check-connection 等直接访问。 */
export function getSqliteInstance(): Database.Database | undefined {
  const dialect = getDialect()
  if (dialect !== 'sqlite') return undefined
  // drizzle 不直接暴露底层实例；通过创建一个保留引用的 wrapper 获取
  return _sqliteRef ?? undefined
}

// 内部：在 drizzle 创建时保留底层 sqlite 实例引用
let _sqliteRef: Database.Database | null = null

function drizzleWrap(sqlite: Database.Database): BetterSQLite3Database<typeof schema> {
  const { drizzle } = require('drizzle-orm/better-sqlite3')
  _sqliteRef = sqlite
  // drizzle() 返回 untyped；构造签名与 BetterSQLite3Database<typeof schema> 结构等价
  const wrapped = drizzle(sqlite, { schema }) as BetterSQLite3Database<typeof schema>
  return wrapped
}
