import Database, { type Database as SqliteDatabase } from 'bun:sqlite';
import { initializeDatabase } from '../../src/db';
import { setDb } from '../../src/db/locator';

// Servicios opcionales para inyección de DB en tests.
// Importamos con nombres existentes en la base de código para respetar convenciones.
import { TaskService } from '../../src/tasks/service';
import { CommandService } from '../../src/services/command';
import { ResponseQueue } from '../../src/services/response-queue';
import { IdentityService } from '../../src/services/identity';
import { GroupSyncService } from '../../src/services/group-sync';
import { RemindersService } from '../../src/services/reminders';
import { AllowedGroups } from '../../src/services/allowed-groups';

/**
 * Crea una DB en memoria y aplica initializeDatabase() con todas las migraciones.
 */
export function makeMemDb(): SqliteDatabase {
  const memdb = new Database(':memory:');
  initializeDatabase(memdb);
  return memdb;
}

/**
 * Inyecta la instancia de DB en los servicios que la exponen como propiedad estática.
 * Pensado para usarse en beforeAll/beforeEach de tests que usan estos servicios.
 */
export function injectAllServices(db: SqliteDatabase): void {
  setDb(db);
}

/**
 * Restablece estado global/cachés en servicios entre tests.
 * Best-effort: solo llama si existen los métodos.
 */
export function resetServices(): void {
  try { (IdentityService as any).clearCache?.(); } catch {}
  try { (GroupSyncService as any).clearCaches?.(); } catch {}
  try { (CommandService as any).resetForTests?.(); } catch {}
  try { (ResponseQueue as any).resetForTests?.(); } catch {}
  try { (RemindersService as any).resetForTests?.(); } catch {}
}

/**
 * Marca como 'allowed' los groupIds indicados en la DB provista.
 */
export function seedAllowed(db: SqliteDatabase, groupIds: string[]): void {
  for (const gid of groupIds) {
    const g = String(gid || '').trim();
    if (!g) continue;
    try { AllowedGroups.setStatus(g, 'allowed'); } catch {}
  }
}
