<template>
    <Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
        <loadingModal notFullScreen ref="loadingModal" />
        <div class="container-fluid page-container-grouped-styles">
            <div class="row">
                <div class="col">
                    <funnelHeader cmsWidgetName="FunnelHeaderWidget" />
                </div>
            </div>
            <div class="row justify-content-center">
                <div class="col-md-6 col-xl-4">
                    <vehicleBanner
                        cmsWidgetName="VehicleBannerWidget"
                        :displayGenericVehicleImage="false" />

                    <funnelSubHeader
                        class="mb-5 mt-4"
                        cmsWidgetName="FunnelSubHeaderWidget"
                        leftAlignHeader />

                    <p v-if="isPiaDisabled" class="fw-normal no-pia-disclaimer">
                        <span>{{ noPiaDisclaimer }}</span>
                    </p>

                    <hr />

                    <cart
                        :damage="damageInfo"
                        :availableLineItems="availableLineItems"
                        :lineItems="taxedLineItems"
                        servicePackageOptionsCmsName="ServicePackageTitle"
                        @cart-remove="cartRemove" />

                    <div>
                        <alert
                            ref="piaErrorAlert"
                            class="my-4"
                            v-if="displayPiaAlert"
                            cmsWidgetName="PIAErrorAlertWidget"
                            alertClass="alert-danger"
                            v-bind:isDismissible="false" />
                    </div>

                    <add-vaps-modal-buttons
                        v-model="lineItems"
                        :availableLineItems="availableLineItems"
                        vapsTilesCmsName="VapsProductTiles" />

                    <paymentMethodQuestion
                        v-if="!isPiaDisabled"
                        v-model="paymentMethodInternalModel"
                        validationRules="option-required" />

                    <navbar
                        cmsWidgetName="FunnelFooterWidget"
                        ref="navbar"
                        :isForwardActionDisabled="!meta.valid"
                        :isBackButtonHidden="shouldHideBackButton"
                        @back-clicked="backButtonAction"
                        @ForwardClicked="forwardButtonAction" />
                </div>
            </div>
        </div>
    </Form>
</template>

<script>
// Components
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
import navbar from "@/fmg-components/nav-bar/nav-bar";
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
import paymentMethodQuestion from "@/layouts/payment-method/payment-method-question/payment-method-question";
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
import cart from "@/fmg-components/cart/cart";
import addVapsModalButtons from "./add-vaps-modal-buttons/add-vaps-modal-buttons";
import { submitWorkOrder } from "@/helpers/heritage-integration/order-helper.js";
import alert from "@/ux-components/alert/alert";

// Supporting Items
import baseMixin from "@/mixins/base-mixin.js";
import { settleAllPromises } from "@/helpers/layout-helper";
import { storeActions } from "@/constants/store-actions";
import store from "@/store";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { paymentMethods } from "@/constants/payment-method-constants";
import { experimentSettings } from "@/constants/experiments";

import { Form } from "vee-validate";
import { defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
import { AppointmentTypeStrings } from "@/constants/schedule-constants";

defineRule("option-required", required(errorMessages.OPTION_REQUIRED));

export default {
    name: "paymentMethod",
    async beforeRouteEnter(to, from, next) {
        // Call APIs
        const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
        const wipersPromise = baseMixin.methods.dispatchStoreActionWithLogging(
            storeActions.GET_WIPERS,
            null,
            "payment-method"
        );

        const rainDefensePromise = baseMixin.methods.dispatchStoreActionWithLogging(
            storeActions.GET_RAIN_DEFENSE,
            null,
            "payment-method"
        );

        const supportingItemsPromise = baseMixin.methods.dispatchStoreActionWithLogging(
            storeActions.GET_SUPPORTING_ITEMS,
            null,
            "payment-method"
        );

        const promiseResultMap = [
            {
                resultKey: "cmsContent",
                promise: cmsContentPromise,
            },
            {
                resultKey: "wipers",
                promise: wipersPromise,
            },
            {
                resultKey: "rainDefense",
                promise: rainDefensePromise,
            },
            {
                resultKey: "supportingItems",
                promise: supportingItemsPromise,
            },
        ];

        const resultMap = await settleAllPromises(promiseResultMap);

        const glassParts = store.getters.order.lineItems.glassParts ?? [];

        const availableLineItems = [
            resultMap.rainDefense,
            ...resultMap.supportingItems,
            ...resultMap.wipers,
            ...glassParts,
        ];

        const pricedAvailableLineItems = await baseMixin.methods.dispatchStoreActionWithLogging(
            storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
            {
                availableLineItems: availableLineItems,
            },
            "payment-method",
            false
        );

        const lineItems = store.getters.order.lineItems;

        const combinedLineItems = [];
        combinedLineItems.push(lineItems.glassParts ?? []);
        combinedLineItems.push(lineItems.supportingItems ?? []);
        combinedLineItems.push(lineItems.vaps ?? []);

        const taxedLineItems = await baseMixin.methods.dispatchStoreActionWithLogging(
            storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
            {
                billToAccountNumber: "87291",
                providerNumber: store.getters.order.serviceLocation.provider.providerNumber,
                appointmentType: store.getters.order.serviceLocation.appointmentType,
                serviceLocationState: store.getters.order.serviceLocation.state,
                serviceLocationZipCode: store.getters.order.serviceLocation.zipCode,
                pricedLineItems: combinedLineItems,
            },
            "payment-method",
            false
        );

        // Call the "next" function to complete the transition to this page.
        next((vm) => {
            vm.cartItems = combinedLineItems; // TOBEREMOVED BY AJC IN CSR-1384

            vm.setCmsContent(resultMap.cmsContent);
            vm.availableLineItems = pricedAvailableLineItems;
            vm.taxedLineItems = taxedLineItems;
            vm.lineItems = lineItems;
        });
    },
    data() {
        return {
            cartItems: [], // TOBEREMOVED BY AJC IN CSR-1384

            lineItems: [],
            taxedLineItems: [], // temporary, for use by cart.vue
            availableLineItems: [],
            paymentMethodInternalModel: this.getPaymentMethodFromStore(),
            displayPiaAlert: this.getPiaAlert(),
        };
    },
    methods: {
        arePagePrerequisitesValid() {
            // Line Items
            const packageReqs = !!store.getters.order.lineItems.supportingItems;

            // Service Location
            const serviceLocation = store.getters.order.serviceLocation;
            const mobileReqs = !!(
                serviceLocation.address &&
                serviceLocation.city &&
                serviceLocation.state &&
                serviceLocation.zipCode
            );

            const providerLocation = serviceLocation.provider.address;
            const dropOffInshopReqs = !!(
                providerLocation.streetAddress &&
                providerLocation.city &&
                providerLocation.state &&
                providerLocation.zipCode
            );

            const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE;

            const serviceLocationReqs =
                (isMobile && mobileReqs) || (!isMobile && dropOffInshopReqs);

            // Insurance
            const isInsuranceSet = store.getters.order.payment.isInsurance !== null;

            // Schedule
            const schedule = store.getters.order.schedule;
            const scheduleReqs = !!(
                schedule.date &&
                schedule.startTime &&
                (!isMobile || schedule.endTime) &&
                schedule.jobMaxMinutes &&
                schedule.jobMinMinutes
            );

            // Customer
            const customer = store.getters.order.customer;
            const customerReqs = !!(
                customer.firstName &&
                customer.lastName &&
                customer.phoneNumber &&
                customer.emailAddress
            );

            return (
                packageReqs && serviceLocationReqs && isInsuranceSet && scheduleReqs && customerReqs
            );
        },
        getPiaAlert() {
            return store.getters.order.payment.piaErrorCode ? true : false;
        },
        getPaymentMethodFromStore() {
            const isPia = store.getters.order.payment.isPia;

            if (isPia === null || isPia === undefined) {
                return null;
            }

            if (isPia) {
                return store.getters.order.payment.piaType;
            } else {
                return paymentMethods.LATER;
            }
        },
        cartRemove(item) {
            const matchedIndices = [];
            this.cartItems.forEach((cartItem, i) => {
                if (cartItem.partType === item.partType) {
                    // console.log("adding this to matchedIndices: ", i);
                    matchedIndices.push(i);
                }
            });
            this.cartItems = this.cartItems.filter((cartItem, index) => {
                return cartItem.partType !== item.partType;
            });
        },
        backButtonAction() {
            this.dispatchStoreAction(storeActions.SAVE_PIA_ERROR_CODE, null, false);
            this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
        },
        async forwardButtonAction() {
            switch (this.paymentMethod) {
                case paymentMethods.CREDIT_CARD:
                    this.piaSetup("cc");
                    break;
                case paymentMethods.PAYPAL:
                    this.piaSetup("pp");
                    break;
                case paymentMethods.AFTERPAY:
                    this.piaSetup("ap");
                    break;
                default:
                    this.dispatchStoreAction(storeActions.SAVE_PIA_ERROR_CODE, null, false);
                    this.dispatchStoreAction(this.storeActions.SAVE_WORK_ORDER_FLAG, true, false);
                    this.dispatchStoreAction(
                        storeActions.SAVE_PAYMENT_METHOD_CHOICE,
                        this.paymentMethod,
                        false
                    );
                    await submitWorkOrder({ pageNameToLog: "payment-method" });
                    this.$router.navigateWithoutSaving(
                        this.navigationScenarios.CLICKED_FORWARD,
                        this.$route
                    );
            }
        },
        async piaSetup(payNowType) {
            this.$refs.loadingModal.showModal();

            // since we're leaving the site for pia, clear any save session promises that we will not be able to resolve when we return
            await this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE);
            await this.dispatchStoreAction(
                storeActions.SAVE_PAYMENT_METHOD_CHOICE,
                payNowType,
                false
            );

            // make sure pia error codes are reset
            this.dispatchStoreAction(storeActions.SAVE_PIA_ERROR_CODE, null, false);

            // if we don't have a work order in delete substatus, set the flag and submit
            if (!store.getters.order.workOrderNumber) {
                this.dispatchStoreAction(storeActions.SAVE_PIA_WORK_ORDER, true);
                await submitWorkOrder({ pageNameToLog: "payment-method" });
                this.dispatchStoreAction(storeActions.SAVE_PIA_WORK_ORDER, false);
            }

            this.$router.navigateWithoutSaving(
                this.navigationScenarios.CLICKED_PAY_NOW,
                this.$route
            );
        },
    },
    computed: {
        damageInfo() {
            return this.$store.getters.damage;
        },
        noPiaDisclaimer() {
            return this.getCmsContent("NoPiaDisclaimerWidget", "Text");
        },
        customCtaCopy() {
            switch (this.paymentMethod) {
                case paymentMethods.CREDIT_CARD:
                    return "Continue to checkout";
                case paymentMethods.PAYPAL:
                    return "Continue to Paypal";
                case paymentMethods.AFTERPAY:
                    return "Continue to Afterpay";
                default:
                    return null;
            }
        },
        isPiaDisabled() {
            const piaExperience =
                this.getSettingValue(experimentSettings.PIA_EXPERIENCE) === "PIA Optional";
            const enablePIA =
                this.getSettingValue(experimentSettings.SUBMIT_ORDER_ENABLE_PIA) === "true";

            return false;
            //return !(piaExperience && enablePIA);
        },
        paymentMethod() {
            if (this.isPiaDisabled) {
                return paymentMethods.LATER;
            }

            return this.paymentMethodInternalModel;
        },
    },
    watch: {
        customCtaCopy(newValue) {
            this.$refs.navbar.updateButtonText(newValue);
        },
    },
    components: {
        funnelHeader,
        navbar,
        funnelSubHeader,
        Form,
        loadingModal,
        cart,
        alert,
        addVapsModalButtons,
        paymentMethodQuestion,
    },
};
</script>

<style lang="scss" scoped>
.no-pia-disclaimer {
    color: $gray-550;
    margin: 0;
}
</style>
