/**
 * Integration Tests für Telegram Upload-Benachrichtigungen
 * 
 * Phase 3: Upload-Benachrichtigungen
 * 
 * Diese Tests prüfen die Integration zwischen Upload-Route und Telegram-Service
 */

const path = require('path');
const fs = require('fs');
const { getRequest } = require('../testServer');

describe('Telegram Upload Notifications (Integration)', () => {
    let TelegramNotificationService;
    let sendUploadNotificationSpy;

    beforeAll(() => {
        // Spy auf TelegramNotificationService
        TelegramNotificationService = require('../../src/services/TelegramNotificationService');
    });

    beforeEach(() => {
        // Spy auf sendUploadNotification erstellen
        sendUploadNotificationSpy = jest.spyOn(TelegramNotificationService.prototype, 'sendUploadNotification')
            .mockResolvedValue({ message_id: 42 });
        
        // isAvailable() immer true zurückgeben für Tests
        jest.spyOn(TelegramNotificationService.prototype, 'isAvailable')
            .mockReturnValue(true);
    });

    afterEach(() => {
        // Restore alle Spys
        jest.restoreAllMocks();
    });

    describe('POST /api/upload/batch', () => {
        const testImagePath = path.join(__dirname, '../utils/test-image.jpg');

        // Erstelle Test-Bild falls nicht vorhanden
        beforeAll(() => {
            if (!fs.existsSync(testImagePath)) {
                // Erstelle 1x1 px JPEG
                const buffer = Buffer.from([
                    0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46,
                    0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01,
                    0x00, 0x01, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43,
                    0x00, 0x08, 0x06, 0x06, 0x07, 0x06, 0x05, 0x08,
                    0x07, 0x07, 0x07, 0x09, 0x09, 0x08, 0x0A, 0x0C,
                    0x14, 0x0D, 0x0C, 0x0B, 0x0B, 0x0C, 0x19, 0x12,
                    0x13, 0x0F, 0x14, 0x1D, 0x1A, 0x1F, 0x1E, 0x1D,
                    0x1A, 0x1C, 0x1C, 0x20, 0x24, 0x2E, 0x27, 0x20,
                    0x22, 0x2C, 0x23, 0x1C, 0x1C, 0x28, 0x37, 0x29,
                    0x2C, 0x30, 0x31, 0x34, 0x34, 0x34, 0x1F, 0x27,
                    0x39, 0x3D, 0x38, 0x32, 0x3C, 0x2E, 0x33, 0x34,
                    0x32, 0xFF, 0xC0, 0x00, 0x0B, 0x08, 0x00, 0x01,
                    0x00, 0x01, 0x01, 0x01, 0x11, 0x00, 0xFF, 0xC4,
                    0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x03, 0xFF, 0xC4, 0x00, 0x14,
                    0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0xFF, 0xDA, 0x00, 0x08, 0x01, 0x01,
                    0x00, 0x00, 0x3F, 0x00, 0x37, 0xFF, 0xD9
                ]);
                fs.writeFileSync(testImagePath, buffer);
            }
        });

        it('sollte Telegram-Benachrichtigung bei erfolgreichem Upload senden', async () => {
            const response = await getRequest()
                .post('/api/upload/batch')
                .field('year', '2024')
                .field('title', 'Test Upload')
                .field('name', 'Test User')
                .field('consents', JSON.stringify({
                    workshopConsent: true,
                    socialMediaConsents: ['instagram', 'tiktok']
                }))
                .attach('images', testImagePath);

            // Upload sollte erfolgreich sein
            expect(response.status).toBe(200);
            expect(response.body.message).toBe('Batch upload successful');

            // Warte kurz auf async Telegram-Call
            await new Promise(resolve => setTimeout(resolve, 150));

            // Telegram-Service sollte aufgerufen worden sein
            expect(sendUploadNotificationSpy).toHaveBeenCalledWith(
                expect.objectContaining({
                    name: 'Test User',
                    year: 2024,
                    title: 'Test Upload',
                    imageCount: 1,
                    workshopConsent: true,
                    socialMediaConsents: ['instagram', 'tiktok']
                })
            );
        });

        it('sollte Upload nicht fehlschlagen wenn Telegram-Service nicht verfügbar', async () => {
            // Restore mock und setze isAvailable auf false
            jest.restoreAllMocks();
            jest.spyOn(TelegramNotificationService.prototype, 'isAvailable')
                .mockReturnValue(false);
            sendUploadNotificationSpy = jest.spyOn(TelegramNotificationService.prototype, 'sendUploadNotification');

            const response = await getRequest()
                .post('/api/upload/batch')
                .field('year', '2024')
                .field('title', 'Test Upload')
                .field('name', 'Test User')
                .field('consents', JSON.stringify({
                    workshopConsent: false,
                    socialMediaConsents: []
                }))
                .attach('images', testImagePath);

            // Upload sollte trotzdem erfolgreich sein
            expect(response.status).toBe(200);
            expect(response.body.message).toBe('Batch upload successful');

            // Telegram sollte nicht aufgerufen worden sein
            expect(sendUploadNotificationSpy).not.toHaveBeenCalled();
        });

        it('sollte Upload nicht fehlschlagen wenn Telegram-Benachrichtigung fehlschlägt', async () => {
            sendUploadNotificationSpy.mockRejectedValueOnce(
                new Error('Telegram API Error')
            );

            const response = await getRequest()
                .post('/api/upload/batch')
                .field('year', '2024')
                .field('title', 'Test Upload')
                .field('name', 'Test User')
                .field('consents', JSON.stringify({
                    workshopConsent: true,
                    socialMediaConsents: []
                }))
                .attach('images', testImagePath);

            // Upload sollte trotzdem erfolgreich sein
            expect(response.status).toBe(200);
            expect(response.body.message).toBe('Batch upload successful');

            // Warte auf async error handling
            await new Promise(resolve => setTimeout(resolve, 150));

            // Telegram wurde versucht aufzurufen
            expect(sendUploadNotificationSpy).toHaveBeenCalled();
        });

        it('sollte korrekte Daten an Telegram-Service übergeben', async () => {
            const response = await getRequest()
                .post('/api/upload/batch')
                .field('year', '2025')
                .field('title', 'Schweißkurs November')
                .field('name', 'Max Mustermann')
                .field('consents', JSON.stringify({
                    workshopConsent: true,
                    socialMediaConsents: ['facebook', 'instagram']
                }))
                .attach('images', testImagePath)
                .attach('images', testImagePath);

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

            await new Promise(resolve => setTimeout(resolve, 150));

            expect(sendUploadNotificationSpy).toHaveBeenCalledWith({
                name: 'Max Mustermann',
                year: 2025,
                title: 'Schweißkurs November',
                imageCount: 2,
                workshopConsent: true,
                socialMediaConsents: ['facebook', 'instagram'],
                token: expect.any(String)
            });
        });
    });
});
