import fs from "node:fs";
import { DatabaseSync } from "node:sqlite";
import bcrypt from "bcryptjs";
import { config } from "./config.js";

fs.mkdirSync(config.dataDir, { recursive: true });
fs.mkdirSync(config.storageDir, { recursive: true });

export const db = new DatabaseSync(config.databasePath);
db.exec("PRAGMA journal_mode = WAL");
db.exec("PRAGMA foreign_keys = ON");

export function migrate() {
  db.exec(`
    CREATE TABLE IF NOT EXISTS users (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      username TEXT NOT NULL UNIQUE,
      password_hash TEXT NOT NULL,
      role TEXT NOT NULL DEFAULT 'user',
      enabled INTEGER NOT NULL DEFAULT 1,
      expires_at TEXT,
      created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
    );

    CREATE TABLE IF NOT EXISTS folders (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      parent_id INTEGER REFERENCES folders(id) ON DELETE CASCADE,
      name TEXT NOT NULL,
      path TEXT NOT NULL UNIQUE,
      library_type TEXT NOT NULL DEFAULT 'system',
      owner_user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
      is_system INTEGER NOT NULL DEFAULT 0,
      created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
      UNIQUE(parent_id, name)
    );

    CREATE TABLE IF NOT EXISTS brands (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT NOT NULL UNIQUE,
      created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
    );

    CREATE TABLE IF NOT EXISTS model_types (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT NOT NULL UNIQUE,
      created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
    );

    CREATE TABLE IF NOT EXISTS models (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      folder_id INTEGER NOT NULL REFERENCES folders(id) ON DELETE CASCADE,
      brand_id INTEGER REFERENCES brands(id) ON DELETE SET NULL,
      type_id INTEGER REFERENCES model_types(id) ON DELETE SET NULL,
      name TEXT NOT NULL,
      original_filename TEXT NOT NULL,
      file_path TEXT NOT NULL UNIQUE,
      library_type TEXT NOT NULL DEFAULT 'system',
      owner_user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
      storage_provider TEXT NOT NULL DEFAULT 'local',
      file_size INTEGER NOT NULL,
      thumbnail_path TEXT,
      thumbnail_provider TEXT,
      operation_tree TEXT NOT NULL DEFAULT '{"OperationTree":"[]"}',
      created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
      updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
      UNIQUE(folder_id, name)
    );

    CREATE TABLE IF NOT EXISTS model_properties (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      model_id INTEGER NOT NULL REFERENCES models(id) ON DELETE CASCADE,
      property_key TEXT NOT NULL,
      property_value TEXT NOT NULL DEFAULT '',
      UNIQUE(model_id, property_key)
    );

    CREATE INDEX IF NOT EXISTS idx_folders_parent_id ON folders(parent_id);
    CREATE INDEX IF NOT EXISTS idx_models_folder_id ON models(folder_id);
    CREATE INDEX IF NOT EXISTS idx_model_properties_model_id ON model_properties(model_id);
  `);

  db.exec(`
    CREATE INDEX IF NOT EXISTS idx_models_brand_id ON models(brand_id);
    CREATE INDEX IF NOT EXISTS idx_models_type_id ON models(type_id);
    CREATE INDEX IF NOT EXISTS idx_folders_library_owner ON folders(library_type, owner_user_id);
    CREATE INDEX IF NOT EXISTS idx_models_library_owner ON models(library_type, owner_user_id);
  `);

  const admin = db.prepare("SELECT id FROM users WHERE username = ?").get("admin");
  if (!admin) {
    db.prepare(`
      INSERT INTO users (username, password_hash, role, enabled)
      VALUES (?, ?, 'admin', 1)
    `).run("admin", bcrypt.hashSync("admin123", 10));
  }

  const systemRoot = db.prepare("SELECT id FROM folders WHERE path = ?").get("system") as { id: number } | undefined;
  if (!systemRoot) {
    db.prepare(`
      INSERT INTO folders (parent_id, name, path, library_type, owner_user_id, is_system)
      VALUES (NULL, ?, ?, 'system', NULL, 1)
    `).run("系统模型库", "system");
  }
}
