import * as navigationHelper from "@/helpers/heritage-integration/navigation-helper";
import * as orderHelper from "@/helpers/heritage-integration/order-helper";
import { lazyLoadComponent } from "@/router/methods/helpers/lazy-load-component";
import { storeActions } from "@/constants/store-actions";
import { storeMutations } from "@/constants/store-mutations";
import { setupMocksForJsFiles, getMockOrderInfo } from "@/helpers/unit-test-helper.js";
import { externalUrls } from "@/router/constants/externalUrl-values";
import { queryStrings } from "@/constants/query-strings";

import { damageLocationsSelected as glassLocations } from "@/constants/damage-locations-selected";

import store from "@/store";
import router from "@/router";

const getPageToRouteExistingOrderTo = navigationHelper.getPageToRouteExistingOrderTo;
const navigateToHeritageFunnel = navigationHelper.navigateToHeritageFunnel;

// Mock Lazy Load
jest.mock("@/router/methods/helpers/lazy-load-component", () => ({
    lazyLoadComponent: jest.fn(),
}));

describe("navigateToHeritageFunnel", () => {
    test("should save session", async () => {
        // Arrange
        const mockReferralNumber = "2";
        const mockCorrelationId = "55";
        const mockReferralDate = "2022";
        const mockParentAccountNumber = "167132";
        const mockSavedSessionId = "xxx-xxx-xxx";
        const mockCrmCustomerId = "xxx-xxx-xxx";

        const mockOrderInfo = getMockOrderInfo(
            mockReferralNumber,
            mockCorrelationId,
            mockReferralDate,
            mockParentAccountNumber,
            mockSavedSessionId,
            mockCrmCustomerId
        );

        const mockData = {
            actionList: [
                {
                    actionName: storeActions.SAVE_SESSION,
                    data: mockOrderInfo,
                },
            ],
        };

        setupMocksForJsFiles(mockData);
        const saveSessionFunction = jest.spyOn(orderHelper, "saveSession");
        router.navigateToExternalUrl = jest.fn();

        // Act
        await navigateToHeritageFunnel({ shouldSaveSession: true });

        // Assert
        expect(saveSessionFunction).toHaveBeenCalled();

        // Should save before we navigate to heritage by default
        const saveSessionFunctionCallOrder = saveSessionFunction.mock.invocationCallOrder[0];
        const routerNavigateFunctionCallOrder =
            router.navigateToExternalUrl.mock.invocationCallOrder[0];
        expect(saveSessionFunctionCallOrder).toBeLessThan(routerNavigateFunctionCallOrder);
        saveSessionFunction.mockRestore();
    });

    test("should go to heritage funnel", async () => {
        // Arrange
        const mockReferralNumber = "2";
        const mockCorrelationId = "55";
        const mockReferralDate = "2022";
        const mockParentAccountNumber = "167132";
        const mockSavedSessionId = "xxx-xxx-xxx";
        const mockCrmCustomerId = "xxx-xxx-xxx";

        const mockOrderInfo = getMockOrderInfo(
            mockReferralNumber,
            mockCorrelationId,
            mockReferralDate,
            mockParentAccountNumber,
            mockSavedSessionId,
            mockCrmCustomerId
        );

        const mockData = {
            actionList: [
                {
                    actionName: storeActions.SAVE_SESSION,
                    data: mockOrderInfo,
                },
            ],
        };

        setupMocksForJsFiles(mockData);

        store.getters.order.referralCorrelationId = mockCorrelationId;

        router.navigateToExternalUrl = jest.fn();

        // Act
        await navigateToHeritageFunnel({});

        // Assert
        expect(router.navigateToExternalUrl).toHaveBeenCalled();
        expect(router.navigateToExternalUrl).toHaveBeenCalledWith(
            externalUrls.HERITAGE_FUNNEL,
            expect.objectContaining({
                corid: mockCorrelationId,
            })
        );
    });

    test("shouldSaveSession is false => should not save session, but should still navigate", async () => {
        // Arrange
        const mockReferralNumber = "2";
        const mockCorrelationId = "55";
        const mockReferralDate = "2022";

        const mockOrderInfo = getMockOrderInfo(
            mockReferralNumber,
            mockCorrelationId,
            mockReferralDate
        );

        const mockData = {
            actionList: [
                {
                    actionName: storeActions.SAVE_SESSION,
                    data: mockOrderInfo,
                },
            ],
        };

        setupMocksForJsFiles(mockData);
        const saveSessionFunction = jest.spyOn(orderHelper, "saveSession");
        router.navigateToExternalUrl = jest.fn();

        // Act
        await navigateToHeritageFunnel({ shouldSaveSession: false });

        // Assert
        expect(saveSessionFunction).not.toHaveBeenCalled();
        expect(router.navigateToExternalUrl).toHaveBeenCalled();
        saveSessionFunction.mockRestore();
    });
});

/**
 * `arePagePrerequisitesValidObject` is an object where the keys are fmgPageValue names and the values are booleans that indicate
 * whether arePagePrerequisitesValid is true or false
 */
function mockLazyLoadComponentReturnValues(arePagePrerequisitesValidObject = {}) {
    lazyLoadComponent.mockImplementation((pageName) => {
        return async () => {
            return Promise.resolve({
                default: {
                    methods: {
                        arePagePrerequisitesValid: jest
                            .fn()
                            .mockReturnValueOnce(arePagePrerequisitesValidObject[pageName]),
                    },
                },
            });
        };
    });
}
