<template>
  <Form
    @submit="onSubmit"
    @invalid-submit="onInvalidSubmit"
    ref="theForm"
    v-slot="{ meta }"
  >
    <div class="page-container-grouped-styles">
      <loadingModal ref="loadingModal"/>
      <funnelHeader cmsWidgetName="FunnelHeaderWidget" />
      <vehicleBanner cmsWidgetName="VehicleBannerWidget" :displayGenericVehicleImage="false" />
      <funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
      <alert
        ref="alertFoundMultipleVehicles"
        class="my-5"
        alertClass="alert-warning"
        :manualHeadline="AlertFoundMultipleVehiclesHeader"
        manualCopy=""
        v-bind:isDismissible="false"
      />
      <addressVehiclesQuestion
        ref="addressVehiclesQuestion"
        cmsWidgetName="VehicleConfirmationQuestion"
        :vehicles="VehiclesForQuestions"
        validationRules="vehicle-required"
        v-model="selectedVehicleVin"
        :isCarIdDifferent="isCarIdDifferent"
      />
      <div class="alert-provide-vin my-3" v-if="splitAlertProvideVinBodyForLink.length">
        <span v-for="copy in splitAlertProvideVinBodyForLink" :key="copy">
          <span v-if="doesCopyContainRouterLink(copy)" class="text-body">
            <router-link :to="{query: {fmgPage: `${getRouterLinkRouteFromCopy(copy)}`}, name: 'root'}">{{ getRouterLinkDisplayTextFromCopy(copy) }}</router-link>
          </span>
          <span v-else class="m-0 text-body" v-html="copy"></span>
        </span>
      </div>
      <funnelFooter
        cmsWidgetName="FunnelFooterWidget"
        ref="funnelFooter"
        :isForwardActionDisabled="!meta.valid"
        @back-clicked="backButtonAction"
        @ForwardClicked="forwardButtonAction"
      />
    </div>
  </Form>
</template>

<script>
// Components
import funnelHeader from "@/common-components/funnel-header/funnel-header";
import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
import alert from "@/ux-components/alert/alert";
import addressVehiclesQuestion from "@/layouts/address-vehicles/address-vehicles-question/address-vehicles-question";
import loadingModal from '@/common-components/loading-modal/loading-modal.vue';

// Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import store from "@/store";
import { storeActions } from "@/constants/store-actions";
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
import { errorMessages } from "@/constants/error-messages";
import { required } from "@/helpers/validation-rules";
import { Form, defineRule } from "vee-validate";
import { isGlassAvailableForCarId } from "@/helpers/damage-helper";
import { doesCopyContainRouterLink,
         splitCopyOnCMSPlaceHolder,
         getRouterLinkRouteFromCopy,
         getRouterLinkDisplayTextFromCopy, } from "@/helpers/cms-content-helper";
import { routerParams } from "@/router/router-constants/router-params";
import vinPagesMixin from "@/mixins/vin-pages-mixin";

// DEFINE VALIDATION RULES
defineRule("vehicle-required", required(errorMessages.VEHICLE_REQUIRED));

export default {
  name: "address-vehicles",
  mixins: [vinPagesMixin],
  async beforeRouteEnter(to, from, next) {
    // Call APIs
    const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);

    // Settle promises and get results
    const promiseResultMap = [
      {
        resultKey: "cmsContent",
        promise: cmsContentPromise,
      },
    ];

    const resultMap = await settleAllPromises(promiseResultMap);

    // Call the "next" function to complete the transition to this page.
    next((vm) => {
      vm.setCmsContent(resultMap.cmsContent);
    });
  },
  props: {
    validationRules: String,
  },
  data() {
    return {
      selectedVehicleVin: "",
      isCarIdDifferent: false,
      isSelectedGlassAvailableForVehicle: true,
    };
  },
  computed: {
    vehicleCount() {
      return this.VehiclesForQuestions.length;
    },
    AlertFoundMultipleVehiclesHeader() {
			return this.getCmsContent("FoundMultipleVehicles", "HeadlineText").replaceAll("{custom:vehicleCount}", this.vehicleCount);
		},
    AlertProvideVinBody() {
			return this.getCmsContent("ProvideVinAlert", "BodyText");
		},
    splitAlertProvideVinBodyForLink() {
      // Splits content when brackets are found in text so that text can be looped through and router-link can be injected when needed
      return this.splitCopyOnCMSPlaceHolder(this.AlertProvideVinBody);
    },
    VehiclesForQuestions() {
      // Map API result data, to address-vehicles data structure
      const mappedData = this.VehiclesFromApi.map((v) => {
        const maskSymbol = "X";
        const vinStart = maskSymbol.repeat(v.vin.length - 6);
        const vinEnd = v.vin.substring(v.vin.length - 6);
        return {
          vin: v.vin,
          vehicle: v.vehicle,
          Text: v.vehicle.year + " " + v.vehicle.make + " " + v.vehicle.model,
          Name: v.vin,
          SubText: "VIN " + vinStart + vinEnd,
        };
      });

      return mappedData;
    },
    VehiclesFromApi() {
      return store.getters.pageData(fmgPageValues.ADDRESS_VEHICLES);
    },
    selectedVehicle() {
      return this.VehiclesForQuestions.find( ({ vin }) => vin === this.selectedVehicleVin );
    },
  },
  methods: {
    doesCopyContainRouterLink,
    splitCopyOnCMSPlaceHolder,
    getRouterLinkRouteFromCopy,
    getRouterLinkDisplayTextFromCopy,
    arePagePrerequisitesValid() {
        if (
            store.getters.order.vehicle.carId
            && store.getters.order.serviceLocation.zipCode
            && store.getters.order.customer.emailAddress
            && store.getters.pageData(fmgPageValues.ADDRESS_VEHICLES)
        ) {
            return true;
        }
        return false;
    },
    backButtonAction() {
      this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
    },
    async forwardButtonAction() {

      const vinLookup = await this.dispatchStoreAction(storeActions.LOOKUP_VEHICLE_BY_VIN,{ vin: this.selectedVehicle.vin })
        .catch(() => {this.$refs.funnelFooter.removeLoader();});

      if (!vinLookup) {
        return;
      }

      this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vinLookup.data.carId);

      await this.dispatchStoreAction(storeActions.SAVE_VIN, {
        vehicleInfo: Object.assign(this.selectedVehicle.vehicle, { vin: this.selectedVehicle.vin }),
        isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle
      }, false);

      return await this.navigateForward();
    },
    async navigateForward() {
      if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
        this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD,this.$route,{},{[routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true },);
      } else {
        await this.navigateForwardWithSingleCarMatch();
      }
    },
  },

  watch: {
    selectedVehicleVin: {
      handler() {
        // does this vehicle match the previously selected carId?
        this.isCarIdDifferent = this.selectedVehicle?.vehicle.carId !== store.getters.vehicle.carId;
        if (this.isCarIdDifferent) {
          this.$refs.funnelFooter.updateButtonText(`Continue with ${this.selectedVehicle.vehicle.year} ${this.selectedVehicle.vehicle.make} ${this.selectedVehicle.vehicle.model}`);
        } else {
          this.$refs.funnelFooter.updateButtonText(this.getCmsContent("FunnelFooterWidget", "ForwardButtonText"));
        }        
      },
      deep: true
    },
  },

  components: {
    Form,
    funnelHeader,
    vehicleBanner,
    funnelSubHeader,
    alert,
    funnelFooter,
    addressVehiclesQuestion,
    loadingModal,
  },
};
</script>

<style lang="scss">
  .alert-provide-vin {
    font-size: 0.875rem;
    line-height: 1.4;

    a {
      text-underline-offset: .2em;
      line-height: inherit;
    }
  }
</style>
