import { describe, it, beforeEach, afterEach, expect } from 'bun:test';
import Database from 'bun:sqlite';
import { initializeDatabase } from '../../../src/db';
import { TaskService } from '../../../src/tasks/service';
import { RemindersService } from '../../../src/services/reminders';
import { AllowedGroups } from '../../../src/services/allowed-groups';
import { ResponseQueue } from '../../../src/services/response-queue';
import { toIsoSql } from '../../helpers/dates';
import { setDb } from '../../../src/db/locator';
import { seedGroup } from '../../helpers/db';

describe('RemindersService - gating por grupos en modo enforce', () => {
  const envBackup = process.env;
  let memdb: Database;
  let originalAdd: any;
  let sent: any[] = [];

  beforeEach(() => {
    process.env = { ...envBackup, NODE_ENV: 'test', GROUP_GATING_MODE: 'enforce', TZ: 'Europe/Madrid', REMINDERS_GRACE_MINUTES: '60' };
    memdb = new Database(':memory:');
    initializeDatabase(memdb);
    setDb(memdb);

    // Stub de ResponseQueue
    originalAdd = (ResponseQueue as any).add;
    (ResponseQueue as any).add = async (msgs: any[]) => { sent.push(...msgs); };
    sent = [];

    // Asegurar usuario receptor para satisfacer la FK de user_preferences
    const iso = toIsoSql(new Date());
    memdb.exec(`
      INSERT INTO users (id, first_seen, last_seen)
      VALUES ('34600123456', '${iso}', '${iso}')
      ON CONFLICT(id) DO NOTHING
    `);

    // Preferencias del usuario receptor
    memdb.exec(`
      INSERT INTO user_preferences (user_id, reminder_freq, reminder_time, last_reminded_on, updated_at)
      VALUES ('34600123456', 'daily', '09:00', NULL, strftime('%Y-%m-%d %H:%M:%f','now'))
      ON CONFLICT(user_id) DO UPDATE SET
        reminder_freq = excluded.reminder_freq,
        reminder_time = excluded.reminder_time,
        last_reminded_on = NULL,
        updated_at = excluded.updated_at
    `);

    // Sembrar grupos y estados
    seedGroup(memdb, 'ok@g.us');
    seedGroup(memdb, 'na@g.us');
    AllowedGroups.setStatus('ok@g.us', 'allowed', 'OK');
    AllowedGroups.setStatus('na@g.us', 'allowed', 'NA'); // inicialmente allowed para que las tareas se creen con group_id

    // Crear dos tareas, una en cada grupo, asignadas al usuario
    TaskService.createTask(
      { description: 'Tarea OK', created_by: '34600123456', group_id: 'ok@g.us', due_date: null },
      [{ user_id: '34600123456', assigned_by: '34600123456' }]
    );
    TaskService.createTask(
      { description: 'Tarea NA', created_by: '34600123456', group_id: 'na@g.us', due_date: null },
      [{ user_id: '34600123456', assigned_by: '34600123456' }]
    );

    // Cambiar a bloqueado uno de los grupos antes de correr los recordatorios
    AllowedGroups.setStatus('na@g.us', 'blocked', 'NA');
  });

  afterEach(() => {
    (ResponseQueue as any).add = originalAdd;
    memdb.close();
    process.env = envBackup;
  });

  it('omite tareas de grupos no allowed en los recordatorios', async () => {
    const now = new Date('2025-09-08T07:40:00.000Z'); // ≥ 09:00 Europe/Madrid en un lunes y dentro de la ventana
    await RemindersService.runOnce(now);

    expect(sent.length).toBe(1);
    const msg = String(sent[0].message);

    // Debe incluir solo la tarea del grupo allowed y omitir la del bloqueado
    expect(msg).toContain('Tarea OK');
    expect(msg).not.toContain('Tarea NA');
  });
});
