import * as cookieHelper from "@/helpers/heritage-integration/cookie-helper";
import {
    loadSessionIfPresent,
    saveSession,
    submitWorkOrder,
} from "@/helpers/heritage-integration/order-helper";
import { cookieNames } from "@/constants/cookie-names";
import {
    setupMocksForJsFiles,
    removeAllTestCookies,
    getMockOrderInfo,
    setupCookies,
} from "@/helpers/unit-test-helper.js";
import { storeActions } from "@/constants/store-actions";
import router from "@/router";

describe("loadSessionIfPresent", () => {
    afterEach(() => {
        removeAllTestCookies();
    });

    test("ShouldResetState == true => funnel cookie is deleted", () => {
        // Arrange
        cookieHelper.deleteFunnelCookie = jest.spyOn(cookieHelper, "deleteFunnelCookie");
        const testShouldResetState = true;

        const testCookieValue = {
            ShouldResetState: testShouldResetState,
            ReferralCorrelationId: "xxx",
            ReferralNumber: "12345",
            SavedSessionId: "aa115a05-e268-4eb4-a095-1d54b44f4a99",
        };

        document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}=${JSON.stringify(
            testCookieValue
        )}; path=/; ${cookieHelper.getCookieDomainValue()}`;

        // Act
        loadSessionIfPresent();

        // Assert
        expect(cookieHelper.deleteFunnelCookie).toHaveBeenCalled();
        expect(document.cookie).toBe("");
    });

    test("ShouldResetState == true => reset store", () => {
        // Arrange
        cookieHelper.getFunnelCookie = jest
            .spyOn(cookieHelper, "getFunnelCookie")
            .mockReturnValueOnce({
                ShouldResetState: true,
                ReferralCorrelationId: "xxx-xxx-xxx",
                ReferralNumber: "12345",
                SavedSessionId: "aa115a05-e268-4eb4-a095-1d54b44f4a99",
            });

        const mockData = {
            actionList: [
                {
                    actionName: storeActions.RESET_STATE,
                },
            ],
        };

        var mocks = setupMocksForJsFiles(mockData);

        // Act
        loadSessionIfPresent();

        // Assert
        expect(cookieHelper.getFunnelCookie).toHaveBeenCalled();
        expect(mocks.baseMixin.methods.dispatchStoreAction).toHaveBeenCalledWith(
            storeActions.RESET_STATE
        );
    });

    test("Funnel cookie is null => store is unchanged", () => {
        // Arrange
        cookieHelper.getFunnelCookie = jest
            .spyOn(cookieHelper, "getFunnelCookie")
            .mockReturnValueOnce(null);

        const mockData = {
            actionList: [
                {
                    actionName: storeActions.RESET_STATE,
                },
            ],
        };

        var mocks = setupMocksForJsFiles(mockData);

        // Act
        loadSessionIfPresent();

        // Assert
        expect(cookieHelper.getFunnelCookie).toHaveBeenCalled();
        expect(mocks.baseMixin.methods.dispatchStoreAction).not.toHaveBeenCalledWith(
            storeActions.RESET_STATE
        );
    });

    test("Funnel cookie valid, should call loadSession", async () => {
        // Arrange
        cookieHelper.getFunnelCookie = jest
            .spyOn(cookieHelper, "getFunnelCookie")
            .mockReturnValueOnce({
                ShouldResetState: false,
                ReferralNumber: 123456,
                ReferralCorrelationId: "yyy-yyy-yyyy",
                ReferralDate: new Date(),
                SavedSessionId: "aa115a05-e268-4eb4-a095-1d54b44f4a99",
            });

        const mockData = {
            actionList: [
                {
                    actionName: storeActions.LOAD_SESSION,
                    data: { ReferralNumber: 123456, vehicle: { year: 2010 } },
                },
            ],
        };

        var mocks = setupMocksForJsFiles(mockData);

        // Act
        const result = await loadSessionIfPresent();

        // Assert
        expect(cookieHelper.getFunnelCookie).toHaveBeenCalled();
        expect(mocks.baseMixin.methods.dispatchStoreAction).not.toHaveBeenCalledWith(
            storeActions.LOAD_SESSION
        );
        expect(result.ReferralNumber).toBe(123456);
        expect(result.vehicle.year).toBe(2010);
    });
});

describe("saveSession", () => {
    afterEach(() => {
        removeAllTestCookies();
    });

    test("saveSession => should set state order values", 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,
                },
                {
                    actionName: storeActions.UPDATE_STORE_WITH_SAVE_SESSION_RESPONSE,
                },
            ],
        };

        const mocks = setupMocksForJsFiles(mockData);

        // Act
        await saveSession({ pageNameToLog: "test" });

        // Assert
        expect(mocks.baseMixin.methods.dispatchStoreActionWithLogging).toHaveBeenCalledWith(
            storeActions.SAVE_SESSION,
            { createUnscheduledStatusWorkOrderForPIA: false, submitAfterSave: false },
            "test"
        );
        expect(mocks.baseMixin.methods.dispatchStoreAction).toHaveBeenCalledWith(
            storeActions.UPDATE_STORE_WITH_SAVE_SESSION_RESPONSE,
            {
                referralNumber: mockReferralNumber,
                referralDate: mockReferralDate,
                referralCorrelationId: mockCorrelationId,
                parentAccountNumber: mockParentAccountNumber,
                savedSessionId: mockSavedSessionId,
                crmCustomerId: mockCrmCustomerId,
            },
            false
        );
    });

    test("saveSession => should update DidHeritageFunnelUpdateLast cookie value to false", async () => {
        // Arrange
        const mockReferralNumber = 1566818;
        const mockReferralDate = "2022-03-15T10:56:24.597";
        const mockReferralCorrelationId = "404d2b04-f86e-45c3-b373-127b6217b060";
        const mockParentAccountNumber = "167132";
        const mockSavedSessionId = "xxx-xxx-xxx";
        const mockCrmCustomerId = "xxx-xxx-xxx";

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

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

        setupMocksForJsFiles(mockData);

        const testCookieValue = {
            ReferralNumber: mockReferralNumber,
            ReferralDate: mockReferralDate,
            ReferralCorrelationId: mockReferralCorrelationId,
            ShouldResetState: false,
            DidHeritageFunnelUpdateLast: true,
        };

        setupCookies({ funnelCookieValue: JSON.stringify(testCookieValue) });

        // Act
        await saveSession({ pageNameToLog: "test" });

        // Assert
        expect(cookieHelper.getFunnelCookie().DidHeritageFunnelUpdateLast).toEqual(false);
    });
});

describe("submitWorkOrder", () => {
    afterEach(() => {
        removeAllTestCookies();
    });

    test("submitWorkOrder => should set state order values", 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,
                },
                {
                    actionName: storeActions.UPDATE_STORE_WITH_SAVE_SESSION_RESPONSE,
                },
            ],
        };

        const mocks = setupMocksForJsFiles(mockData);

        // Act
        await submitWorkOrder({ pageNameToLog: "test", submitAfterSave: true });

        // Assert
        expect(mocks.baseMixin.methods.dispatchStoreActionWithLogging).toHaveBeenCalledWith(
            storeActions.SAVE_SESSION,
            { createUnscheduledStatusWorkOrderForPIA: false, submitAfterSave: true },
            "test"
        );
        expect(mocks.baseMixin.methods.dispatchStoreAction).toHaveBeenCalledWith(
            storeActions.UPDATE_STORE_WITH_SAVE_SESSION_RESPONSE,
            {
                referralNumber: mockReferralNumber,
                referralDate: mockReferralDate,
                referralCorrelationId: mockCorrelationId,
                parentAccountNumber: mockParentAccountNumber,
                savedSessionId: mockSavedSessionId,
                crmCustomerId: mockCrmCustomerId,
            },
            false
        );
    });

    test("submitWorkOrder => should update DidHeritageFunnelUpdateLast cookie value to false", async () => {
        // Arrange
        const mockReferralNumber = 1566818;
        const mockReferralDate = "2022-03-15T10:56:24.597";
        const mockReferralCorrelationId = "404d2b04-f86e-45c3-b373-127b6217b060";
        const mockParentAccountNumber = "167132";
        const mockSavedSessionId = "xxx-xxx-xxx";
        const mockCrmCustomerId = "xxx-xxx-xxx";

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

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

        setupMocksForJsFiles(mockData);

        const testCookieValue = {
            ReferralNumber: mockReferralNumber,
            ReferralDate: mockReferralDate,
            ReferralCorrelationId: mockReferralCorrelationId,
            ShouldResetState: false,
            DidHeritageFunnelUpdateLast: true,
        };

        setupCookies({ funnelCookieValue: JSON.stringify(testCookieValue) });

        // Act
        await submitWorkOrder({ pageNameToLog: "test", submitAfterSave: true });

        // Assert
        expect(cookieHelper.getFunnelCookie().DidHeritageFunnelUpdateLast).toEqual(false);
    });
});
