// Components
import confirmation from "@/layouts/confirmation/confirmation.vue";
import { AppointmentTypeStrings, RouteCodeFlags } from "@/constants/schedule-constants";
import { applicationConfig } from "@/constants/application-config.js";

// Supporting Files
import { shallowMount } from "@vue/test-utils";
import { nextTick } from "vue";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import store from "@/store";
import router from "@/router";
import experimentMixin from "@/mixins/experiment-mixin.js";
import { experimentSettings } from "@/constants/experiments";

const mockExperimentSettings = experimentSettings;

jest.mock("@/mixins/experiment-mixin.js", () => ({
    methods: {
        getSettingValue(settingName) {
            if (settingName === mockExperimentSettings.RECAL_PRICE_REMOVE) {
                return true;
            }
        },
        hasSettingEqualTo(settingName, settingValue) {
            return true;
        },
    },
}));

// Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({
    settleAllPromises: jest.fn(),
}));
var wordingText = "wording Text {custom:ADDRESS}";
beforeEach(() => {
    jest.restoreAllMocks();
    jest.clearAllMocks();
    store.getters = {
        order: {
            schedule: {
                date: "2023-01-01",
                startTime: "09:00",
                endTime: "10:00",
                routeCode: "000",
            },
            lineItems: {
                glassParts: [
                    {
                        partNumber: "ABC123",
                    },
                ],
                supportingItems: [],
            },
            serviceLocation: {
                appointmentType: AppointmentTypeStrings.IN_SHOP,
                address: "test",
                address2: "123",
                city: "test",
                state: "AZ",
                appointmentType: "Inshop",
                zipCode: "12345",
                zipCodeCtu: "01234",
                provider: {
                    providerNumber: "123",
                    address: {
                        streetAddress: "test1",
                        city: "test",
                        state: "AZ",
                        zipCode: "12345",
                        zipCodeCtu: "01234",
                    },
                },
            },
            damage: {
                isRepair: false,
            },
            referralNumber: "1234567",
            vehicle: {
                year: "2004",
                make: "Ford",
                model: "F Series F250",
            },
            customer: {
                emailAddress: "test@test.com",
            },
            policy: {
                isNoComp: false,
            },
        },
        damage: {},
        payment: {
            isInsurance: true,
        },
        lineItems: {
            glassParts: [],
            supportingItems: [],
        },
    };
});
afterEach(() => {
    store.getters = {};
    jest.restoreAllMocks();
    jest.clearAllMocks();
});

describe("confirmation.vue", () => {
    const realLocation = window.location;

    beforeAll(() => {
        delete window.location;
        window.location = { ...realLocation, assign: jest.fn() };
    });

    afterAll(() => {
        window.location = realLocation;
    });
    test("arePagePrerequisitesValid should be true ", async () => {
        //Arrange
        const { wrapper } = setupMocks({});

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

        //Assert
        expect(arePagePrerequisitesValid).toBe(true);
    });
    test("'Back to safelite.com' button should take user back to safelite.com", async () => {
        //Arrange
        const { wrapper } = setupMocks({});

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

        //Assert
        expect(window.location.assign).toHaveBeenCalled();
    });
});
describe("computed properties...", () => {
    test("ScheduleDateFormatted should return date in expected format.", () => {
        //Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                startTime: "09:00",
                endTime: "11:00",
                date: "2023-01-01",
                jobMaxMinutes: 120,
                jobMinMinutes: 60,
                routeCode: "",
            },
            serviceLocation: store.getters.order.serviceLocation,
        };

        // Act
        const testValue = wrapper.vm.ScheduleDateFormatted;

        // Assert
        expect(testValue).toEqual("Sunday, January 1");
    });
    test("ScheduleTimeFormatted should return mobile time in expected format.", () => {
        //Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                startTime: "09:00",
                endTime: "11:00",
                date: "2024-09-28",
                jobMaxMinutes: 120,
                jobMinMinutes: 60,
                routeCode: "",
            },
            serviceLocation: store.getters.order.serviceLocation,
        };
        wrapper.vm.submittedOrder.serviceLocation.appointmentType = AppointmentTypeStrings.MOBILE;

        // Act
        const testValue = wrapper.vm.ScheduleTimeFormatted;

        // Assert
        expect(testValue).toEqual("Between 9 AM - 11 AM");
    });
    test("ScheduleTimeFormatted should return DROP_OFF time in expected format.", () => {
        //Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                startTime: "09:00",
                endTime: "11:00",
                date: "2024-09-28",
                jobMaxMinutes: 120,
                jobMinMinutes: 60,
                routeCode: "",
            },
            serviceLocation: store.getters.order.serviceLocation,
        };
        wrapper.vm.submittedOrder.serviceLocation.appointmentType = AppointmentTypeStrings.DROP_OFF;

        // Act
        const testValue = wrapper.vm.ScheduleTimeFormatted;

        // Assert
        expect(testValue).toEqual("Drop off before 9:30 AM");
    });
    test("ScheduleTimeFormatted should return Inshop time in expected format.", () => {
        //Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                startTime: "09:00",
                endTime: "11:00",
                date: "2024-09-28",
                jobMaxMinutes: 120,
                jobMinMinutes: 60,
                routeCode: "",
            },
            serviceLocation: store.getters.order.serviceLocation,
        };
        wrapper.vm.submittedOrder.serviceLocation.appointmentType = AppointmentTypeStrings.IN_SHOP;

        // Act
        const testValue = wrapper.vm.ScheduleTimeFormatted;

        // Assert
        expect(testValue).toEqual("at 9:00 AM");
    });
    test("AppointmentWordingText should return mobile text in expected format.", () => {
        //Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                endTime: "10:00",
                date: "2024-09-28",
                jobMaxMinutes: 120,
                jobMinMinutes: 60,
                routeCode: "",
            },
            serviceLocation: store.getters.order.serviceLocation,
        };
        wrapper.vm.submittedOrder.serviceLocation.appointmentType = AppointmentTypeStrings.MOBILE;
        // Act
        const testValue = wrapper.vm.AppointmentWordingText;

        // Assert
        expect(testValue).toEqual("wording Text test, 123,<br/> test, AZ 12345");
    });
    test("AppointmentWordingText should return DROP_OFF text in expected format.", () => {
        //Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                endTime: "10:00",
                date: "2024-09-28",
                jobMaxMinutes: 120,
                jobMinMinutes: 60,
                routeCode: "",
            },
            serviceLocation: store.getters.order.serviceLocation,
        };
        wrapper.vm.submittedOrder.serviceLocation.appointmentType = AppointmentTypeStrings.DROP_OFF;

        // Act
        const testValue = wrapper.vm.AppointmentWordingText;

        // Assert
        expect(testValue).toEqual("wording Text test1,<br/> test, AZ 12345");
    });
    test("AppointmentWordingText should return IN_SHOP text in expected format.", () => {
        //Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                endTime: "10:00",
                date: "2024-09-28",
                jobMaxMinutes: 120,
                jobMinMinutes: 60,
                routeCode: "",
            },
            serviceLocation: store.getters.order.serviceLocation,
        };

        // Act
        const testValue = wrapper.vm.AppointmentWordingText;

        // Assert
        expect(testValue).toEqual("wording Text test1,<br/> test, AZ 12345");
    });
    test("ConfirmationEmailText should return text in expected format.", () => {
        //Arrange
        wordingText = "{custom:MY_ACCOUNT_URL}";
        const { wrapper } = setupMocks({});
        // Act
        const testValue = wrapper.vm.ConfirmationEmailText;

        // Assert
        expect(testValue).toEqual(applicationConfig.MY_ACCOUNT);
    });
    test("ScheduleDate should return date in expected format.", () => {
        //Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                date: "2023-01-01",
                endTime: "10:00",
                jobMaxMinutes: 120,
                jobMinMinutes: 60,
                routeCode: "",
            },
            serviceLocation: store.getters.order.serviceLocation,
        };

        // Act
        const testValue = wrapper.vm.ScheduleDate;

        // Assert
        expect(testValue).toEqual("2023-01-01");
    });
    test("ScheduleStartTime should return time in expected format.", () => {
        //Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                startTime: "09:00",
                date: "2024-09-28",
                jobMaxMinutes: 120,
                jobMinMinutes: 60,
                routeCode: "",
            },
            serviceLocation: store.getters.order.serviceLocation,
        };

        // Act
        const testValue = wrapper.vm.ScheduleStartTime;

        // Assert
        expect(testValue).toEqual("09:00");
    });
    test("ScheduleEndTime should return time in expected format.", () => {
        //Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                endTime: "10:00",
                date: "2024-09-28",
                jobMaxMinutes: 120,
                jobMinMinutes: 60,
                routeCode: "",
            },
            serviceLocation: store.getters.order.serviceLocation,
        };

        // Act
        const testValue = wrapper.vm.ScheduleEndTime;

        // Assert
        expect(testValue).toEqual("10:00");
    });
    test("InShopWordingText should return text in expected format.", () => {
        //Arrange
        wordingText = "InShopWordingText format";
        const { wrapper } = setupMocks({});

        // Act
        const testValue = wrapper.vm.InShopWordingText;

        // Assert
        expect(testValue).toEqual(wordingText);
    });
    test("MobileWordingText should return text in expected format.", () => {
        //Arrange
        wordingText = "MobileWordingText format";
        const { wrapper } = setupMocks({});

        // Act
        const testValue = wrapper.vm.MobileWordingText;

        // Assert
        expect(testValue).toEqual(wordingText);
    });
    test("DropOffWordingText should return text in expected format.", () => {
        //Arrange
        wordingText = "DropOffWordingText format";
        const { wrapper } = setupMocks({});

        // Act
        const testValue = wrapper.vm.DropOffWordingText;

        // Assert
        expect(testValue).toEqual(wordingText);
    });
    test("ServiceLocationFullAddress should return text in expected format.", () => {
        //Arrange

        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                date: "2024-09-28",
                jobMaxMinutes: 120,
                jobMinMinutes: 60,
                routeCode: "",
            },
            serviceLocation: store.getters.order.serviceLocation,
        };

        // Act
        const testValue = wrapper.vm.ServiceLocationFullAddress;

        // Assert
        expect(testValue).toEqual("test, 123,<br/> test, AZ 12345");
    });
    test("ProviderFullAddress should return text in expected format.", () => {
        //Arrange

        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                date: "2024-09-28",
                jobMaxMinutes: 120,
                jobMinMinutes: 60,
                routeCode: "",
            },
            serviceLocation: store.getters.order.serviceLocation,
        };

        // Act
        const testValue = wrapper.vm.ProviderFullAddress;

        // Assert
        expect(testValue).toEqual("test1,<br/> test, AZ 12345");
    });
    test("Appointment Duration should return text in expected format.", () => {
        //Arrange

        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                date: "2024-09-28",
                jobMaxMinutes: 120,
                jobMinMinutes: 60,
                routeCode: "",
            },
        };

        // Act
        const testValue = wrapper.vm.AppointmentDuration;

        // Assert
        expect(testValue).toEqual("Duration: 1 - 2 hours");
    });
    test("Appointment Duration should return with correct duration values in expected format for hours.", () => {
        //Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                date: "2024-09-28",
                jobMaxMinutes: 120,
                jobMinMinutes: 60,
                routeCode: "",
            },
        };

        // Act
        const testValue = wrapper.vm.AppointmentDuration;

        // Assert
        expect(testValue).toEqual("Duration: 1 - 2 hours");
    });
    test("Appointment Duration should return with correct duration values in expected format for minutes.", () => {
        //Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                date: "2024-09-28",
                jobMaxMinutes: 45,
                jobMinMinutes: 30,
                routeCode: "",
            },
        };

        // Act
        const testValue = wrapper.vm.AppointmentDuration;

        // Assert
        expect(testValue).toEqual("Duration: 30 - 45 minutes");
    });

    test("Appointment Duration should return with All Day.", () => {
        //Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                date: "2024-09-28",
                jobMaxMinutes: 45,
                jobMinMinutes: 30,
                routeCode: RouteCodeFlags.ALL_DAY_DROP_OFF,
            },
        };

        // Act
        const testValue = wrapper.vm.AppointmentDuration;

        // Assert
        expect(testValue).toEqual("Duration: All Day");
    });

    test("Appointment Duration should return with Overnight.", () => {
        //Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.submittedOrder = {
            vehicle: {
                imageUrl: "",
            },
            schedule: {
                date: "2024-09-28",
                jobMaxMinutes: 45,
                jobMinMinutes: 30,
                routeCode: RouteCodeFlags.OVERNIGHT_DROP_OFF,
            },
        };

        // Act
        const testValue = wrapper.vm.AppointmentDuration;

        // Assert
        expect(testValue).toEqual("Duration: Overnight");
    });
});

function setupMocks({ customMountOptions }) {
    const mountOptions = getMountOptions({
        ...customMountOptions,
    });

    mountOptions.mixins = [
        {
            methods: {
                getCmsContent: jest.fn().mockImplementation(() => {
                    return wordingText;
                }),
            },
        },
    ];

    const wrapper = shallowMount(confirmation, mountOptions);
    return { wrapper };
}
