import Database from 'better-sqlite3';
import fs from 'fs';
import path from 'path';

const DB_PATH =
  process.env.SDD_BOT_DB_PATH ??
  path.join(process.cwd(), '.sdd', 'bot', 'sdd-bot.db');

function ensureDir(filePath: string): void {
  const dir = path.dirname(filePath);
  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir, { recursive: true });
  }
}

function checkFilePermissions(filePath: string): void {
  try {
    const stat = fs.statSync(filePath);
    // On Windows, mode checks are limited; only warn on Unix-like systems
    const mode = stat.mode & 0o777;
    if (process.platform !== 'win32' && mode !== 0o600) {
      console.warn(
        `[db] AVISO S-03: permissão do arquivo "${filePath}" é ${mode.toString(8)}, esperado 0600. ` +
          'Considere executar: chmod 600 ' + filePath
      );
    }
  } catch {
    // Arquivo ainda não existe; permissão será verificada após criação
  }
}

function applyMigrations(db: Database.Database): void {
  let currentVersion = (
    db.pragma('user_version', { simple: true }) as number
  );

  if (currentVersion >= 2) {
    console.info(`[db] Migration já aplicada (user_version=${currentVersion}). Nenhuma ação necessária.`);
    return;
  }

  const migrations: Array<[number, string]> = [
    [1, '001_init.sql'],
    [2, '002_github_provider.sql'],
  ];

  for (const [version, file] of migrations) {
    if (currentVersion >= version) continue;

    const migrationPath = path.join(__dirname, 'migrations', file);
    const sql = fs.readFileSync(migrationPath, 'utf-8');
    const statements = sql
      .split(';')
      .map((s) => s.trim())
      .filter((s) => s.length > 0);

    for (const stmt of statements) {
      db.exec(stmt + ';');
    }
    currentVersion = db.pragma('user_version', { simple: true }) as number;
    console.info(`[db] Migration ${file} aplicada com sucesso (user_version=${currentVersion}).`);
  }
}

function openDatabase(): Database.Database {
  ensureDir(DB_PATH);

  // Verifica permissões antes de abrir (arquivo pode já existir)
  checkFilePermissions(DB_PATH);

  const db = new Database(DB_PATH);

  // Verifica permissões após criação (caso seja novo arquivo)
  checkFilePermissions(DB_PATH);

  // Garante foreign keys habilitadas para esta conexão
  db.pragma('foreign_keys = ON');

  // Aplica migrations de forma idempotente
  applyMigrations(db);

  // Valida journal_mode WAL
  const journalMode = db.pragma('journal_mode', { simple: true }) as string;
  if (journalMode !== 'wal') {
    console.warn(`[db] AVISO: journal_mode esperado "wal", obtido "${journalMode}".`);
  }

  return db;
}

// Singleton
export const db: Database.Database = openDatabase();
