import { describe, test, vi, expect } from 'vitest';

import { addCredits } from './addCredits';
import { Client } from '@vulog/aima-client';

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

    const addCreditsSpy = vi.fn().mockImplementation(addCredits);

    test('Call OK with valid payload', async () => {
        const payload = {
            initialAmount: 100,
            validityStartDate: '2023-01-01T00:00:00Z',
            validityEndDate: '2024-01-01T00:00:00Z',
            notes: 'Test credit',
            discountCategory: 'CREDITS',
            oneTimeUsage: true,
            entityId: 'de66ea16-e942-4eaa-9f86-491e62bf59a2',
            type: 'LOCAL',
            usage: 'TRIP',
        };

        const creditResponse = {
            id: 'credit1',
            availableAmount: 100,
            usedAmount: 0,
            originId: null,
            creditAlreadyUsed: false,
            updateDate: new Date().toISOString(),
            ...payload,
        };

        postMock.mockResolvedValue({ data: creditResponse });

        await addCreditsSpy(client, payload);
        expect(addCreditsSpy).toHaveBeenCalledWith(client, payload);
        expect(addCreditsSpy).toHaveBeenCalledTimes(1);
        expect(postMock).toHaveBeenCalledTimes(1);
    });

    test('Should throw TypeError when entityId is not a valid UUID', async () => {
        const invalidPayload = {
            initialAmount: 100,
            validityStartDate: '2023-01-01T00:00:00Z',
            validityEndDate: '2024-01-01T00:00:00Z',
            notes: 'Test credit',
            discountCategory: 'CREDITS',
            oneTimeUsage: true,
            entityId: 'invalid-uuid',
            type: 'LOCAL',
            usage: 'TRIP',
        };

        await expect(addCreditsSpy(client, invalidPayload)).rejects.toThrow(TypeError);
        await expect(addCreditsSpy(client, invalidPayload)).rejects.toThrow('Invalid args');
    });

    test('Should throw TypeError when initialAmount is negative', async () => {
        const invalidPayload = {
            initialAmount: -10,
            validityStartDate: '2023-01-01T00:00:00Z',
            validityEndDate: '2024-01-01T00:00:00Z',
            notes: 'Test credit',
            discountCategory: 'CREDITS',
            oneTimeUsage: true,
            entityId: 'de66ea16-e942-4eaa-9f86-491e62bf59a2',
            type: 'LOCAL',
            usage: 'TRIP',
        };

        await expect(addCreditsSpy(client, invalidPayload)).rejects.toThrow(TypeError);
    });

    test('Should throw TypeError when dates are invalid', async () => {
        const invalidPayload = {
            initialAmount: 100,
            validityStartDate: 'not-a-date',
            validityEndDate: '2024-01-01T00:00:00Z',
            notes: 'Test credit',
            discountCategory: 'CREDITS',
            oneTimeUsage: true,
            entityId: 'de66ea16-e942-4eaa-9f86-491e62bf59a2',
            type: 'LOCAL',
            usage: 'TRIP',
        };

        await expect(addCreditsSpy(client, invalidPayload)).rejects.toThrow(TypeError);
    });

    test('Should throw TypeError when enum value is invalid', async () => {
        const invalidPayload = {
            initialAmount: 100,
            validityStartDate: '2023-01-01T00:00:00Z',
            validityEndDate: '2024-01-01T00:00:00Z',
            notes: 'Test credit',
            discountCategory: 'INVALID_CATEGORY',
            oneTimeUsage: true,
            entityId: 'de66ea16-e942-4eaa-9f86-491e62bf59a2',
            type: 'LOCAL',
            usage: 'TRIP',
        };

        await expect(addCreditsSpy(client, invalidPayload as any)).rejects.toThrow(TypeError);
    });
});
