/**
 * Apertura y migración de la BD local. Singleton: una sola conexión por proceso.
 */
import * as SQLite from 'expo-sqlite';
import { DB_NAME } from '../config';
import { SCHEMA_SQL, SCHEMA_VERSION } from './schema';

let dbPromise: Promise<SQLite.SQLiteDatabase> | null = null;

export function getDb(): Promise<SQLite.SQLiteDatabase> {
  if (!dbPromise) {
    dbPromise = openAndMigrate();
  }
  return dbPromise;
}

async function openAndMigrate(): Promise<SQLite.SQLiteDatabase> {
  const db = await SQLite.openDatabaseAsync(DB_NAME);
  await db.execAsync(SCHEMA_SQL);

  // Versionado por PRAGMA user_version. Migraciones incrementales.
  const row = await db.getFirstAsync<{ user_version: number }>('PRAGMA user_version');
  const current = row?.user_version ?? 0;

  if (current < 2) {
    // local_id: id temporal de la fila creada offline que produjo esta operación
    // (para reconciliar el id del servidor tras el PUSH).
    await db.execAsync('ALTER TABLE outbox ADD COLUMN local_id INTEGER');
  }

  if (current < SCHEMA_VERSION) {
    await db.execAsync(`PRAGMA user_version = ${SCHEMA_VERSION}`);
  }
  return db;
}

/** Borra todos los datos locales (logout / cambio de usuario). */
export async function wipeDatabase(): Promise<void> {
  const db = await getDb();
  const tables = [
    'meta',
    'projects',
    'phases',
    'layers',
    'features',
    'inspections',
    'issues',
    'issue_tasks',
    'issue_comments',
    'templates',
    'media',
    'outbox',
    'media_outbox',
  ];
  await db.withTransactionAsync(async () => {
    for (const t of tables) {
      await db.execAsync(`DELETE FROM ${t}`);
    }
  });
}
