import { describe, test, expect, beforeEach, afterEach, beforeAll, afterAll } from 'bun:test';
import { Database } from 'bun:sqlite';
import { initializeDatabase } from '../../../src/db';
import { GroupSyncService } from '../../../src/services/group-sync';
import { setDb, resetDb } from '../../../src/db/locator';

let memdb: Database;
const envBackup = { ...process.env };
let originalFetchMembers: any;

describe('GroupSyncService - syncMembersForActiveGroups (agregado por grupos)', () => {
  beforeAll(() => {
    memdb = new Database(':memory:');
    memdb.exec('PRAGMA foreign_keys = ON;');
    initializeDatabase(memdb);
    setDb(memdb as any);
  });

  afterAll(() => {
    resetDb();
    memdb.close();
  });

  beforeEach(() => {
    process.env = { ...envBackup, NODE_ENV: 'development' }; // evitar early return
    setDb(memdb as any);
    try { GroupSyncService.activeGroupsCache.clear(); } catch {}
    // Reset tablas
    memdb.exec('DELETE FROM group_members');
    memdb.exec('DELETE FROM users');
    memdb.exec('DELETE FROM groups');

    // Grupo activo
    memdb.prepare(`INSERT INTO groups (id, community_id, name, active) VALUES (?, ?, ?, 1)`)
      .run('g1@g.us', 'community-1', 'Grupo 1');

    // Refrescar caché de grupos activos
    GroupSyncService.refreshActiveGroupsCache();

    // Stub método de red
    originalFetchMembers = (GroupSyncService as any).fetchGroupMembersFromAPI;
  });

  afterEach(() => {
    (GroupSyncService as any).fetchGroupMembersFromAPI = originalFetchMembers;
    process.env = envBackup;
  });

  test('primera pasada añade miembros y marca activos', async () => {
    (GroupSyncService as any).fetchGroupMembersFromAPI = async (_gid: string) => ([
      { userId: '111', isAdmin: true },
      { userId: '222', isAdmin: false },
    ]);

    const res = await GroupSyncService.syncMembersForActiveGroups();
    expect(res).toEqual({ groups: 1, added: 2, updated: 0, deactivated: 0 });

    const rows = memdb.prepare(`SELECT user_id, is_admin, is_active FROM group_members ORDER BY user_id`).all() as any[];
    expect(rows).toHaveLength(2);
    expect(rows[0]).toEqual({ user_id: '111', is_admin: 1, is_active: 1 });
    expect(rows[1]).toEqual({ user_id: '222', is_admin: 0, is_active: 1 });
  });

  test('pasadas posteriores actualizan roles y desactivan ausentes', async () => {
    // Semilla inicial
    (GroupSyncService as any).fetchGroupMembersFromAPI = async (_gid: string) => ([
      { userId: '111', isAdmin: true },
      { userId: '222', isAdmin: false },
    ]);
    await GroupSyncService.syncMembersForActiveGroups();

    // Cambio: 111 pierde admin, 222 desaparece
    (GroupSyncService as any).fetchGroupMembersFromAPI = async (_gid: string) => ([
      { userId: '111', isAdmin: false },
    ]);

    const res2 = await GroupSyncService.syncMembersForActiveGroups();
    expect(res2).toEqual({ groups: 1, added: 0, updated: 1, deactivated: 1 });

    const rows = memdb.prepare(`SELECT user_id, is_admin, is_active FROM group_members ORDER BY user_id`).all() as any[];
    const m111 = rows.find(r => r.user_id === '111');
    const m222 = rows.find(r => r.user_id === '222');
    expect(m111.is_admin).toBe(0);
    expect(m111.is_active).toBe(1);
    expect(m222.is_active).toBe(0);
  });
});
