<template>
  <Form
    @submit="onSubmit"
    @invalid-submit="onInvalidSubmit"
    ref="theForm"
    v-slot="{ meta }"
  >
    <div
      class="container-fluid shadow rounded-3 p-2 position-relative make-tall px-5"
    >
      <funnelHeader cmsWidgetName="FunnelHeaderWidget" />
      <vehicleBanner
        cmsWidgetName="VehicleBannerWidget"
        :displayGenericVehicleImage="false"
      />
      <funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
      <div class="row my-2">
        <div class="col">
          <textboxQuestion
            cmsWidgetName="VinNumber"
            v-model="vin"
            inputId="vin"
            isRequired
            disableAutoFill
            validationRules="vin-required|vin-format"
            :isDisabled="isVinFieldReadOnly"
          />
        </div>
      </div>
      <div class="row my-2">
        <div class="col">
          <vinInformation />
        </div>
      </div>
      <div class="row my-2">
        <div class="col">
          <textboxQuestion
            cmsWidgetName="ServiceZIP"
            v-model="zip"
            inputId="zip"
            mask="#####"
            isRequired
            disableAutoFill
            validationRules="zip-required"
          />
        </div>
      </div>
      <div class="row my-2">
        <div class="col">
          <textboxQuestion
            cmsWidgetName="EmailAddress"
            v-model="email"
            inputId="email"
            isRequired
            disableAutoFill
            validationRules="email-address-required|email-address-format"
          />
        </div>
      </div>
      <alert
        class="my-3"
        :manualHeadline="MatchedDifferentVehicleAlertHeader"
        :manualCopy="MatchedDifferentVehicleAlertBody"
        v-model="customAlertData"
        v-if="isCarIdDifferent"
        alertClass="alert-danger"
      />
      <alert
        class="my-3"
        :manualHeadline="NoServiceZipHeader"
        :manualCopy="NoServiceZipBody"
        v-model="customAlertData"
        v-if="noServiceZip"
        alertClass="alert-warning"
      />
      <alert
        class="my-3"
        v-model="customAlertData"
        v-if="vinNotFound"
        alertClass="alert-warning"
        cmsWidgetName="VinNotFound"
      />
      <alert
        class="my-3"
        v-model="customAlertData"
        v-if="perfectMatchNewVinAlert"
        alertClass="alert-success"
        cmsWidgetName="PerfectMatchNewVinAlert"
      />
      <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 textboxQuestion from "@/common-components/textbox-question/textbox-question";
import vinInformation from "@/layouts/vin-lookup/vin-information/vin-information";

// Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import store from "@/store";
import baseMixin from "@/mixins/base-mixin.js";
import { storeActions } from "@/constants/store-actions";
import { storeMutations } from "@/constants/store-mutations";
import { errorMessages } from "@/constants/error-messages";
import { getDamageString, isGlassAvailableForCarId } from "@/helpers/damage-helper";
import { required, regex } from "@/helpers/validation-rules";
import { Form, defineRule } from "vee-validate";
import { navigateAfterSaveToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";

// DEFINE VALIDATION RULES
defineRule("zip-required", required(errorMessages.ZIP_REQUIRED));
defineRule(
  "email-address-required",
  required(errorMessages.EMAIL_ADDRESS_REQUIRED)
);
defineRule(
  "email-address-format",
  regex(
    /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+).([a-zA-Z]{2,})$/,
    errorMessages.EMAIL_ADDRESS_FORMAT
  )
);
defineRule("vin-required", required(errorMessages.VIN_REQUIRED));
defineRule(
  "vin-format",
  regex(/^[A-HJ-NPR-Z0-9]{17}$/, errorMessages.VIN_FORMAT)
);

export default {
  name: "vin-lookup",
  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);
    });
  },
  data() {
    return {
      isCarIdDifferent: false,
      noServiceZip: false,
      vinNotFound: false,
      vin: this.getVinFromStore(),
      zip: this.getZipFromStore(),
      email: this.getEmailFromStore(),
      customAlertData: {},
      previouslyEnteredCarId: '',
      invalidZip: '',
      vinPopulatedOnPageLoad: this.getVinFromStore()?.length > 0,
    };
  },
  computed: {
    perfectMatchNewVinAlert() {
      return this.vinPopulatedOnPageLoad && this.vin === this.getVinFromStore();
    },
    MatchedDifferentVehicleAlertHeader(){
      const text = this.getCmsContent("MatchedDifferentVehicle",
      "HeadlineText").replaceAll("{custom:damage}", getDamageString());

      return text;
    },
    MatchedDifferentVehicleAlertBody(){
      const text = this.getCmsContent("MatchedDifferentVehicle",
        "BodyText").replaceAll("{custom:damage}", getDamageString()).replaceAll("{custom:vinlookupYear}", this.customAlertData?.vehicleInfo?.year).replaceAll("{custom:vinlookupMake}", this.customAlertData?.vehicleInfo?.make).replaceAll("{custom:vinlookupModel}",
        this.customAlertData?.vehicleInfo?.model);

      return text;
    },
    NoServiceZipHeader(){
      const text = this.getCmsContent("NoServiceZipWidget", "HeadlineText").replaceAll("{custom:serviceZip}", this.invalidZip);

      return text;
    },
    NoServiceZipBody(){
      return this.getCmsContent("NoServiceZipWidget", "BodyText");
    },
    PerfectMatchNewVinAlertHeader() {
      return this.getCmsContent("PerfectMatchNewVinAlert", "HeadlineText");
    },
    PerfectMatchNewVinAlertBody() {
      return this.getCmsContent("PerfectMatchNewVinAlert", "BodyText").replaceAll("{custom:damage}",
      getDamageString())
    },
    isVinFieldReadOnly(){
        return this.$store.getters.payment.insuranceCoverage.isVerified;
    },
  },
  methods: {
    arePagePrerequisitesValid() {
      return store.getters.vehicle.carId !== null;
    },
    resetDependentState() {
      store.commit(storeMutations.UPDATE_REGISTRATION_ADDRESS, null);
      store.commit(storeMutations.UPDATE_REGISTRATION_CITY, null);
      store.commit(storeMutations.UPDATE_REGISTRATION_FIRST_NAME, null);
      store.commit(storeMutations.UPDATE_REGISTRATION_LAST_NAME, null);
      store.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
    },
    getEmailFromStore(){
      return store.getters.order.customer.emailAddress
    },
    getVinFromStore(){
      return store.getters.vehicle.vin
    },
    getZipFromStore(){
      return store.getters.vehicle.registration.zipCode
    },
    attachCustomEvents() {
      this.prependActionToMethod(this, this.forwardButtonAction, () => {
        this.pushEventToGA(
          this.$route.query[this.queryStrings.FMG_PAGE],
          this.GaActions.SUBMITTED,
          this.GaLabels.VINLOOKUP,
          true
        );
      });
    },
    backButtonAction() {
      this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
    },
    async forwardButtonAction() {
      const zipValidation = await this.validateZip(this.zip);
      if (!zipValidation.data.isServiceable) {
        this.customAlertData.zip = this.zip;
        this.$refs.funnelFooter.removeLoader();
        this.noServiceZip = true;
        this.invalidZip = this.zip;
        return;
      }
      const vehicleLookup = await this.lookupVehicle(this.vin).catch(() => {
        this.vinNotFound = true;
        this.$refs.funnelFooter.removeLoader();
        this.noServiceZip = false;
        return;
      });
      this.isCarIdDifferent = vehicleLookup.data.carId !== store.getters.vehicle.carId;

      if (this.isCarIdDifferent && (vehicleLookup.data.carId !== this.previouslyEnteredCarId)) {
        this.previouslyEnteredCarId = vehicleLookup.data.carId;
        this.noServiceZip = false;
        this.customAlertData.vehicleInfo = vehicleLookup.data;
        this.$refs.funnelFooter.updateButtonText(`Continue with ${vehicleLookup.data.year} ${vehicleLookup.data.make} ${vehicleLookup.data.model}`);
        this.isVinValid = true;
        this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vehicleLookup.data.carId);
        this.$refs.funnelFooter.removeLoader();
        this.isCarIdDifferent = true;
        return;
      }
      this.updateStore(vehicleLookup.data);
      this.navigateForward();
    },
    navigateForward(){
        if(this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle){
            this.$router.navigateAfterSave(this.navigationScenarios.CLICKED_FORWARD, this.$route, {}, { displayVehicleChangeAlert: true }, {});
            return;
        } else {
            navigateAfterSaveToHeritageFunnel(this.$route);
            return;
        }
    },
    validateZip(zip) {
      return baseMixin.methods.dispatchStoreAction(storeActions.VALIDATE_ZIP, {
        zip,
      });
    },
    lookupVehicle(vin) {
      return baseMixin.methods.dispatchStoreAction(
        storeActions.LOOKUP_VEHICLE_BY_VIN,
        { vin }
      );
    },
    updateStore(carInfo) {
      if(this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle){
          store.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
      }
      store.commit(storeMutations.UPDATE_VEHICLE_VIN, this.vin);
      store.commit(storeMutations.UPDATE_YEAR, carInfo.year);
      store.commit(storeMutations.UPDATE_MAKE, carInfo.make);
      store.commit(storeMutations.UPDATE_MODEL, carInfo.model);
      store.commit(storeMutations.UPDATE_STYLE, carInfo.style);
      store.commit(storeMutations.UPDATE_CAR_ID, carInfo.carId);
      store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, carInfo.category);
      store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, carInfo.imageUrl);
      store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, carInfo.imageVifNumber);
      store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, carInfo.imageVifNumber);
      store.commit(storeMutations.UPDATE_SERVICE_LOCATION_ZIP_CODE, this.zip);
      store.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, this.email);
    },
  },
  components: {
    Form,
    funnelHeader,
    vehicleBanner,
    funnelSubHeader,
    textboxQuestion,
    alert,
    funnelFooter,
    vinInformation,
  },
};
</script>
