import { useMainStore } from '@/store';
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
import settleAllPromises from '@/helpers/layout-helper';

function processZipCodeResults(request) {
    return request.then((serviceZipValidationResponse) => ({
        containsMilitaryBase: serviceZipValidationResponse.containsMilitaryBase,
        isValid: serviceZipValidationResponse.isValid,
        isServiceable: serviceZipValidationResponse.isServiceable,
        city: serviceZipValidationResponse.city,
        state: serviceZipValidationResponse.state,
        zipCodeCtu: serviceZipValidationResponse.zipCodeCtu
    })).catch(() => ({
        isValid: false
    }));
}

export async function getAvailabilityRating(
    startDate,
    endDate,
    shopAppointmentType,
    providerNumber
) {
    // For a given shop provider number and date range, get the appointment time slots available
    const shopTimeSlots = await useMainStore().getShopTimeSlots(startDate, endDate, shopAppointmentType, providerNumber);

    const numberOfDaysToEvaluate = 2;
    const isGoodAvailability =
        shopTimeSlots.data.days.filter((x) => x.timeSlots.length > 0).length
        >= numberOfDaysToEvaluate;

    const shopStatus = isGoodAvailability ? 'high' : 'low';

    return Promise.resolve(shopStatus);
}

export async function getMobileZipCodeData(zipCode) {
    return await processZipCodeResults(useMainStore().validateMobileZip({ zip: zipCode }));
}

export async function getPricedMobileFeePart(serviceZipCode) {
    if (!serviceZipCode) {
        return Promise.resolve(null);
    }

    // Get the Mobile Fee Part
    const mobileFeePart = await useMainStore().getMobileFeePart();

    if (mobileFeePart?.data == null || mobileFeePart.data === '') {
        return Promise.resolve(null);
    }

    // Get the Mobile Fee Part Price
    const pricingResults = await useMainStore()
        .getCombinedQuote([mobileFeePart.data]);

    return Promise.resolve(pricingResults[0]);
}

export function getProviderData() {
    const mainStore = useMainStore();
    const storeServiceLocation = mainStore.order.serviceLocation;
    const storeSelectedAppointmentType = storeServiceLocation?.appointmentType;
    const isMobileAppointment = storeSelectedAppointmentType === AppointmentTypeStrings.MOBILE
        || storeSelectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
    const storeSelectedProvider = storeServiceLocation?.provider;
    const serviceZipCode = storeServiceLocation?.zipCode || mainStore.order.customer.address.zipCode;

    return { storeServiceLocation, isMobileAppointment, storeSelectedProvider, serviceZipCode }
}

export async function getZipCodeData(zipCode) {
    return await processZipCodeResults(useMainStore().validateZip({ zip: zipCode }));
}

export function mapTimeSlot(timeSlot, timeOfDay) {
    return {
        ...timeSlot,
        isDropoff: timeSlot.id.endsWith('DROP OFF'),
        timeOfDay
    };
}

export async function onProviderChanged() {
    const { isMobileAppointment, storeSelectedProvider, serviceZipCode } = getProviderData();
    if (!storeSelectedProvider) {
        return;
    }

    const mainStore = useMainStore();

    await mainStore.getBillToInfo(storeSelectedProvider.providerNumber);
    const promiseResultMap = [
        {
            resultKey: 'glassFees',
            promise: mainStore.getGlassFees()
                .then(async (glassFees) => await mainStore.getCombinedQuote(glassFees.data))
                .then(async (quotedGlassFees) => mainStore.updateGlassFees(quotedGlassFees))
        },
    ];

    if (isMobileAppointment && (mainStore.isNoComp || mainStore.isITAC)) {
        promiseResultMap.push({
            resultKey: 'priceMobileFee',
            promise: getPricedMobileFeePart(serviceZipCode).then(mobileFee => mainStore.updateMobileFee(mobileFee))
        });
    } else {
        mainStore.updateMobileFee(null);
    }

    await settleAllPromises(promiseResultMap);
}
