import { describe, test, expect, vi, beforeEach } from 'vitest';
import { Client } from '@vulog/aima-client';
import { getInvoicesByTripId } from './getInvoicesByTripId';
import type { InvoicesByTripIdResponse } from './types';

describe('getInvoicesByTripId', () => {
    const getMock = vi.fn();
    const client = {
        get: getMock,
        clientOptions: {
            fleetId: 'FLEET_ID',
        },
    } as unknown as Client;

    beforeEach(() => {
        getMock.mockReset();
    });

    test('throws Invalid args when tripId is empty', async () => {
        await expect(getInvoicesByTripId(client, '')).rejects.toThrow(TypeError);
        await expect(getInvoicesByTripId(client, '')).rejects.toMatchObject({
            message: 'Invalid args',
        });
        expect(getMock).not.toHaveBeenCalled();
    });

    test('throws Invalid args when tripId is whitespace only', async () => {
        await expect(getInvoicesByTripId(client, '   ')).rejects.toThrow(TypeError);
        expect(getMock).not.toHaveBeenCalled();
    });

    test('calls GET with correct URL and returns trip billing response', async () => {
        const tripId = 'BEBD00056A9A16103D418CC36D940E26';
        const response: InvoicesByTripIdResponse = {
            balance: 499.99,
            userId: '20fb98a3-b60d-491a-9359-62e55f51fcb9',
            entityId: 'ba0b4e0b-ff0a-49f5-8e98-065b54355df9',
            Billing: [
                {
                    vehiculeModelName: 'Yaris_Subs',
                    vehiculePlate: 'Yaris_Abo_001',
                    modelId: '1754',
                    userId: '20fb98a3-b60d-491a-9359-62e55f51fcb9',
                    withTaxInitialTotalAmount: 499.99,
                    totalWithTax: 499.99,
                    pricingId: '96e1fff7-d422-4181-8e19-1b2759b2f073',
                    distanceUnit: 'KM',
                    isTaxIncluded: true,
                },
            ],
        };
        getMock.mockResolvedValueOnce({ data: response });

        const result = await getInvoicesByTripId(client, tripId);

        expect(getMock).toHaveBeenCalledTimes(1);
        expect(getMock).toHaveBeenCalledWith(
            `/boapi/proxy/billing/fleets/FLEET_ID/trips/${tripId}/invoices`
        );
        expect(result).toEqual(response);
        expect(result.balance).toBe(499.99);
        expect(result.Billing).toHaveLength(1);
        expect(result.Billing[0].vehiculeModelName).toBe('Yaris_Subs');
    });

    test('returns response with empty Billing array when no billing items', async () => {
        const tripId = 'some-trip-id';
        const response: InvoicesByTripIdResponse = {
            balance: 0,
            userId: 'user-id',
            entityId: 'entity-id',
            Billing: [],
        };
        getMock.mockResolvedValueOnce({ data: response });

        const result = await getInvoicesByTripId(client, tripId);

        expect(result).toEqual(response);
        expect(result.Billing).toEqual([]);
    });
});
