import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest';
import { Client } from '@vulog/aima-client';
import { getUserDocuments } from './getUserDocuments';
import { personalInformationUserTypes } from '../../user/src/types';
import { personalInformationDocumentTypes } from './types';

describe('getUserDocument', () => {
    const FLEET_ID = 'FLEET_ID';
    const USER_ID = '018ab2b6-71b2-4c76-90bd-6e8d3f268618';
    const docTypeId = {
        id: 690,
        fleetId: FLEET_ID,
        type: 'IDENTITY_CARD',
        name: 'ID',
        mandatory: false,
        hasNumber: true,
        hasExpirationDate: false,
        numberUploadUrl: 1,
        hasIssuingCountry: false,
        hasIssuingOffice: true,
        hasIssuingDate: true,
        hasDlClass: false,
    };
    const docTypeDl = {
        id: 691,
        fleetId: FLEET_ID,
        type: 'DRIVING_LICENSE',
        name: 'Driving license',
        mandatory: false,
        hasNumber: true,
        hasExpirationDate: false,
        numberUploadUrl: 2,
        hasIssuingCountry: true,
        hasIssuingOffice: true,
        hasIssuingDate: true,
        hasDlClass: true,
        hasIssuingSubdivision: true,
    };
    const docTypeSelfie = {
        id: 460,
        fleetId: FLEET_ID,
        type: 'SELFIE',
        name: 'Selfie',
        mandatory: false,
        hasNumber: false,
        hasExpirationDate: false,
        numberUploadUrl: 1,
        hasIssuingCountry: false,
        hasIssuingOffice: false,
        hasIssuingDate: false,
        hasDlClass: false,
        hasIssuingSubdivision: false,
    };
    const idDocId = 10892065;
    const dlDocId = 10892077;
    const selfieDocId = 10931811;
    const documents = {
        documentTypes: [{ ...docTypeId }, { ...docTypeDl }, { ...docTypeSelfie }],
        documents: [
            {
                id: idDocId,
                fleetId: FLEET_ID,
                userId: USER_ID,
                documentType: { ...docTypeId },
                expirationDate: '1970-01-01',
                approvalDate: null,
                files: [
                    {
                        id: null,
                        url: `https://java-test.vulog.com/boapi/proxy/upload/fleets/${FLEET_ID}/users/${USER_ID}/documents/${idDocId}/${docTypeId.type}_0`,
                        name: `${docTypeId.type}_0`,
                    },
                ],
                uploadUrls: [
                    {
                        id: null,
                        url: `https://java-test.vulog.com/upload/fleets/${FLEET_ID}/documents/${idDocId}/${docTypeId.type}_0?tk=s2TzoXn%2BhEUKnCbEEFZfhRqOvStMSdS14ow3QHFhgRA3ttoqIrcNxpP4JhMvyIYkyGLo%2Bnwttnz3zt1NkOX3Lf8PBVPiXXyxB9%2BtW1FkBISvOOjA0FTyMLquFoe2cSNn`,
                        name: `${docTypeId.type}_0`,
                    },
                ],
                status: 'VALID',
                reviewer: '493a4d98-7437-42db-8d4e-bd722ac62caa',
                issuingCountry: null,
                issuingOffice: 'Nice, 06',
                issuingDate: '2023-01-16',
                dlClass: null,
                issuingSubdivision: null,
                documentNumber: null,
            },
            {
                id: dlDocId,
                fleetId: FLEET_ID,
                userId: USER_ID,
                documentType: { ...docTypeDl },
                expirationDate: '1970-01-01',
                approvalDate: null,
                files: [
                    {
                        id: null,
                        url: `https://java-test.vulog.com/boapi/proxy/upload/fleets/${FLEET_ID}/users/${USER_ID}/documents/${dlDocId}/${docTypeDl.type}_0`,
                        name: `${docTypeDl.type}_0`,
                    },
                    {
                        id: null,
                        url: `https://java-test.vulog.com/boapi/proxy/upload/fleets/${FLEET_ID}/users/${USER_ID}/documents/${dlDocId}/${docTypeDl.type}_1`,
                        name: `${docTypeDl.type}_1`,
                    },
                ],
                uploadUrls: [
                    {
                        id: null,
                        url: `https://java-test.vulog.com/upload/fleets/${FLEET_ID}/documents/${dlDocId}/${docTypeDl.type}_0?tk=3Xs08XSnb2ZatHY%2Blic5G88IMPGKs0LOy8hlM47eaER1nPDxgYeewOMYySGQfbPMKz3Opy5T3RPULV9O3IBCm4iOIApdah4Q22rCi4hH5rZ%2BOyGuLwmffBuoYA16rLuO`,
                        name: `${docTypeDl.type}_0`,
                    },
                    {
                        id: null,
                        url: `https://java-test.vulog.com/upload/fleets/${FLEET_ID}/documents/${dlDocId}/${docTypeDl.type}_1?tk=fg8Y3duKmYM3olsMaC6mipzB5AsjCf5h8mRHwNb4iGzpy8MqMXigaBce5PxdFKcgiuQjoWYvcbBZx2W985Mqt8CGpxoGIzqbYOmsS9kvPjp6UZERqnfan73y5vk3MPUy`,
                        name: `${docTypeDl.type}_1`,
                    },
                ],
                status: 'VALID',
                reviewer: '493a4d98-7437-42db-8d4e-bd722ac62caf',
                issuingCountry: 'FR',
                issuingOffice: 'Nice',
                issuingDate: '1994-02-18',
                dlClass: 'B',
                issuingSubdivision: '06',
                documentNumber: '123456',
            },
            {
                id: selfieDocId,
                fleetId: FLEET_ID,
                userId: USER_ID,
                documentType: { ...docTypeSelfie },
                expirationDate: null,
                approvalDate: null,
                files: [
                    {
                        id: null,
                        url: 'https://java-eu01.vulog.com/upload/fleets/${FLEET_ID}/file?tk=sbSfJzSpv8xJ4FN7ETn5Zq5ykKoAmYKIpFjvVPzVpsCcAGmrMWNJ3h4NunQu***',
                        name: `${docTypeSelfie.type}_0`,
                    },
                ],
                uploadUrls: [
                    {
                        id: null,
                        url: 'https://java-eu01.vulog.com/upload/fleets/${FLEET_ID}/documents/10931800/SELFIE_0?tk=sbSfJzSpv8xJ4FN7ETn5Zn1MGPxqzzDIvE1WJ***',
                        name: `${docTypeSelfie.type}_0`,
                    },
                ],
                status: 'VALID',
                reviewer: 'Registration',
                issuingCountry: null,
                issuingOffice: null,
                issuingDate: null,
                dlClass: null,
                issuingSubdivision: null,
                documentNumber: null,
            },
        ],
        documentByService: [
            {
                serviceId: '0166e9a0-ac01-46d1-8211-f5ac24145953',
                areMandatoryPresent: false,
                mandatoryDocumentTypeId: [],
            },
            {
                serviceId: '0a6db44e-8a83-4f74-a6f8-5b21bd693289',
                areMandatoryPresent: false,
                mandatoryDocumentTypeId: [],
            },
        ],
        documentByFranchise: null,
    };
    const piId = {
        fleetId: FLEET_ID,
        userId: USER_ID,
        documentId: idDocId,
        documentNumber1: '741',
        updateDate: '2025-04-29T10:40:42.000Z',
    };
    const piDl = {
        fleetId: FLEET_ID,
        userId: USER_ID,
        documentId: dlDocId,
        documentNumber1: '159',
        updateDate: '2025-04-29T10:40:42.000Z',
    };

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

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

        getMock.mockImplementation((url: string): Promise<any> => {
            if (url === `/boapi/proxy/user/fleets/${FLEET_ID}/users/${USER_ID}/documents`) {
                return Promise.resolve({
                    data: documents,
                    status: 200,
                    statusText: 'OK',
                    headers: {},
                    config: {},
                });
            } else if (
                url.startsWith(`/boapi/proxy/user/fleets/${FLEET_ID}/users/${USER_ID}/documents/${idDocId}/pi`)
            ) {
                return Promise.resolve({
                    data: piId,
                    status: 200,
                    statusText: 'OK',
                    headers: {},
                    config: {},
                });
            } else if (
                url.startsWith(`/boapi/proxy/user/fleets/${FLEET_ID}/users/${USER_ID}/documents/${dlDocId}/pi`)
            ) {
                return Promise.resolve({
                    data: piDl,
                    status: 200,
                    statusText: 'OK',
                    headers: {},
                    config: {},
                });
            } else if (
                url.startsWith(`/boapi/proxy/user/fleets/${FLEET_ID}/users/${USER_ID}/documents/${selfieDocId}/pi`)
            ) {
                return Promise.resolve({
                    data: {
                        fleetId: FLEET_ID,
                        userId: USER_ID,
                        documentId: selfieDocId,
                    },
                    status: 200,
                    statusText: 'OK',
                    headers: {},
                    config: {},
                });
            }
            // Pour les autres URLs, rejetez la promesse
            return Promise.reject(new Error('404 Not Found'));
        });
    });

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

    test('call without PI', async () => {
        const docs = await getUserDocuments(client, USER_ID);
        expect(getMock).toHaveBeenCalledOnce();
        expect(getMock).toBeCalledWith(`/boapi/proxy/user/fleets/${FLEET_ID}/users/${USER_ID}/documents`);

        expect(docs).toBeTruthy();
        expect(docs.documents).toBeTruthy();
        expect(docs.documents.length).toEqual(documents.documents.length);
        expect(docs.documents.length).toEqual(3);
        expect(docs.documents[0].id).toEqual(documents.documents[0].id);
        expect(docs.documents[0].documentNumber).toBeNull();
        expect(docs.documents[1].id).toEqual(documents.documents[1].id);
        expect(docs.documents[1].documentNumber).toEqual(documents.documents[1].documentNumber);
        expect(docs.documents[2].id).toEqual(documents.documents[2].id);
        expect(docs.documents[2].documentNumber).toBeNull();

        expect(docs.documents[0].fleetId).toEqual(documents.documents[0].fleetId);
        expect(docs.documents[0].userId).toEqual(documents.documents[0].userId);
        expect(docs.documents[0].documentType).not.toBeNull();
        expect(docs.documents[0].documentNumber).toEqual(documents.documents[0].documentNumber);
        expect(docs.documents[0].expirationDate).toEqual(documents.documents[0].expirationDate);
        expect(docs.documents[0].files).toEqual(documents.documents[0].files);
        expect(docs.documents[0].uploadUrls).toEqual(documents.documents[0].uploadUrls);
        expect(docs.documents[0].status).toEqual(documents.documents[0].status);
        expect(docs.documents[0].reviewer).toEqual(documents.documents[0].reviewer);
        expect(docs.documents[0].issuingCountry).toEqual(documents.documents[0].issuingCountry);
        expect(docs.documents[0].issuingOffice).toEqual(documents.documents[0].issuingOffice);
        expect(docs.documents[0].issuingDate).toEqual(documents.documents[0].issuingDate);
        expect(docs.documents[0].dlClass).toEqual(documents.documents[0].dlClass);
        expect(docs.documents[0].issuingSubdivision).toEqual(documents.documents[0].issuingSubdivision);

        expect(docs.documents[1].fleetId).toEqual(documents.documents[1].fleetId);
        expect(docs.documents[1].userId).toEqual(documents.documents[1].userId);
        expect(docs.documents[1].documentType).not.toBeNull();
        expect(docs.documents[1].documentNumber).toEqual(documents.documents[1].documentNumber);
        expect(docs.documents[1].expirationDate).toEqual(documents.documents[1].expirationDate);
        expect(docs.documents[1].files).toEqual(documents.documents[1].files);
        expect(docs.documents[1].uploadUrls).toEqual(documents.documents[1].uploadUrls);
        expect(docs.documents[1].status).toEqual(documents.documents[1].status);
        expect(docs.documents[1].reviewer).toEqual(documents.documents[1].reviewer);
        expect(docs.documents[1].issuingCountry).toEqual(documents.documents[1].issuingCountry);
        expect(docs.documents[1].issuingOffice).toEqual(documents.documents[1].issuingOffice);
        expect(docs.documents[1].issuingDate).toEqual(documents.documents[1].issuingDate);
        expect(docs.documents[1].dlClass).toEqual(documents.documents[1].dlClass);
        expect(docs.documents[1].issuingSubdivision).toEqual(documents.documents[1].issuingSubdivision);

        expect(docs.documents[2].fleetId).toEqual(documents.documents[2].fleetId);
        expect(docs.documents[2].userId).toEqual(documents.documents[2].userId);
        expect(docs.documents[2].documentType).not.toBeNull();
        expect(docs.documents[2].documentNumber).toEqual(documents.documents[2].documentNumber);
        expect(docs.documents[2].expirationDate).toEqual(documents.documents[2].expirationDate);
        expect(docs.documents[2].files).toEqual(documents.documents[2].files);
        expect(docs.documents[2].uploadUrls).toEqual(documents.documents[2].uploadUrls);
        expect(docs.documents[2].status).toEqual(documents.documents[2].status);
        expect(docs.documents[2].reviewer).toEqual(documents.documents[2].reviewer);
        expect(docs.documents[2].issuingCountry).toEqual(documents.documents[2].issuingCountry);
        expect(docs.documents[2].issuingOffice).toEqual(documents.documents[2].issuingOffice);
        expect(docs.documents[2].issuingDate).toEqual(documents.documents[2].issuingDate);
        expect(docs.documents[2].dlClass).toEqual(documents.documents[2].dlClass);
        expect(docs.documents[2].issuingSubdivision).toEqual(documents.documents[2].issuingSubdivision);
    });

    test('call with PI', async () => {
        const docs = await getUserDocuments(client, USER_ID, ['DOCUMENT_NUMBER_1']);
        expect(getMock).toHaveBeenCalledTimes(4);
        expect(getMock).toBeCalledWith(`/boapi/proxy/user/fleets/${FLEET_ID}/users/${USER_ID}/documents`);
        expect(getMock).toBeCalledWith(
            `/boapi/proxy/user/fleets/${FLEET_ID}/users/${USER_ID}/documents/${idDocId}/pi?types=DOCUMENT_NUMBER_1`
        );
        expect(getMock).toBeCalledWith(
            `/boapi/proxy/user/fleets/${FLEET_ID}/users/${USER_ID}/documents/${dlDocId}/pi?types=DOCUMENT_NUMBER_1`
        );

        expect(docs).toBeTruthy();
        expect(docs.documents).toBeTruthy();
        expect(docs.documents.length).toEqual(documents.documents.length);
        expect(docs.documents.length).toEqual(3);
        expect(docs.documents[0].id).toEqual(documents.documents[0].id);
        expect(docs.documents[0].documentNumber).toBeTruthy();
        expect(docs.documents[1].id).toEqual(documents.documents[1].id);
        expect(docs.documents[1].documentNumber).toBeTruthy();
        expect(docs.documents[2].id).toEqual(documents.documents[2].id);
        expect(docs.documents[2].documentNumber).toBeFalsy();

        if (docs.documents[0].id === idDocId) {
            expect(docs.documents[0].documentNumber).toEqual(piId.documentNumber1);
            expect(docs.documents[1].documentNumber).toEqual(piDl.documentNumber1);
        }
        if (docs.documents[0].id === dlDocId) {
            expect(docs.documents[0].documentNumber).toEqual(piDl.documentNumber1);
            expect(docs.documents[1].documentNumber).toEqual(piId.documentNumber1);
        }
    });
});
