import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest';
import { sendEmail, SendEmailData, SendEmailParam } from './sendEmail';
import { Client } from '@vulog/aima-client';

describe('sendEmail', () => {
    const postMock = vi.fn();
    const client = {
        post: postMock,
        clientOptions: {
            fleetId: 'FLEET_ID',
        },
    } as unknown as Client;

    beforeEach(() => {
        postMock.mockReset();
        vi.useFakeTimers({ now: new Date('2025-01-12T13:35:50.123Z') });
    });

    afterEach(() => {
        vi.useRealTimers();
    });

    test('call Base', async () => {
        postMock.mockResolvedValueOnce({
            data: {},
        });

        const bodyData: SendEmailData = {
            param1: 'val1',
        };
        const body: SendEmailParam = {
            bodyData,
            lang: 'en_GB',
            to: ['test@test.com'],
            type: 'test-type',
        };

        await sendEmail(client, body);
        expect(postMock).toBeCalled();
        expect(postMock).toBeCalledWith('/boapi/proxy/notifier/fleets/FLEET_ID/email/send', body);
    });

    test('call wrong email', async () => {
        const bodyData: SendEmailData = {
            param1: 'val1',
        };
        const body: SendEmailParam = {
            bodyData,
            lang: 'en_GB',
            to: ['test-test.com'],
            type: 'test-type',
        };

        const rejects = expect(() => sendEmail(client, body)).rejects;
        await rejects.toThrowError('Invalid data');
        await rejects.toSatisfy((error: any) => {
            expect(error).toHaveProperty('cause');
            expect(error.cause).toHaveLength(1);
            expect(error.cause[0]).toHaveProperty('validation');
            expect(error.cause[0]).toHaveProperty('message');
            expect(error.cause[0].validation).toBe('email');
            expect(error.cause[0].message).toBe('Invalid email');
            return true;
        });
    });

    test('call missing all param', async () => {
        const body = {} as unknown as SendEmailParam;

        const rejects = expect(() => sendEmail(client, body)).rejects;
        await rejects.toThrowError('Invalid data');
        await rejects.toSatisfy((error: any) => {
            expect(error).toHaveProperty('cause');
            expect(error.cause).toHaveLength(4);
            expect(error.cause[0]).toHaveProperty('message');
            expect(error.cause[0].message).toBe('Required');
            return true;
        });
    });

    test('call body null', async () => {
        const bodyData: SendEmailData = {
            param1: 'val1',
        };
        const body = null as unknown as SendEmailParam;

        const rejects = expect(() => sendEmail(client, body)).rejects;
        await rejects.toThrowError('Invalid data');
        await rejects.toSatisfy((error: any) => {
            expect(error).toHaveProperty('cause');
            expect(error.cause).toHaveLength(1);
            const cause = error.cause[0];
            expect(cause.code).toBe('invalid_type');
            expect(cause.expected).toBe('object');
            expect(cause.received).toBe('null');
            return true;
        });
    });
});
