/**
 * Command logging and date‑handling tests.
 *
 * Covers tarea command logging, date parsing edge cases, XSS/SQL
 * injection resilience, and sender ID normalization.
 */
import { describe, test, expect } from 'bun:test';
import { WebhookServer } from '../../src/server';
import { SimulatedResponseQueue } from '../helpers/queue';
import { createTestRequest, getFutureDate, registerServerTestLifecycle } from '../helpers/server-test-harness';

const testDb = registerServerTestLifecycle();

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

describe('tarea command logging', () => {
	test('should log basic tarea command', async () => {
		const payload = {
			event: 'messages.upsert',
			instance: 'test-instance',
			data: {
				key: {
					remoteJid: 'group-id@g.us',
					participant: 'user123@s.whatsapp.net',
				},
				message: { conversation: 'tarea test' },
			},
		};

		await WebhookServer.handleRequest(createTestRequest(payload));
		expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
	});

	test('should log command with due date', async () => {
		const futureDate = getFutureDate(3);
		const payload = {
			event: 'messages.upsert',
			instance: 'test-instance',
			data: {
				key: {
					remoteJid: 'group-id@g.us',
					participant: 'user123@s.whatsapp.net',
				},
				message: {
					conversation: `tarea nueva Finish project @user2 ${futureDate}`,
					contextInfo: {
						mentionedJid: ['user2@s.whatsapp.net'],
					},
				},
			},
		};

		await WebhookServer.handleRequest(createTestRequest(payload));
		expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
	});
});

describe('WebhookServer — Date handling & edge cases', () => {
	test('should handle XSS/SQL injection attempts', async () => {
		const maliciousMessage = `tarea nueva <script>alert('xss')</script>'; DROP TABLE tasks; --`;
		const payload = {
			event: 'messages.upsert',
			instance: 'test-instance',
			data: {
				key: {
					remoteJid: 'group-id@g.us',
					participant: 'sender-id@s.whatsapp.net',
				},
				message: { conversation: maliciousMessage },
			},
		};
		const request = createTestRequest(payload);
		const response = await WebhookServer.handleRequest(request);
		expect(response.status).toBe(200);
		expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
	});

	test('should handle multiple dates in command (use last one as due date)', async () => {
		const futureDate1 = getFutureDate(3);
		const futureDate2 = getFutureDate(5);
		const payload = {
			event: 'messages.upsert',
			instance: 'test-instance',
			data: {
				key: {
					remoteJid: 'group-id@g.us',
					participant: 'sender-id@s.whatsapp.net',
				},
				message: { conversation: `tarea nueva Test task ${futureDate1} some text ${futureDate2}` },
			},
		};

		await WebhookServer.handleRequest(createTestRequest(payload));
		expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
	});

	test('should ignore past dates as due dates', async () => {
		const pastDate = '2020-01-01';
		const payload = {
			event: 'messages.upsert',
			instance: 'test-instance',
			data: {
				key: {
					remoteJid: 'group-id@g.us',
					participant: 'sender-id@s.whatsapp.net',
				},
				message: { conversation: `tarea nueva Old task ${pastDate}` },
			},
		};

		await WebhookServer.handleRequest(createTestRequest(payload));
		expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
	});

	test('should handle multiple past dates correctly', async () => {
		const payload = {
			event: 'messages.upsert',
			instance: 'test-instance',
			data: {
				key: {
					remoteJid: 'group-id@g.us',
					participant: 'sender-id@s.whatsapp.net',
				},
				message: { conversation: 'tarea nueva Test 2020-01-01 2020-02-01' },
			},
		};

		await WebhookServer.handleRequest(createTestRequest(payload));
		expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
	});

	test('should handle mixed valid and invalid date formats', async () => {
		const futureDate = getFutureDate(3);
		const payload = {
			event: 'messages.upsert',
			instance: 'test-instance',
			data: {
				key: {
					remoteJid: 'group-id@g.us',
					participant: 'sender-id@s.whatsapp.net',
				},
				message: { conversation: `tarea nueva Test invalid-date ${futureDate} another-bad` },
			},
		};

		await WebhookServer.handleRequest(createTestRequest(payload));
		expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
	});

	test('should normalize sender ID before processing', async () => {
		const payload = {
			event: 'messages.upsert',
			instance: 'test-instance',
			data: {
				key: {
					remoteJid: 'group-id@g.us',
					participant: 'sender-id:12@s.whatsapp.net',
				},
				message: { conversation: 'tarea nueva Test' },
			},
		};
		const request = createTestRequest(payload);
		const response = await WebhookServer.handleRequest(request);
		expect(response.status).toBe(200);
		expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);
	});

	test('should ignore messages with invalid sender ID', async () => {
		const payload = {
			event: 'messages.upsert',
			instance: 'test-instance',
			data: {
				key: {
					remoteJid: 'group-id@g.us',
					participant: 'invalid!@#$',
				},
				message: { conversation: 'tarea nueva Test' },
			},
		};
		const request = createTestRequest(payload);
		const response = await WebhookServer.handleRequest(request);
		expect(response.status).toBe(200);
		expect(SimulatedResponseQueue.get().length).toBe(0);
	});

	test('should ensure user exists and use normalized ID', async () => {
		const payload = {
			event: 'messages.upsert',
			instance: 'test-instance',
			data: {
				key: {
					remoteJid: 'group-id@g.us',
					participant: '1234567890@s.whatsapp.net',
				},
				message: { conversation: 'tarea nueva Test user' },
			},
		};
		const request = createTestRequest(payload);
		const response = await WebhookServer.handleRequest(request);
		expect(response.status).toBe(200);
		expect(SimulatedResponseQueue.get().length).toBeGreaterThan(0);

		const user = testDb.query('SELECT * FROM users WHERE id = ?').get('1234567890');
		expect(user).toBeDefined();
		expect((user as any).id).toBe('1234567890');
	});

	test('should ignore messages if user creation fails', async () => {
		const payload = {
			event: 'messages.upsert',
			instance: 'test-instance',
			data: {
				key: {
					remoteJid: 'group-id@g.us',
					participant: 'invalid!user@s.whatsapp.net',
				},
				message: { conversation: 'tarea nueva Test' },
			},
		};
		const request = createTestRequest(payload);
		const response = await WebhookServer.handleRequest(request);
		expect(response.status).toBe(200);
		expect(SimulatedResponseQueue.get().length).toBe(0);

		const userCount = testDb.query('SELECT COUNT(*) as count FROM users').get();
		expect((userCount as any).count).toBe(0);
	});
});
