import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import store from "@/store";

import review from "@/layouts/review/review";

const testConstants = {};

jest.mock("@/store", () => ({
    commit: jest.fn(),
    dispatch: jest.fn(),
}));

describe("Review Page", () => {
    beforeEach(() => {
        store.getters = {
            order: {
                vehicle: {
                    year: "2020",
                    make: "Acura",
                    model: "MDX",
                    style: "4 door sedan",
                },
                damage: {
                    isRepair: false,
                    numberOfChips: 2,
                    glassToReplace: ["dummy location value"],
                },
                lineItems: {
                    glassParts: ["dummy part value"],
                    supportingItems: ["dummy supporting item"],
                    vaps: ["dummy vap"],
                },
                serviceLocation: {
                    address: "address 1",
                    address2: "address 2",
                    city: "city",
                    state: "state",
                    zipCode: "zip code",
                    appointmentType: "Mobile",
                    provider: {
                        providerNumber: 1,
                        address: {
                            streetAddress: "provider address 1",
                            city: "provider city",
                            state: "provider state",
                            zipCode: "provider zip code",
                        },
                    },
                },
                schedule: {
                    date: "date",
                    startTime: "start",
                    endTime: "end",
                    jobMinMinutes: "30",
                    jobMaxMinutes: "45",
                },
                customer: {
                    firstName: "first name",
                    lastName: "last name",
                    emailAddress: "builddigitaltest@safelite.com",
                    phoneNumber: "555-555-5555",
                    isSmsOptIn: true,
                },
            },
        };
    });
    describe("arePagePrerequisitesValid", () => {
        test("Returns true for baseline valid state", () => {
            // Arrange
            const { wrapper } = setupMocks({});

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

            // Assert
            expect(isValid).toBe(true);
        });
        test("Returns false for empty state", () => {
            // Arrange
            store.getters.order = {
                vehicle: {
                    year: null,
                    make: null,
                    model: null,
                    style: null,
                    carId: null,
                    category: null,
                    vin: null,
                    imageUrl: null,
                    imageVifNumber: null,
                    imageColor: null,
                    registration: {
                        licensePlate: null,
                    },
                },
                serviceLocation: {
                    address: null,
                    address2: null,
                    city: null,
                    state: null,
                    zipCode: null,
                    zipCodeCtu: null,
                    appointmentType: null,
                    isVehicleProtected: null,
                    provider: {
                        providerNumber: null,
                        address: {
                            streetAddress: null,
                            city: null,
                            state: null,
                            zipCode: null,
                            zipCodeCtu: null,
                        },
                    },
                    techNotes: null,
                },
                customer: {
                    firstName: null,
                    lastName: null,
                    emailAddress: null,
                    phoneNumber: null,
                    isSmsOptIn: null,
                },
                damage: {
                    isRepair: null,
                    numberOfChips: null,
                    glassToReplace: null,
                    partQuestionAnswers: null,
                    moldingQuestionAnswers: null,
                    capabilityQuestionAnswers: null,
                },
                lineItems: {
                    glassParts: null,
                    supportingItems: null,
                    vaps: null,
                    serverData: null,
                },
                payment: {
                    isInsurance: null,
                    insuranceCoverage: {
                        isVerified: null,
                        coverageStatus: null,
                    },
                    parentAccountNumber: 0,
                },
                schedule: {
                    date: null,
                    startTime: null,
                    endTime: null,
                    routeCode: null,
                    jobMaxMinutes: null,
                    jobMinMinutes: null,
                },
                referralNumber: null,
                referralSequenceNumber: null,
                referralDate: null,
                referralCorrelationId: null,
                eon: null,
            };

            const { wrapper } = setupMocks({});

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

            // Assert
            expect(isValid).toBe(false);
        });
        describe("Damage requirements", () => {
            test("Accepts null glassToReplace when is repair", () => {
                // Arrange
                store.getters.order.damage.isRepair = true;
                store.getters.order.damage.glassToReplace = null;
                store.getters.order.damage.numberOfChips = 1;

                const { wrapper } = setupMocks({});

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

                // Assert
                expect(isValid).toBe(true);
            });
            test("Rejects 0 chips when repair", () => {
                // Arrange
                store.getters.order.damage.isRepair = true;
                store.getters.order.damage.numberOfChips = 0;

                const { wrapper } = setupMocks({});

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

                // Assert
                expect(isValid).toBe(false);
            });
            test("Rejects null chips when repair", () => {
                // Arrange
                store.getters.order.damage.isRepair = true;
                store.getters.order.damage.numberOfChips = null;

                const { wrapper } = setupMocks({});

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

                // Assert
                expect(isValid).toBe(false);
            });
            test("Accepts null chips when not repair", () => {
                // Arrange
                store.getters.order.damage.isRepair = false;
                store.getters.order.damage.numberOfChips = null;

                const { wrapper } = setupMocks({});

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

                // Assert
                expect(isValid).toBe(true);
            });
            test("Rejects empty glassToReplace when not repair", () => {
                // Arrange
                store.getters.order.damage.isRepair = false;
                store.getters.order.damage.glassToReplace = null;

                const { wrapper } = setupMocks({});

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

                // Assert
                expect(isValid).toBe(false);
            });
            test("Rejects null glassToReplace when not repair", () => {
                // Arrange
                store.getters.order.damage.isRepair = false;
                store.getters.order.damage.glassToReplace = [];

                const { wrapper } = setupMocks({});

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

                // Assert
                expect(isValid).toBe(false);
            });
        });
        describe("Package requirements", () => {
            test("Accepts null glassParts when is repair", () => {
                // Arrange
                store.getters.order.damage.isRepair = true;
                store.getters.order.lineItems.glassParts = null;

                const { wrapper } = setupMocks({});

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

                // Assert
                expect(isValid).toBe(true);
            });
            test("Rejects null glassParts when not repair", () => {
                // Arrange
                store.getters.order.damage.isRepair = false;
                store.getters.order.lineItems.glassParts = null;

                const { wrapper } = setupMocks({});

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

                // Assert
                expect(isValid).toBe(false);
            });
        });
        describe("Service Location requirements", () => {
            test("Accepts null provider address when mobile appointment", () => {
                // Arrange
                store.getters.order.serviceLocation.appointmentType = "Mobile";
                store.getters.order.serviceLocation.provider.address = {};

                const { wrapper } = setupMocks({});

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

                // Assert
                expect(isValid).toBe(true);
            });
            test("Reject null provider address when non-mobile appointment", () => {
                // Arrange
                store.getters.order.serviceLocation.appointmentType = "Inshop";
                store.getters.order.serviceLocation.provider.address = {};

                const { wrapper } = setupMocks({});

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

                // Assert
                expect(isValid).toBe(false);
            });
            test("Accepts null service location address when non-mobile appointment", () => {
                // Arrange
                store.getters.order.serviceLocation.appointmentType = "Inshop";
                store.getters.order.serviceLocation.address = null;
                store.getters.order.serviceLocation.address2 = null;
                store.getters.order.serviceLocation.zipCode = null;
                store.getters.order.serviceLocation.city = null;
                store.getters.order.serviceLocation.state = null;

                const { wrapper } = setupMocks({});

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

                // Assert
                expect(isValid).toBe(true);
            });
            test("Rejects null service location address when mobile appointment", () => {
                // Arrange
                store.getters.order.serviceLocation.appointmentType = "Mobile";
                store.getters.order.serviceLocation.address = null;
                store.getters.order.serviceLocation.address2 = null;
                store.getters.order.serviceLocation.zipCode = null;
                store.getters.order.serviceLocation.city = null;
                store.getters.order.serviceLocation.state = null;

                const { wrapper } = setupMocks({});

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

                // Assert
                expect(isValid).toBe(false);
            });
        });
    });
});

function setupMocks(customMountOptions) {
    customMountOptions.store = store;

    const mountOptions = getMountOptions(customMountOptions);

    const mockMixin = {
        methods: {
            getCmsContent: jest.fn((widgetName, cmsFieldName) => {
                return `${widgetName} ${cmsFieldName}`;
            }),
        },
    };

    mountOptions.global.mixins = [mockMixin];

    const wrapper = shallowMount(review, mountOptions);
    wrapper.vm.setCmsContent = jest.fn();
    return { wrapper };
}
