/**
 * Regression tests: DM (direct message) gating.
 *
 * Ensures that user DMs are NEVER treated as groups for gating purposes.
 * A user JID (e.g. 1234567890@s.whatsapp.net) must not trigger group
 * discovery (notify admins of a "new group") or group enforcement
 * (silently block the message).
 */
import { describe, test, expect } from 'bun:test';
import { WebhookServer } from '../../src/server';
import { SimulatedResponseQueue } from '../helpers/queue';
import { createTestRequest, registerServerTestLifecycle } from '../helpers/server-test-harness';

const testDb = registerServerTestLifecycle();

// ── Helpers ────────────────────────────────────────────────────────────

function makeDmPayload(text: string) {
  return {
    event: 'messages.upsert',
    instance: 'test-instance',
    data: {
      key: {
        remoteJid: '1234567890@s.whatsapp.net', // user JID, NOT a group
        fromMe: false,
      },
      message: { conversation: text },
    },
  };
}

function countAllowedGroups(): number {
  try {
    const row = testDb.prepare('SELECT COUNT(*) AS c FROM allowed_groups').get() as { c: number };
    return row.c;
  } catch {
    return 0;
  }
}

// ── Tests ──────────────────────────────────────────────────────────────

describe('DM gating — user DMs must not be treated as groups', () => {

  test('discover mode: DM does NOT register user JID in allowed_groups', async () => {
    process.env.GROUP_GATING_MODE = 'discover';

    const request = createTestRequest(makeDmPayload('t ver mis'));
    const response = await WebhookServer.handleRequest(request);

    expect(response.status).toBe(200);

    // No allowed_groups entry should exist for the user JID
    const count = countAllowedGroups();
    expect(count).toBe(0);

    // Admin should NOT be notified about a "new group"
    const out = SimulatedResponseQueue.get();
    const adminNotices = out.filter(r => r.message && (r.message as string).includes('Nuevo grupo detectado'));
    expect(adminNotices.length).toBe(0);
  });

  test('enforce mode: DM is NOT blocked (user can still use commands)', async () => {
    process.env.GROUP_GATING_MODE = 'enforce';

    const request = createTestRequest(makeDmPayload('t ver mis'));
    const response = await WebhookServer.handleRequest(request);

    expect(response.status).toBe(200);

    // Command should have processed and produced a response
    const out = SimulatedResponseQueue.get();
    // "ver mis" in DM should produce at least one response
    expect(out.length).toBeGreaterThan(0);
  });

  test('discover mode: unknown GROUP still gets discovered (regression check)', async () => {
    process.env.GROUP_GATING_MODE = 'discover';
    process.env.NOTIFY_ADMINS_ON_DISCOVERY = 'false'; // don't spam admins in test

    // Ensure the group is NOT already in allowed_groups or active groups
    testDb.exec('DELETE FROM allowed_groups WHERE group_id = \'unknown-group@g.us\'');
    testDb.exec('DELETE FROM groups WHERE id = \'unknown-group@g.us\'');

    const payload = {
      event: 'messages.upsert',
      instance: 'test-instance',
      data: {
        key: {
          remoteJid: 'unknown-group@g.us', // group JID
          participant: '1234567890@s.whatsapp.net',
        },
        message: { conversation: 'hola' },
      },
    };

    const request = createTestRequest(payload);
    await WebhookServer.handleRequest(request);

    // Should have registered the group as pending
    const row = testDb.prepare('SELECT * FROM allowed_groups WHERE group_id = ?').get('unknown-group@g.us') as any;
    expect(row).toBeDefined();
    expect(row.status).toBe('pending');
  });

  test('enforce mode: non-allowed GROUP is still blocked (regression check)', async () => {
    process.env.GROUP_GATING_MODE = 'enforce';

    // Ensure the group is NOT allowed
    testDb.exec('DELETE FROM allowed_groups WHERE group_id = \'blocked-group@g.us\'');
    testDb.exec('DELETE FROM groups WHERE id = \'blocked-group@g.us\'');
    // Add it as active so it passes ensureGroupActive
    testDb.exec(`
      INSERT OR IGNORE INTO groups (id, community_id, name, active)
      VALUES ('blocked-group@g.us', 'test-community', 'Blocked Group', 1)
    `);

    const payload = {
      event: 'messages.upsert',
      instance: 'test-instance',
      data: {
        key: {
          remoteJid: 'blocked-group@g.us',
          participant: '1234567890@s.whatsapp.net',
        },
        message: { conversation: 't ver mis' },
      },
    };

    const request = createTestRequest(payload);
    await WebhookServer.handleRequest(request);

    // Message should be silently blocked (no response)
    const out = SimulatedResponseQueue.get();
    expect(out.length).toBe(0);
  });

  test('enforce mode: allowed GROUP can still use commands (regression check)', async () => {
    process.env.GROUP_GATING_MODE = 'enforce';

    testDb.exec(`
      INSERT OR REPLACE INTO allowed_groups (group_id, label, status)
      VALUES ('group-id@g.us', 'Test Group', 'allowed')
    `);

    const payload = {
      event: 'messages.upsert',
      instance: 'test-instance',
      data: {
        key: {
          remoteJid: 'group-id@g.us',
          participant: '1234567890@s.whatsapp.net',
        },
        message: { conversation: 't n Test tarea mañana' },
      },
    };

    const request = createTestRequest(payload);
    await WebhookServer.handleRequest(request);

    const out = SimulatedResponseQueue.get();
    expect(out.length).toBeGreaterThan(0);
  });

});
