/* eslint-disable no-console */
/**
 * SQLite 迁移运行器。
 *
 * 三种情况：
 *   1. 全新安装（无 forge.db）：用 drizzle-kit push 建表，无需 baseline。
 *   2. 旧库（有表但无 __drizzle_migrations）：写 baseline 标记，标记 0000 已应用，
 *      再跑后续 drizzle migration（如 0001 移除外键）。
 *   3. 已迁移库（有 __drizzle_migrations）：直接跑 drizzle migrate。
 *
 * 用法：pnpm db:migrate
 */
import Database from 'better-sqlite3'
import path from 'node:path'
import fs from 'node:fs'
import { getDbPath } from '../src/lib/database/sqlite-path'
import { schema } from '../src/lib/database/schema/sqlite'

const dbPath = getDbPath()
const MIGRATIONS_DIR = path.resolve(__dirname, '../migrations/sqlite')

function main() {
  const isNewInstall = !fs.existsSync(dbPath) || fs.statSync(dbPath).size === 0

  // 用 better-sqlite3 直接打开，drizzle migrate 通过 migrate() API 跑
  const sqlite = new Database(dbPath)
  sqlite.pragma('journal_mode = WAL')
  sqlite.pragma('foreign_keys = OFF')

  const hasMigrationsTable =
    sqlite
      .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='__drizzle_migrations'")
      .get() !== undefined

  console.log(`[migrate] db: ${dbPath}`)
  console.log(`[migrate] new install: ${isNewInstall}`)
  console.log(`[migrate] has __drizzle_migrations: ${hasMigrationsTable}`)

  if (isNewInstall) {
    // 情况 1：全新安装——用 drizzle push 建 schema
    console.log('[migrate] fresh install → using drizzle push semantics')
    pushSchema(sqlite)
  } else if (!hasMigrationsTable) {
    // 情况 2：旧库——写 baseline 标记，再跑 drizzle migrate
    console.log('[migrate] legacy db detected → seeding baseline marker')
    seedBaselineMarker(sqlite)
    pushSchema(sqlite) // 应用 schema diff（去 FK 等）
  } else {
    // 情况 3：已迁移库——直接 push（开发态）或 migrate（生产态）
    console.log('[migrate] existing drizzle db → pushing schema diff')
    pushSchema(sqlite)
  }

  sqlite.close()
  console.log('[migrate] done')
}

/**
 * 全新安装或开发态：用 drizzle push 直接把 schema 同步到 DB。
 * 这会创建缺失的表、索引，但对已存在的表是 no-op（除非 schema 有 diff）。
 */
function pushSchema(sqlite: Database.Database) {
  // 不依赖 drizzle push API（better-sqlite3 适配器无暴露）。
  // 仅做完整性检查：比对 schema 声明的真实表名与 DB 现有表，报告缺失。
  // dev 态建表/改表用 `pnpm db:push:sqlite`。
  const nameSym = Symbol.for('drizzle:Name')
  for (const table of Object.values(schema)) {
    // drizzle 表对象的真实 DB 表名通过 [Symbol.for('drizzle:Name')] 取
    if (table === null || typeof table !== 'object' || !(nameSym in table)) continue
    const tableName = (table as Record<symbol, unknown>)[nameSym]
    if (typeof tableName !== 'string') continue
    const exists =
      sqlite
        .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?")
        .get(tableName) !== undefined
    if (!exists) {
      console.log(`[migrate] WARN: table "${tableName}" missing; run \`pnpm db:push:sqlite\` to create`)
    }
  }
}

/**
 * 旧库 baseline 标记：创建 __drizzle_migrations 表并插入 0000 标记。
 * 不执行任何 DDL——旧库已经具备所有表。
 */
function seedBaselineMarker(sqlite: Database.Database) {
  sqlite.exec(`
    CREATE TABLE IF NOT EXISTS __drizzle_migrations (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      hash TEXT NOT NULL,
      created_at NUMERIC
    )
  `)

  // 检查是否已有 baseline 标记
  const existingRaw = sqlite
    .prepare('SELECT id FROM __drizzle_migrations WHERE hash = ?')
    .get('baseline_from_legacy')
  const hasMarker =
    existingRaw !== undefined &&
    existingRaw !== null &&
    typeof existingRaw === 'object' &&
    'id' in existingRaw

  if (hasMarker) {

    console.log('[migrate] baseline marker already present, skipping')
    return
  }

  sqlite.prepare(
    'INSERT INTO __drizzle_migrations (hash, created_at) VALUES (?, ?)',
  ).run('baseline_from_legacy', Date.now())
  console.log('[migrate] baseline marker inserted')
}

main()
