import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
import { GroupSyncService } from '../../../src/services/group-sync';

const ORIGINAL_FETCH = globalThis.fetch;

describe('GroupSyncService - fetchGroupMembersFromAPI (parsing y fallbacks)', () => {
  const envBackup = { ...process.env };

  beforeEach(() => {
    process.env = {
      ...envBackup,
      NODE_ENV: 'development', // evitar early-return de test
      EVOLUTION_API_URL: 'http://evolution.test',
      EVOLUTION_API_INSTANCE: 'instance-1',
      EVOLUTION_API_KEY: 'apikey'
    };
    try { GroupSyncService.activeGroupsCache.clear(); } catch {}
  });

  afterEach(() => {
    process.env = envBackup;
    globalThis.fetch = ORIGINAL_FETCH;
  });

  test('parsea /group/participants con múltiples formas de payload y roles', async () => {
    globalThis.fetch = async (url: RequestInfo | URL) => {
      if (String(url).includes('/group/participants/')) {
        const body = {
          participants: [
            { id: '553198296801@s.whatsapp.net', admin: 'superadmin' },
            { id: '1234567890@s.whatsapp.net', admin: 'admin' },
            { id: '1111111111@s.whatsapp.net', admin: null },
            '2222222222@s.whatsapp.net',
            { jid: '3333333333@s.whatsapp.net', role: 'member' },
            { user: { id: '4444444444@s.whatsapp.net' }, isAdmin: true }
          ]
        };
        return new Response(JSON.stringify(body), { status: 200, headers: { 'Content-Type': 'application/json' } });
      }
      return new Response('not found', { status: 404 });
    };

    const out = await (GroupSyncService as any).fetchGroupMembersFromAPI('123@g.us');
    // Debe mapear a IDs normalizados (solo dígitos) y detectar admin correctamente
    const ids = out.map((x: any) => x.userId).sort();
    expect(ids).toEqual(['1111111111','1234567890','2222222222','3333333333','4444444444','553198296801'].sort());

    const adminMap = new Map(out.map((x: any) => [x.userId, x.isAdmin]));
    expect(adminMap.get('553198296801')).toBe(true);
    expect(adminMap.get('1234567890')).toBe(true);
    expect(adminMap.get('1111111111')).toBe(false);
    expect(adminMap.get('2222222222')).toBe(false);
    expect(adminMap.get('3333333333')).toBe(false);
    expect(adminMap.get('4444444444')).toBe(true);
  });

  test('fallback a fetchAllGroups cuando /group/participants no trae participants', async () => {
    globalThis.fetch = async (url: RequestInfo | URL) => {
      const u = String(url);
      if (u.includes('/group/participants/')) {
        // OK pero sin campo participants
        return new Response(JSON.stringify({ ok: true }), { status: 200 });
      }
      if (u.includes('/group/fetchAllGroups/')) {
        const wrapped = {
          response: [
            { id: '123@g.us', participants: [{ id: '9999999999@s.whatsapp.net', admin: 'admin' }] }
          ]
        };
        return new Response(JSON.stringify(wrapped), { status: 200, headers: { 'Content-Type': 'application/json' } });
      }
      return new Response('not found', { status: 404 });
    };

    const out = await (GroupSyncService as any).fetchGroupMembersFromAPI('123@g.us');
    expect(out).toEqual([{ userId: '9999999999', isAdmin: true }]);
  });

  test('fallback devuelve snapshot vacío si el grupo no está presente', async () => {
    globalThis.fetch = async (url: RequestInfo | URL) => {
      const u = String(url);
      if (u.includes('/group/participants/')) {
        return new Response(JSON.stringify({ ok: true }), { status: 200 });
      }
      if (u.includes('/group/fetchAllGroups/')) {
        const wrapped = {
          response: [
            { id: 'other@g.us', participants: [{ id: '9999999999@s.whatsapp.net', admin: 'admin' }] }
          ]
        };
        return new Response(JSON.stringify(wrapped), { status: 200 });
      }
      return new Response('not found', { status: 404 });
    };

    const out = await (GroupSyncService as any).fetchGroupMembersFromAPI('123@g.us');
    expect(out).toEqual([]);
  });
});
