import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
import { WebhookServer } from '../../../src/server';
import { GroupSyncService } from '../../../src/services/group-sync';
import { makeMemDb, injectAllServices, resetServices } from '../../helpers/db';
import type { Database as SqliteDatabase } from 'bun:sqlite';

describe('WebhookServer - groups.upsert encadena syncGroups y syncMembersForActiveGroups', () => {
  const envBackup = { ...process.env };
  let db: SqliteDatabase;

  let originalSyncGroups: any;
  let originalRefresh: any;
  let originalSyncMembers: any;

  let calledSyncGroups = 0;
  let calledRefresh = 0;
  let calledSyncMembers = 0;

  beforeEach(() => {
    process.env = {
      ...envBackup,
      NODE_ENV: 'production',
      EVOLUTION_API_INSTANCE: 'inst-1',
      EVOLUTION_API_URL: 'http://localhost:1234',
      EVOLUTION_API_KEY: 'dummy',
      CHATBOT_PHONE_NUMBER: '123456789',
      WEBHOOK_URL: 'http://localhost:3000/webhook'
    };

    db = makeMemDb();
    // Inyectar DB en servicios
    (WebhookServer as any).dbInstance = db;
    injectAllServices(db);

    // Guardar originales y stubear
    originalSyncGroups = GroupSyncService.syncGroups;
    originalRefresh = GroupSyncService.refreshActiveGroupsCache;
    originalSyncMembers = GroupSyncService.syncMembersForActiveGroups;

    calledSyncGroups = 0;
    calledRefresh = 0;
    calledSyncMembers = 0;

    GroupSyncService.syncGroups = async () => {
      calledSyncGroups++;
      return { added: 0, updated: 0 };
    };
    GroupSyncService.refreshActiveGroupsCache = () => {
      calledRefresh++;
    };
    GroupSyncService.syncMembersForActiveGroups = async () => {
      calledSyncMembers++;
      return { groups: 0, added: 0, updated: 0, deactivated: 0 };
    };
  });

  afterEach(async () => {
    // Restaurar stubs
    GroupSyncService.syncGroups = originalSyncGroups;
    GroupSyncService.refreshActiveGroupsCache = originalRefresh;
    GroupSyncService.syncMembersForActiveGroups = originalSyncMembers;

    resetServices();
    try { db.close(); } catch {}
    process.env = envBackup;
  });

  test('dispara syncGroups -> refreshActiveGroupsCache -> syncMembersForActiveGroups y responde 200', async () => {
    const payload = {
      event: 'groups.upsert',
      instance: 'inst-1',
      data: { any: 'thing' }
    };

    const req = new Request('http://localhost/webhook', {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify(payload)
    });

    const res = await WebhookServer.handleRequest(req);
    expect(res.status).toBe(200);
    expect(calledSyncGroups).toBe(1);
    expect(calledRefresh).toBe(1);
    expect(calledSyncMembers).toBe(1);
  });
});
