import { queryStrings } from "@/constants/query-strings";
import { getQuerystringParameter } from "@/helpers/querystring-helper";
import { externalUrls } from "@/router/router-constants/externalUrl-values";
import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js";
import { saveSession } from "@/helpers/heritage-integration/order-helper.js";
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
import { storeActions } from "@/constants/store-actions.js";
import { settleAllPromises } from "@/helpers/layout-helper";
import experimentMixin from "@/mixins/experiment-mixin";
import { experimentSettings } from "@/constants/experiments";
import { includesWindshieldReplacement } from "@/helpers/damage-helper";
import { applicationConfig } from "@/constants/application-config.js";
import store from "@/store";
import router from "@/router";

export async function getPageToRouteExistingOrderTo(toRoute = {}) {
    const fmgQueryPage = toRoute.query[queryStrings.FMG_PAGE];
    const hasFmgQueryPage = !!fmgQueryPage;

    if (hasFmgQueryPage) {
        return await getDirectNavigation(toRoute);
    } else {
        return await getImplicitNavigation(toRoute);
    }
}

/*
 * Send the user to the specified page, except in specific scenarios.
 */
export async function getDirectNavigation(toRoute) {
    const fmgPageValue = toRoute.query[queryStrings.FMG_PAGE];

    // Verified insurance users need to be routed around some pages.  Same goes for C&C unverified 6 digit referrals
    // vehicle -> vehicle-damage
    // quote -> vin-lookup/estimate
    // insurance-company -> vin-lookup/estimate
    if (
        store.getters.payment?.insuranceCoverage?.isVerified ||
        store.getters.order?.referralNumber?.length === 6
    ) {
        if (fmgPageValue === fmgPageValues.VEHICLE) {
            return fmgPageValues.VEHICLE_DAMAGE;
        }

        if (fmgPageValue === fmgPageValues.QUOTE) {
            const skipVin = await skipVinLookup();

            if (skipVin || !store.getters.vehicle?.vin) {
                return fmgPageValues.ESTIMATE;
            } else {
                return fmgPageValues.VIN_LOOKUP;
            }
        }
    }

    // Otherwise, respect navigation from query string.
    return fmgPageValue;
}

/*
 * Determine which page in the flow the user should be sent to, based on their current order.
 * General strategy: run through pages in reverse order, and select first where prerequisites are valid.
 * QUOTE is the latest page to send to.
 */
export async function getImplicitNavigation(toRoute) {
    const vehicleDamageComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_DAMAGE);
    const estimateComponent = await getLazyLoadedComponent(fmgPageValues.ESTIMATE);
    const vinLookupComponent = await getLazyLoadedComponent(fmgPageValues.VIN_LOOKUP);
    const partQuestionsComponent = await getLazyLoadedComponent(fmgPageValues.PART_QUESTIONS);
    const vehiclePartsComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_PARTS);
    const moldingQuestionsComponent = await getLazyLoadedComponent(fmgPageValues.MOLDING_QUESTIONS);
    const capabilityQuestionsComponent = await getLazyLoadedComponent(
        fmgPageValues.CAPABILITY_QUESTIONS
    );
    const quoteComponent = await getLazyLoadedComponent(fmgPageValues.QUOTE);

    const skipVin = await skipVinLookup();

    if (store.getters.order.payment.insuranceCoverage?.isVerified) {
        return fmgPageValues.HERITAGE;
    }

    if (quoteComponent.methods.arePagePrerequisitesValid()) {
        // Do not send to quote if verified insurance user.
        if (store.getters.requiresVerifiedRedirecting) {
            return fmgPageValues.HERITAGE;
        } else {
            return fmgPageValues.QUOTE;
        }
    } else if (capabilityQuestionsComponent.methods.arePagePrerequisitesValid()) {
        return fmgPageValues.CAPABILITY_QUESTIONS;
    } else if (moldingQuestionsComponent.methods.arePagePrerequisitesValid()) {
        return fmgPageValues.MOLDING_QUESTIONS;
    } else if (vehiclePartsComponent.methods.arePagePrerequisitesValid()) {
        return fmgPageValues.VEHICLE_PARTS;
    } else if (partQuestionsComponent.methods.arePagePrerequisitesValid()) {
        return fmgPageValues.PART_QUESTIONS;
    } else if (vinLookupComponent.methods.arePagePrerequisitesValid() && !skipVin) {
        return fmgPageValues.VIN_LOOKUP;
    } else if (estimateComponent.methods.arePagePrerequisitesValid()) {
        return fmgPageValues.ESTIMATE;
    } else if (vehicleDamageComponent.methods.arePagePrerequisitesValid()) {
        return fmgPageValues.VEHICLE_DAMAGE;
    } else {
        return fmgPageValues.VEHICLE;
    }
}

/*
    Used to navigate to the heritage funnel with the correct query string and url.
*/

export async function navigateToHeritageFunnel({ shouldSaveSession, pageNameToLog, navType }) {
    const log = getQuerystringParameter(queryStrings.LOG);
    if (log === "true") {
        console.log("------------- Navigate to heritage start -----------------");
        console.log(new Date() + " applicationConfig: " + JSON.stringify(applicationConfig));
        console.log(new Date() + " navigateToHeritageFunnel: " + applicationConfig.HERITAGE_FUNNEL);
        console.log("------------- Navigate to heritage end -----------------");
    }

    // Create the order (or save existing order) when navigating to Heritage Funnel.
    if (shouldSaveSession) {
        await saveSession({ pageNameToLog: pageNameToLog, shouldAwaitSaveSessionQueue: true });
    }

    var heritageParms = {
        corid: store.getters.order.referralCorrelationId,
        src: "concept-funnel",
        conceptsqid: store.getters.applicationUser.savedSessionId,
        isInsurance: store.getters.payment.isInsurance,
    };

    const promo = getQuerystringParameter(queryStrings.PROMO);

    if (promo) {
        heritageParms["promo"] = promo;
    }

    if (navType) {
        heritageParms["navType"] = navType;
    }

    if (
        (process.env.VUE_APP_HERITAGE_FUNNEL.includes("fixmyglasstest") &&
            process.env.VUE_APP_CURRENT_ENVIRONMENT === "Localhost") ||
        (process.env.VUE_APP_HERITAGE_FUNNEL.includes("fixmyglassdev") &&
            process.env.VUE_APP_CURRENT_ENVIRONMENT === "Localhost") ||
        (process.env.VUE_APP_HERITAGE_FUNNEL.includes("localhost") &&
            process.env.VUE_APP_CURRENT_ENVIRONMENT === "Localhost")
    ) {
        heritageParms["forceEndToEndInsurance"] = true;
    }

    // clear the heritage session that may still exist after an order was already submitted
    if (window.sessionStorage.getItem("createNewSessionForHeritage") !== null) {
        heritageParms["cns"] = "all";
        window.sessionStorage.removeItem("createNewSessionForHeritage");
    }

    router.navigateToExternalUrl(applicationConfig.HERITAGE_FUNNEL, heritageParms);
}

export async function skipVinLookup() {
    if (store.getters.damage.isRepair) {
        return true;
    }
    const isVinOptionalVehicle = store.getters.order.vehicle.make
        ? await store.dispatch(storeActions.IS_VIN_OPTIONAL_VEHICLE)
        : false;

    return (
        isVinOptionalVehicle ||
        !includesWindshieldReplacement() ||
        experimentMixin.methods.hasSettingEqualTo(experimentSettings.SUPPRESS_VIN_CAPTURE, "true")
    );
}

export async function skipVinLookupNotRepair() {
    if (store.getters.damage.isRepair) {
        return false;
    }

    const isVinOptionalVehicle = store.getters.order.vehicle.make
        ? await store.dispatch(storeActions.IS_VIN_OPTIONAL_VEHICLE)
        : false;

    return (
        isVinOptionalVehicle ||
        !includesWindshieldReplacement() ||
        experimentMixin.methods.hasSettingEqualTo(experimentSettings.SUPPRESS_VIN_CAPTURE, "true")
    );
}

async function getLazyLoadedComponent(pageName) {
    return (await lazyLoadComponent(pageName)()).default;
}
