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

import damageReview from "@/layouts/payment-method/review-dropdown/review-sections/damage-review/damage-review";
import { damageLocationsSelected as glassConstants } from "@/constants/damage-locations-selected";

const testConstants = {
    cmsConstants: {
        widgetNames: {
            header: "DamageReviewWidget",
            locations: "DamageLocationsWidget",
            driverDamages: "DriverDamagesWidget",
            passengerDamages: "PassengerDamagesWidget",
        },
        header: {
            text: "Damage",
        },
        damageLocations: {
            windshield: glassConstants.WINDSHIELD,
            driver: glassConstants.DRIVER,
            passenger: glassConstants.PASSENGER,
            rear: glassConstants.REAR,
        },
        damageNames: {
            vent: glassConstants.VENT,
            front: glassConstants.FRONT,
            back: glassConstants.BACK,
            quarter: glassConstants.QUARTER,
            side: glassConstants.SIDEDOOR,
        },
        locationCopy: {
            windshield: "Windshield copy",
            driver: "Driver copy",
            passenger: "Passenger copy",
            rear: "Rear copy",
        },
        damageCopy: {
            vent: "Vent copy",
            front: "Front copy",
            back: "Back copy",
            quarter: "Quarter copy",
            side: "Side copy",
        },
        imageId: "00000000-0000-0000-0000-000000000000",
    },
    makeBulletedList: (items) => {
        let list = "<ul>";
        items.forEach((item) => {
            list += `<li>${item}</li>`;
        });
        list += "</ul>";

        return list;
    },
    glassItems: {
        windshield: {
            glassLocation: glassConstants.WINDSHIELD,
            glassName: glassConstants.SINGLE,
        },
        rear: {
            glassLocation: glassConstants.REAR,
            glassName: glassConstants.STATIONARY,
        },
        passengerItems: {
            vent: {
                glassLocation: glassConstants.PASSENGER,
                glassName: glassConstants.VENT,
            },
            front: {
                glassLocation: glassConstants.PASSENGER,
                glassName: glassConstants.FRONT,
            },
            back: {
                glassLocation: glassConstants.PASSENGER,
                glassName: glassConstants.BACK,
            },
            quarter: {
                glassLocation: glassConstants.PASSENGER,
                glassName: glassConstants.QUARTER,
            },
            side: {
                glassLocation: glassConstants.PASSENGER,
                glassName: glassConstants.SIDEDOOR,
            },
        },
        driverItems: {
            vent: {
                glassLocation: glassConstants.DRIVER,
                glassName: glassConstants.VENT,
            },
            front: {
                glassLocation: glassConstants.DRIVER,
                glassName: glassConstants.FRONT,
            },
            back: {
                glassLocation: glassConstants.DRIVER,
                glassName: glassConstants.BACK,
            },
            quarter: {
                glassLocation: glassConstants.DRIVER,
                glassName: glassConstants.QUARTER,
            },
            side: {
                glassLocation: glassConstants.DRIVER,
                glassName: glassConstants.SIDEDOOR,
            },
        },
    },
};

let cmsContent;

describe("Damage Review Block", () => {
    beforeEach(() => {
        cmsContent = {
            DamageReviewWidget: {
                Text: testConstants.cmsConstants.header.text,
            },
            DamageLocationsWidget: {
                Answers: [
                    {
                        Name: testConstants.cmsConstants.damageLocations.windshield,
                        Text: testConstants.cmsConstants.locationCopy.windshield,
                        SubText: "",
                        ImageId: testConstants.cmsConstants.imageId,
                        Image: "",
                        SubWidgetName: "",
                    },
                    {
                        Name: testConstants.cmsConstants.damageLocations.driver,
                        Text: testConstants.cmsConstants.locationCopy.driver,
                        SubText: "",
                        ImageId: testConstants.cmsConstants.imageId,
                        Image: "",
                        SubWidgetName: testConstants.cmsConstants.widgetNames.driverDamages,
                    },
                    {
                        Name: testConstants.cmsConstants.damageLocations.passenger,
                        Text: testConstants.cmsConstants.locationCopy.passenger,
                        SubText: "",
                        ImageId: testConstants.cmsConstants.imageId,
                        Image: "",
                        SubWidgetName: testConstants.cmsConstants.widgetNames.passengerDamages,
                    },
                    {
                        Name: testConstants.cmsConstants.damageLocations.rear,
                        Text: testConstants.cmsConstants.locationCopy.rear,
                        SubText: "",
                        ImageId: testConstants.cmsConstants.imageId,
                        Image: "",
                        SubWidgetName: "",
                    },
                ],
            },
            DriverDamagesWidget: {
                Answers: [
                    {
                        Name: testConstants.cmsConstants.damageNames.vent,
                        Text: testConstants.cmsConstants.damageCopy.vent,
                        SubText: "",
                        ImageId: testConstants.cmsConstants.imageId,
                        Image: "",
                        SubWidgetName: "",
                    },
                    {
                        Name: testConstants.cmsConstants.damageNames.front,
                        Text: testConstants.cmsConstants.damageCopy.front,
                        SubText: "",
                        ImageId: testConstants.cmsConstants.imageId,
                        Image: "",
                        SubWidgetName: "",
                    },
                    {
                        Name: testConstants.cmsConstants.damageNames.back,
                        Text: testConstants.cmsConstants.damageCopy.back,
                        SubText: "",
                        ImageId: testConstants.cmsConstants.imageId,
                        Image: "",
                        SubWidgetName: "",
                    },
                    {
                        Name: testConstants.cmsConstants.damageNames.quarter,
                        Text: testConstants.cmsConstants.damageCopy.quarter,
                        SubText: "",
                        ImageId: testConstants.cmsConstants.imageId,
                        Image: "",
                        SubWidgetName: "",
                    },
                    {
                        Name: testConstants.cmsConstants.damageNames.side,
                        Text: testConstants.cmsConstants.damageCopy.side,
                        SubText: "",
                        ImageId: testConstants.cmsConstants.imageId,
                        Image: "",
                        SubWidgetName: "",
                    },
                ],
            },
            PassengerDamagesWidget: {
                Answers: [
                    {
                        Name: testConstants.cmsConstants.damageNames.vent,
                        Text: testConstants.cmsConstants.damageCopy.vent,
                        SubText: "",
                        ImageId: testConstants.cmsConstants.imageId,
                        Image: "",
                        SubWidgetName: "",
                    },
                    {
                        Name: testConstants.cmsConstants.damageNames.front,
                        Text: testConstants.cmsConstants.damageCopy.front,
                        SubText: "",
                        ImageId: testConstants.cmsConstants.imageId,
                        Image: "",
                        SubWidgetName: "",
                    },
                    {
                        Name: testConstants.cmsConstants.damageNames.back,
                        Text: testConstants.cmsConstants.damageCopy.back,
                        SubText: "",
                        ImageId: testConstants.cmsConstants.imageId,
                        Image: "",
                        SubWidgetName: "",
                    },
                    {
                        Name: testConstants.cmsConstants.damageNames.quarter,
                        Text: testConstants.cmsConstants.damageCopy.quarter,
                        SubText: "",
                        ImageId: testConstants.cmsConstants.imageId,
                        Image: "",
                        SubWidgetName: "",
                    },
                    {
                        Name: testConstants.cmsConstants.damageNames.side,
                        Text: testConstants.cmsConstants.damageCopy.side,
                        SubText: "",
                        ImageId: testConstants.cmsConstants.imageId,
                        Image: "",
                        SubWidgetName: "",
                    },
                ],
            },
        };
    });

    describe("Correctly assembles damage info into a display string", () => {
        test("Shows windshield copy when windshield damage is included", async () => {
            // Arrange
            const { wrapper } = setupMocks({
                propsData: {
                    cmsWidgetName: testConstants.cmsConstants.widgetNames.header,
                    damageLocationsWidgetName: testConstants.cmsConstants.widgetNames.locations,
                    damage: {
                        isRepair: false,
                        glassToReplace: [testConstants.glassItems.windshield],
                    },
                },
            });

            // Act
            await wrapper.vm.$nextTick();

            // Assert
            expect(wrapper.vm.displayContent).toStrictEqual([
                testConstants.cmsConstants.locationCopy.windshield,
            ]);
        });

        test("Windshield copy is shown when order is a repair", async () => {
            // Arrange
            const { wrapper } = setupMocks({
                propsData: {
                    cmsWidgetName: testConstants.cmsConstants.widgetNames.header,
                    damageLocationsWidgetName: testConstants.cmsConstants.widgetNames.locations,
                    damage: {
                        isRepair: true,
                        numberOfChips: 2,
                        glassToReplace: [],
                    },
                },
            });

            // Act
            await wrapper.vm.$nextTick();

            // Assert
            expect(wrapper.vm.displayContent).toStrictEqual([
                testConstants.cmsConstants.locationCopy.windshield,
            ]);
        });

        test("Rear windshield copy shows when rear damage is present", async () => {
            // Arrange
            const { wrapper } = setupMocks({
                propsData: {
                    cmsWidgetName: testConstants.cmsConstants.widgetNames.header,
                    damageLocationsWidgetName: testConstants.cmsConstants.widgetNames.locations,
                    damage: {
                        isRepair: false,
                        numberOfChips: null,
                        glassToReplace: [testConstants.glassItems.rear],
                    },
                },
            });

            // Act
            await wrapper.vm.$nextTick();

            // Assert
            expect(wrapper.vm.displayContent).toStrictEqual([
                testConstants.cmsConstants.locationCopy.rear,
            ]);
        });

        test("Driver side copy and items are shown when driver side damage is present", async () => {
            // Arrange
            const { wrapper } = setupMocks({
                propsData: {
                    cmsWidgetName: testConstants.cmsConstants.widgetNames.header,
                    damageLocationsWidgetName: testConstants.cmsConstants.widgetNames.locations,
                    damage: {
                        isRepair: false,
                        numberOfChips: null,
                        glassToReplace: [
                            testConstants.glassItems.driverItems.back,
                            testConstants.glassItems.driverItems.front,
                        ],
                    },
                },
            });

            // Act
            await wrapper.vm.$nextTick();

            // Assert
            expect(wrapper.vm.displayContent).toStrictEqual([
                testConstants.cmsConstants.locationCopy.driver,
                testConstants.makeBulletedList([
                    testConstants.cmsConstants.damageCopy.front,
                    testConstants.cmsConstants.damageCopy.back,
                ]),
            ]);
        });

        test("Passenger side copy and items are shown when passenger side damage is present", async () => {
            // Arrange
            const { wrapper } = setupMocks({
                propsData: {
                    cmsWidgetName: testConstants.cmsConstants.widgetNames.header,
                    damageLocationsWidgetName: testConstants.cmsConstants.widgetNames.locations,
                    damage: {
                        isRepair: false,
                        numberOfChips: null,
                        glassToReplace: [
                            testConstants.glassItems.passengerItems.quarter,
                            testConstants.glassItems.passengerItems.vent,
                            testConstants.glassItems.passengerItems.side,
                        ],
                    },
                },
            });

            // Act
            await wrapper.vm.$nextTick();

            // Assert
            expect(wrapper.vm.displayContent).toStrictEqual([
                testConstants.cmsConstants.locationCopy.passenger,
                testConstants.makeBulletedList([
                    testConstants.cmsConstants.damageCopy.vent,
                    testConstants.cmsConstants.damageCopy.quarter,
                    testConstants.cmsConstants.damageCopy.side,
                ]),
            ]);
        });

        test("All relevant sections are shown in order in multiglass scenario", async () => {
            // Arrange
            const { wrapper } = setupMocks({
                propsData: {
                    cmsWidgetName: testConstants.cmsConstants.widgetNames.header,
                    damageLocationsWidgetName: testConstants.cmsConstants.widgetNames.locations,
                    damage: {
                        isRepair: false,
                        numberOfChips: null,
                        glassToReplace: [
                            testConstants.glassItems.windshield,
                            testConstants.glassItems.rear,
                            testConstants.glassItems.driverItems.vent,
                            testConstants.glassItems.driverItems.front,
                            testConstants.glassItems.driverItems.back,
                            testConstants.glassItems.passengerItems.quarter,
                            testConstants.glassItems.passengerItems.back,
                            testConstants.glassItems.passengerItems.side,
                        ],
                    },
                },
            });

            // Act
            await wrapper.vm.$nextTick();

            // Assert
            expect(wrapper.vm.displayContent).toStrictEqual([
                testConstants.cmsConstants.locationCopy.windshield,
                testConstants.cmsConstants.locationCopy.driver,
                testConstants.makeBulletedList([
                    testConstants.cmsConstants.damageCopy.vent,
                    testConstants.cmsConstants.damageCopy.front,
                    testConstants.cmsConstants.damageCopy.back,
                ]),
                testConstants.cmsConstants.locationCopy.passenger,
                testConstants.makeBulletedList([
                    testConstants.cmsConstants.damageCopy.back,
                    testConstants.cmsConstants.damageCopy.quarter,
                    testConstants.cmsConstants.damageCopy.side,
                ]),
                testConstants.cmsConstants.locationCopy.rear,
            ]);
        });
    });
});

function setupMocks(customMountOptions) {
    const mountOptions = getMountOptions(customMountOptions);

    const mockMixin = {
        methods: {
            getCmsContent: jest.fn((widgetName, cmsFieldName) => {
                return cmsContent?.[widgetName]?.[cmsFieldName] ?? "";
            }),
        },
    };

    mountOptions.global.mixins = [mockMixin];

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