// Components
import vehicle from "@/layouts/vehicle/vehicle.vue";

// Supporting Files
import store from "@/store";
import { shallowMount } from "@vue/test-utils";
import { nextTick } from "vue";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import baseMixin from "../../mixins/base-mixin";
import { settleAllPromises } from "@/helpers/layout-helper.js";

// Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({
    settleAllPromises: jest.fn(),
}));

// Mock fetchCmsContentForPage
jest.mock("@/helpers/cms-content-helper", () => ({
    fetchCmsContentForPage: jest.fn(),
}));

// Mock Store
jest.mock("@/store", () => ({
    commit: jest.fn(),
    dispatch: jest.fn(),
    getters: {
        applicationUser: {
            experiments: [{ universeName: "ConceptFunnel" }],
        },
        externalParameterState: { isExternalParameter: false },
        externalParameterVehicle: {
            year: null,
            make: null,
            model: null,
            style: null,
        },
        vehicle: {
            carId: "C00000000",
            image: "test.jpg",
        },
        order: {
            vehicle: {
                year: 2018,
                make: "Honda",
                model: "Accord",
                style: "4 door sedan",
                carId: "C00000000",
                image: "test.jpg",
            },
        },
    },
}));

describe("vehicle.vue", () => {
    test("arePagePrerequisitesValid should be true ", async () => {
        //Arrange
        const { wrapper } = setupMocks();

        //Act
        let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
        await nextTick();

        //Assert
        expect(arePagePrerequisitesValid).toBe(true);
    });
    test("if the vehicle is not serviceable displays the displayNoServiceAlert", async () => {
        //Arrange
        const { wrapper } = setupMocks({
            canSafeliteService: false,
        });

        //Act
        await wrapper.vm.getVehicleDetails();

        //Assert
        expect(wrapper.findComponent({ ref: "AlertNoService" }).isVisible()).toBe(true);
    });
});
describe("vehicle.vue", () => {
    describe("navigation", () => {
        test("if the continue button is clicked, navigate forward", async () => {
            // Arrange
            const { wrapper } = setupMocks();

            // Act
            await wrapper.vm.forwardButtonAction();

            // Assert
            expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
        });
    });
});

describe("vehicle.vue", () => {
    test("should call forwardButtonAction if isExternalParameter is true and form is valid", async () => {
        store.getters.externalParameterState.isExternalParameter = true;
        // Create a shallow mount of MyComponent
        const { wrapper } = setupMocks();
        // Set displayNoServiceAlert to false
        wrapper.setData({ displayNoServiceAlert: false });

        // Mock the getVehicleDetails method
        wrapper.vm.getVehicleDetails = jest.fn();
        wrapper.vm.forwardButtonAction = jest.fn();

        baseMixin.methods.isFormValid = jest.fn().mockReturnValue(true);
        const nextFunction = jest.fn((c) => {
            c(wrapper.vm);
        });
        // Call the method that contains the if-else logic
        await vehicle.beforeRouteEnter.call(
            wrapper.vm,
            { query: { fmgPage: "vehicle" } },
            undefined,
            nextFunction
        );
        await nextTick();

        expect(nextFunction).toHaveBeenCalled();
        expect(wrapper.vm.forwardButtonAction).toHaveBeenCalled();
    });
});

function setupMocks() {
    const groupName = "vehicle";
    const cmsQuestionText = "Vehicle Year";
    const cmsAnswers = [{ Name: "Vehicle year" }];
    const FunnelFooterWidget = { ForwardButtonText: "vehicle button" };

    //Mock CMS Content
    const cmsContent = {
        groupName: groupName,
        QuestionText: cmsQuestionText,
        Answers: cmsAnswers,
        FunnelFooterWidget: FunnelFooterWidget,
    };
    //Mock props
    const mockMixin = {
        methods: {
            getCmsContent: jest.fn(),
        },
    };
    const mountOptionsMockData = {
        router: {
            navigate: jest.fn(),
            navigateWithSaving: jest.fn(),
            navigateWithoutSaving: jest.fn(),
        },
        route: {
            query: {},
        },
    };
    const apiPromise = Promise.resolve({ cmsContent });
    settleAllPromises.mockImplementation(() => apiPromise);

    const mountOptions = getMountOptions({
        ...mountOptionsMockData,
        mixins: [baseMixin, mockMixin],
    });
    mountOptions["attachTo"] = document.body;

    const wrapper = shallowMount(vehicle, mountOptions);
    wrapper.vm.isDisabled = jest.fn();
    return { wrapper, apiPromise };
}
