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

store.getters = {
    damage: {
        isRepair: false,
    },
};

const mockCmsContent = {
    QuestionText: "Choose a service option:",
    Answers: [
        {
            AnswerImageUrl: "",
            Name: "Mobile",
            SubText: "",
            SubWidgetName: "",
            Text: "Mobile",
        },
        {
            AnswerImageUrl: "",
            Name: "Inshop",
            SubText: "",
            SubWidgetName: "",
            Text: "In-shop",
        },
        {
            AnswerImageUrl: "",
            Name: "Dropoff",
            SubText: "",
            SubWidgetName: "",
            Text: "Drop-off",
        },
    ],
};

const cmsWidgetName = "AppointmentTypeQuestionWidget";
const mockMixin = {
    methods: {
        getCmsContent: jest.fn((widgetName, cmsFieldName) => {
            if (widgetName === cmsWidgetName) {
                return mockCmsContent[cmsFieldName];
            }

            return null;
        }),
    },
};

afterEach(() => {
    // reset store after each test
    store.getters = {
        damage: {
            isRepair: false,
        },
    };
});

describe("appointment-type-question.vue", () => {
    it("Should display all options if in-shop, mobile, and dropoff are available", async () => {
        // Arrange/Act
        const { wrapper } = setupMocks({
            mixins: [mockMixin],
            props: {
                cmsWidgetName: cmsWidgetName,
                isServiceableInshop: true,
                isServiceableMobile: true,
                isServiceableDropoff: true,
            },
            mountOptions: {
                attachTo: document.body,
            },
        });

        // Assert
        expect(wrapper.vm.answersToDisplay).toEqual([
            {
                AnswerImageUrl: "",
                Name: "Mobile",
                SubText: "",
                SubWidgetName: "",
                Text: "Mobile",
            },
            {
                AnswerImageUrl: "",
                Name: "Inshop",
                SubText: "",
                SubWidgetName: "",
                Text: "In-shop",
            },
            {
                AnswerImageUrl: "",
                Name: "Dropoff",
                SubText: "",
                SubWidgetName: "",
                Text: "Drop-off",
            },
        ]);
    });

    it("Should display only the In-Shop and Drop-Off answers when only in-shop service is available", async () => {
        // Arrange/Act
        const { wrapper } = setupMocks({
            mixins: [mockMixin],
            props: {
                cmsWidgetName: cmsWidgetName,
                isServiceableInshop: true,
                isServiceableMobile: false,
            },
            mountOptions: {
                attachTo: document.body,
            },
        });

        // Assert
        expect(wrapper.vm.answersToDisplay).toEqual([
            {
                AnswerImageUrl: "",
                Name: "Inshop",
                SubText: "",
                SubWidgetName: "",
                Text: "In-shop",
            },
            {
                AnswerImageUrl: "",
                Name: "Dropoff",
                SubText: "",
                SubWidgetName: "",
                Text: "Drop-off",
            },
        ]);
    });

    it("Should display only the In-Shop and Drop-Off answers when mobile service is not  available", async () => {
        // Arrange/Act
        const { wrapper } = setupMocks({
            mixins: [mockMixin],
            props: {
                cmsWidgetName: cmsWidgetName,
                isServiceableInshop: true,
                isServiceableMobile: false,
                isServiceableDropoff: true,
            },
            mountOptions: {
                attachTo: document.body,
            },
        });

        // Assert
        expect(wrapper.vm.answersToDisplay).toEqual([
            {
                AnswerImageUrl: "",
                Name: "Inshop",
                SubText: "",
                SubWidgetName: "",
                Text: "In-shop",
            },
            {
                AnswerImageUrl: "",
                Name: "Dropoff",
                SubText: "",
                SubWidgetName: "",
                Text: "Drop-off",
            },
        ]);
    });

    it("Should display only the Mobile answer when only mobile service is available", async () => {
        // Arrange/Act
        const { wrapper } = setupMocks({
            mixins: [mockMixin],
            props: {
                cmsWidgetName: cmsWidgetName,
                isServiceableInshop: false,
                isServiceableMobile: true,
                isServiceableDropoff: false,
            },
            mountOptions: {
                attachTo: document.body,
            },
        });

        // Assert
        expect(wrapper.vm.answersToDisplay).toEqual([
            {
                AnswerImageUrl: "",
                Name: "Mobile",
                SubText: "",
                SubWidgetName: "",
                Text: "Mobile",
            },
        ]);
    });
    it("Should not display Drop off answer when it is repair order", async () => {
        // Arrange/Act

        store.getters = {
            damage: {
                isRepair: true,
            },
        };

        const { wrapper } = setupMocks({
            mixins: [mockMixin],
            props: {
                cmsWidgetName: cmsWidgetName,
                isServiceableInshop: true,
                isServiceableMobile: true,
                isServiceableDropoff: true,
            },
            mountOptions: {
                attachTo: document.body,
            },
        });

        // Assert
        expect(wrapper.vm.answersToDisplay).toEqual([
            {
                AnswerImageUrl: "",
                Name: "Mobile",
                SubText: "",
                SubWidgetName: "",
                Text: "Mobile",
            },
            {
                AnswerImageUrl: "",
                Name: "Inshop",
                SubText: "",
                SubWidgetName: "",
                Text: "In-shop",
            },
        ]);
    });

    it("Should display no answers if neither in-shop nor mobile service are available", async () => {
        // Arrange/Act
        const { wrapper } = setupMocks({
            mixins: [mockMixin],
            props: {
                cmsWidgetName: cmsWidgetName,
                isServiceableInshop: false,
                isServiceableMobile: false,
                isServiceableDropoff: false,
            },
            mountOptions: {
                attachTo: document.body,
            },
        });

        // Assert
        expect(wrapper.vm.answersToDisplay).toEqual([]);
    });
});

function setupMocks({ mountOptions, mixins, props, isShallowMount = true }) {
    const resultingMountOptions = getMountOptions({
        ...mountOptions,
        mixins,
    });

    if (props) resultingMountOptions.propsData = props;

    resultingMountOptions.global.mocks["$store"] = store;

    const wrapper = isShallowMount
        ? shallowMount(appointmentTypeQuestion, resultingMountOptions)
        : mount(appointmentTypeQuestion, resultingMountOptions);

    return { wrapper };
}
