import {
    getPricedMobileFeePart,
    getServiceabilityDetails,
    getAvailabilityRating,
} from "./service-location-helper";
import { storeActions } from "@/constants/store-actions";

jest.mock("@/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,
                    address: null,
                    city: null,
                    state: null,
                    zipCode: null,
                    firstName: null,
                    lastName: null,
                },
            },
            serviceLocation: {
                address: null,
                city: null,
                state: null,
                zipCode: null,
                zipCodeCtu: null,
                appointmentType: null,
                provider: {
                    providerNumber: null,
                    address: {
                        streetAddress: null,
                        city: null,
                        state: null,
                        zipCode: null,
                        zipCodeCtu: null,
                    },
                },
            },
            customer: {
                emailAddress: 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,
            },
            referralNumber: null,
            referralDate: null,
            referralCorrelationId: null,
            eon: null,
        },
    },
}));

const mockStoreActionGetMobileFeePart = storeActions.GET_MOBILE_FEE_PART;
const mockStoreActionPriceOrderItemsAndSaveServerData =
    storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA;
const mockStoreActionGetServiceabilityDetails = storeActions.GET_SERVICEABILITY_DETAILS;
const mockStoreActionGetShopTimeSlots = storeActions.GET_SHOP_TIME_SLOTS;

const mockGetShopTimeSlotsGoodAvailability = {
    data: {
        estimatedServiceMinutesMinimum: 0,
        estimatedServiceMinutesMaximimum: 0,
        days: [
            {
                date: "string",
                timeSlots: [
                    {
                        id: "string",
                        startTime: "",
                        endTime: "",
                        offerPremium: true,
                    },
                ],
            },
            {
                date: "string",
                timeSlots: [
                    {
                        id: "string",
                        startTime: "",
                        endTime: "",
                        offerPremium: true,
                    },
                ],
            },
        ],
    },
};

const mockGetShopTimeSlotsLowAvailability = {
    data: {
        estimatedServiceMinutesMinimum: 0,
        estimatedServiceMinutesMaximimum: 0,
        days: [
            {
                date: "string",
                timeSlots: [
                    {
                        id: "string",
                        startTime: "",
                        endTime: "",
                        offerPremium: true,
                    },
                ],
            },
        ],
    },
};

jest.mock("@/mixins/base-mixin.js", () => ({
    methods: {
        getZipCodeData: jest.fn().mockImplementation(() => {
            return Promise.resolve({
                containsMilitaryBase: false,
                isServiceable: true,
                isValid: true,
                state: "OH",
                zipCodeCtu: "01820",
            });
        }),

        dispatchStoreAction: jest.fn().mockImplementation((actionName, request) => {
            if (actionName === mockStoreActionGetMobileFeePart) {
                return Promise.resolve({
                    data: {
                        partNumber: "MOBILE FEE",
                        description: "MOBILE FEE",
                        partType: "FEE",
                    },
                });
            }

            if (actionName === mockStoreActionPriceOrderItemsAndSaveServerData) {
                return Promise.resolve([
                    {
                        partNumber: "MOBILE FEE",
                        description: "MOBILE FEE",
                        partType: "FEE",
                        laborAmount: 49.99,
                        sellingPrice: 0,
                        kitPrice: 0,
                    },
                ]);
            }

            if (actionName === mockStoreActionGetServiceabilityDetails) {
                return Promise.resolve({
                    isGlassServiceableInshop: true,
                    isRecalibrationServiceableInshop: true,
                    isGlassServiceableMobile: true,
                    isRecalibrationServiceableMobile: true,
                });
            }

            if (actionName === mockStoreActionGetShopTimeSlots) {
                if (request.providerNumber == "0000001") {
                    return Promise.resolve(mockGetShopTimeSlotsGoodAvailability);
                }

                return Promise.resolve(mockGetShopTimeSlotsLowAvailability);
            }
        }),
        dispatchStoreActionWithLogging: jest.fn().mockImplementation((actionName, request) => {
            if (actionName === mockStoreActionGetMobileFeePart) {
                return Promise.resolve({
                    data: {
                        partNumber: "MOBILE FEE",
                        description: "MOBILE FEE",
                        partType: "FEE",
                    },
                });
            }

            if (actionName === mockStoreActionPriceOrderItemsAndSaveServerData) {
                return Promise.resolve([
                    {
                        partNumber: "MOBILE FEE",
                        description: "MOBILE FEE",
                        partType: "FEE",
                        laborAmount: 49.99,
                        sellingPrice: 0,
                        kitPrice: 0,
                    },
                ]);
            }

            if (actionName === mockStoreActionGetServiceabilityDetails) {
                return Promise.resolve({
                    isGlassServiceableInshop: true,
                    isRecalibrationServiceableInshop: true,
                    isGlassServiceableMobile: true,
                    isRecalibrationServiceableMobile: true,
                });
            }

            if (actionName === mockStoreActionGetShopTimeSlots) {
                if (request.providerNumber == "0000001") {
                    return Promise.resolve(mockGetShopTimeSlotsGoodAvailability);
                }

                return Promise.resolve(mockGetShopTimeSlotsLowAvailability);
            }
        }),
    },
}));

describe("service-location-helper.js", () => {
    describe("getPricedMobileFeePart", () => {
        it("Should return null if no service zip code is passed in", async () => {
            // Arrange
            const serviceZipCode = null;
            const damageType = "Replace";
            const parentAccountNumber = 167132;
            const billToAccountNumber = 1234;
            const expected = null;

            // Act
            const result = await getPricedMobileFeePart(
                serviceZipCode,
                damageType,
                parentAccountNumber,
                billToAccountNumber
            );

            // Assert
            expect(result).toEqual(expected);
        });

        it("Should return the priced mobile fee part", async () => {
            // Arrange
            const serviceZipCode = "43235";
            const damageType = "Replace";
            const parentAccountNumber = 167132;
            const billToAccountNumber = 1234;

            const expected = {
                partNumber: "MOBILE FEE",
                description: "MOBILE FEE",
                partType: "FEE",
                laborAmount: 49.99,
                sellingPrice: 0,
                kitPrice: 0,
            };

            // Act
            const result = await getPricedMobileFeePart(
                serviceZipCode,
                damageType,
                parentAccountNumber,
                billToAccountNumber
            );

            // Assert
            expect(result).toEqual(expected);
        });
    });

    describe("getServiceabilityDetails", () => {
        it("Should return the serviceability details", async () => {
            // Arrange
            const serviceZipCode = "43235";

            const expected = {
                isGlassServiceableInshop: true,
                isRecalibrationServiceableInshop: true,
                isGlassServiceableMobile: true,
                isRecalibrationServiceableMobile: true,
            };

            // Act
            const result = await getServiceabilityDetails(serviceZipCode);

            // Assert
            expect(result).toEqual(expected);
        });
    });

    describe("getAvailabilityRating", () => {
        it("Should return a 'high' rating", async () => {
            // Arrange
            const providerNumber = "0000001";
            const expected = "high";
            // Act
            const result = await getAvailabilityRating(
                "2023-06-30",
                "2023-07-06",
                "Inshop",
                providerNumber
            );

            // Assert
            expect(result).toEqual(expected);
        });

        it("Should return a 'low' rating", async () => {
            // Arrange
            const providerNumber = "0000000";
            const expected = "low";
            // Act
            const result = await getAvailabilityRating(
                "2023-06-30",
                "2023-07-06",
                "Inshop",
                providerNumber
            );

            // Assert
            expect(result).toEqual(expected);
        });
    });
});
