// Components
import addressVehicles from "@/layouts/address-vehicles/address-vehicles";

// Supporting Files
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import store from "@/store";
import { storeActions } from "@/constants/store-actions";
import { storeMutations } from "@/constants/store-mutations";
import * as navigateToHeritage from "@/helpers/heritage-integration/navigation-helper";

// Mock our module for promises.
jest.mock("@/helpers/damage-helper", () => ({
    isGlassAvailableForCarId: () => {
        return false;
    },
}));

describe("addressVehicles.vue", () => {
    test("Should return true for valid page requisites if carId / zipCode / emailAddress / pageData exists", async () => {
        // Arrange
        const { wrapper } = setupMocks({});
        store.commit(storeMutations.UPDATE_CAR_ID, "NOT NULL");
        store.commit(storeMutations.UPDATE_SERVICE_LOCATION, { zipCode: "12345" });
        store.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, "test@test.com");

        // Act
        const result = wrapper.vm.arePagePrerequisitesValid();

        //Assert
        expect(result).toBe(true);

        wrapper.unmount();
    });

    test("Should return false for valid page requisites if carId is missing", async () => {
        // Arrange
        const { wrapper } = setupMocks({});

        // Act
        store.commit(storeMutations.UPDATE_CAR_ID, null);
        const result = wrapper.vm.arePagePrerequisitesValid();

        //Assert
        expect(result).toBe(false);

        wrapper.unmount();
    });

    // NOTE: this test is only here to meet code coverage; it does not test any logic in the original function
    test("Should navigate to CLICKED_BACK if backButtonAction is run", async () => {
        // Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.$router.navigateWithoutSaving = jest.fn();

        // Act
        await wrapper.setData({
            selectedVehicleVin: "5NMS3CADXLH233004",
        });
        wrapper.vm.backButtonAction();

        //Assert
        expect(wrapper.vm.$router.navigateWithoutSaving).toBeCalled();

        wrapper.unmount();
    });

    // NOTE: this test is only here to meet code coverage; it does not test any logic in the original function
    test("Should run several related methods if forwardButtonAction is run", async () => {
        // Arrange
        const { wrapper } = setupMocks({});
        const lookupVinResponse = {
            data: {
                carId: "456",
            },
        };

        // the following has to be set BEFORE changing the data which is being watched, and requires updateButtonText to be mocked
        wrapper.vm.$refs.navbar.updateButtonText = jest.fn();
        wrapper.vm.$refs.navbar.removeLoader = jest.fn();
        wrapper.vm.lookupVin = jest.fn(() => Promise.resolve(lookupVinResponse));
        wrapper.vm.$router.navigate = jest.fn();
        wrapper.vm.updateCustomerInfo = jest.fn().mockImplementation(() => {});
        wrapper.vm.navigateForward = jest.fn().mockImplementation(() => {});

        // Act
        await wrapper.setData({
            selectedVehicleVin: "5NMS3CADXLH233004",
        });

        await wrapper.vm.forwardButtonAction();
        wrapper.vm.$nextTick();

        //Assert
        expect(wrapper.vm.navigateForward).toBeCalled();

        wrapper.unmount();
    });

    test("Should return out of forwardButtonAction if lookupVin returns with an error", async () => {
        // Arrange
        const { wrapper } = setupMocks({});

        const lookupVinResponse = {
            error: "there is an error",
        };

        // the following has to be set BEFORE changing the data which is being watched, and requires updateButtonText to be mocked
        wrapper.vm.$refs.navbar.updateButtonText = jest.fn();
        wrapper.vm.$refs.navbar.removeLoader = jest.fn();
        wrapper.vm.lookupVin = jest.fn(() => Promise.reject(lookupVinResponse));
        wrapper.vm.$router.navigateWithSaving = jest.fn();
        wrapper.vm.updateCustomerInfo = jest.fn().mockImplementation(() => {});

        // Act
        await wrapper.setData({
            selectedVehicleVin: "5NMS3CADXLH233004",
        });
        await wrapper.vm.forwardButtonAction();
        wrapper.vm.$nextTick();

        //Assert
        expect(wrapper.vm.forwardButtonAction).toReturn;

        wrapper.unmount();
    });

    test("Should navigate to CLICKED_FORWARD scenario if carId is different and selected glass not available for vehicle on navigateForward", async () => {
        // Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.$refs.navbar.updateButtonText = jest.fn();
        wrapper.vm.$router.navigateWithSaving = jest.fn();

        // Act
        await wrapper.setData({
            selectedVehicleVin: "5NMS3CADXLH233004",
            isSelectedGlassAvailableForVehicle: false,
            isCarIdDifferent: true,
        });
        await wrapper.vm.navigateForward();

        //Assert
        expect(wrapper.vm.$router.navigateWithSaving).toBeCalledTimes(1);

        wrapper.unmount();
    });

    test("carId is not different on navigateForward (car was found) => Should handle navigating forward with car match", async () => {
        // Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.$refs.navbar.updateButtonText = jest.fn();
        navigateToHeritage.navigateToHeritageFunnel = jest.fn();

        // Act
        await wrapper.setData({
            isCarIdDifferent: false,
        });
        await wrapper.vm.navigateForward();

        //Assert
        expect(wrapper.vm.navigateForwardWithSingleCarMatch).toBeCalledTimes(1);

        wrapper.unmount();
    });
});

function setupMocks({}) {
    //Mock store
    store.commit(storeMutations.RESET_STATE);
    store.commit(storeMutations.UPDATE_PAGE_DATA, {
        page: "address-vehicles",
        data: [
            {
                vehicle: {
                    carId: "CR00069309",
                    category: "SUV",
                    year: 2020,
                    make: "Hyundai",
                    model: "Santa Fe",
                    style: "4 door utility",
                    imageUrl:
                        "https://dbhdyzvm8lm25.cloudfront.net/color_0320_032/MY2020/13769/13769_cc0320_032_WW8.jpg",
                    imageVifNumber: "13769",
                    imageVifColor: "white",
                },
                vin: "5NMS3CADXLH233004",
            },
        ],
    });

    const mountOptions = getMountOptions({
        router: {
            navigate: jest.fn(),
        },
        actionList: [
            {
                actionName: storeActions.LOOKUP_VEHICLE_BY_VIN,
                data: {},
            },
        ],
    });

    //Mock props
    const mockMixin = {
        methods: {
            getCmsContent: jest.fn((contentName) => {
                if (contentName === "FoundMultipleVehicles") {
                    return "FoundMultipleVehiclesTestReturn";
                }
                if (contentName === "ProvideVinAlert") {
                    return "ProvideVinAlertTestReturn";
                }
                return null;
            }),
        },
        computed: {
            dynamicStrings() {
                return { ROUTER_LINK: "routerLink:" };
            },
        },
    };

    mountOptions.mixins = [mockMixin];

    const wrapper = shallowMount(addressVehicles, mountOptions);

    wrapper.vm.$refs.navbar.updateButtonText = jest.fn();
    wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();

    return { wrapper };
}
