<template>
  <div
    role="form"
    class="call-me"
    :class="{
      hasLightTheme,
      'shake-horizontal': hasPhoneError || hasLegalError,
    }"
  >
    <ma-stack space="xsmall">
      <ma-text-field
        v-model="phoneNumber"
        class="call-me-input"
        :title="$t('pattern')"
        :placeholder="placeholder || $t('placeholder')"
        :label="computedLabel"
        :aria-label="!computedLabel && $t('label')"
        :has-error="hasPhoneError"
        :tone="hasLightTheme ? 'white' : 'gray-dark'"
        error-message=""
        type="tel"
      >
        <template #inputSibling>
          <ma-button
            :loading="isLoading"
            :aria-label="$t('textButton')"
            role="button"
            class="btn"
            tabindex="0"
            @click="onClickCallMe"
            :text="buttonText"
            :icon="buttonText || isLoading ? '' : 'Phone'"
          />
        </template>
      </ma-text-field>
      <ma-option
        v-if="!isSuccessful"
        v-model="hasAcceptedLegal"
        :class="{ 'error-checkbox': hasLegalError }"
        type="checkbox"
        :tone="hasLightTheme ? 'white' : 'gray'"
        size="xsmall"
      >
        <privacy-modal>
          <template #default="{ openModal }">
            <i18n class="description" tag="span" path="policyPrivacy.text">
              {{ $t('policyPrivacy.text') }}
              <a
                slot="link"
                class="hl-link"
                @click.prevent="openModal"
                v-text="$t('policyPrivacy.linkText')"
              />
            </i18n>
            <error-icon v-if="hasLegalError" :has-light-theme="hasLightTheme" />
          </template>
        </privacy-modal>
      </ma-option>
      <ma-alert v-if="isSuccessful" class="success" tone="green">
        {{ $t('successMessage') }}
      </ma-alert>
    </ma-stack>
  </div>
</template>

<script lang="ts">
import {
  isValidPhone,
  phoneMatchLength,
} from '@kalimotxo/ui/utils/validate-phone'
import PrivacyModal from '../PrivacyModal/PrivacyModal.vue'
import ErrorIcon from './_components/ErrorIcon.vue'
import { dataLayerPush } from '@kalimotxo/ui/utils/push-event'
import { TranslateResult } from 'vue-i18n'
import { handleCreatePhoneLead } from '@kalimotxo/application/CallMe/createPhoneLead'

export default {
  name: 'CallMe',

  components: { ErrorIcon, PrivacyModal },

  props: {
    businessUnit: { type: String, default: 'electricity' },

    eventCategory: { type: String, required: true },

    eventLabel: { type: String, required: true },

    buttonText: { type: String, default: '' },

    hasLightTheme: { type: Boolean, default: false },

    label: { type: String, default: 'default' },

    owner: { type: String, default: '17838303' },

    calendarId: { type: String, default: '' },

    placeholder: { type: String, default: '' },

    url: { type: String, default: '' },
  },

  data() {
    return {
      phoneNumber: '',
      hasPhoneError: false,
      isLoading: false,
      isSuccessful: false,
      hasAcceptedLegal: false,
      hasLegalError: false,
    }
  },

  computed: {
    computedPhoneNumber(): string {
      return this.phoneNumber.replace(/\s/g, '')
    },

    computedLabel(): TranslateResult {
      return this.label === 'default' ? this.$t('label') : this.label
    },

    getUrl(): string {
      return this.url
        ? this.url
        : `${location?.protocol}//${location?.host}${location?.pathname}`
    },
  },

  watch: {
    phoneNumber() {
      this.hasPhoneError = this.hasLegalError = false
    },
  },

  methods: {
    onClickCallMe() {
      this.hasLegalError = !this.hasAcceptedLegal
      this.validatePhone()
      if (this.hasPhoneError || this.hasLegalError) {
        dataLayerPush({
          event: 'gaEvent',
          eventAction: this.hasPhoneError ? 'Error num' : 'Error check',
          eventCategory: this.eventCategory,
          eventLabel: this.eventLabel,
        })
        return
      }
      dataLayerPush({
        event: 'gaEvent',
        phone_number: `+34${this.phoneNumber}`,
      })
      this.$emit('submitted')
      this.createPhoneLead()
    },

    async isCallMeBack() {
      // TODO: There's something weird, here. Are we either returning a Boolean
      // or a Promise<Boolean>?
      const workTime = await this.$isWorkTime
      return !workTime[this.businessUnit as keyof typeof workTime]
    },

    async createPhoneLead() {
      this.isLoading = true
      const isCallMeBack = await this.isCallMeBack()

      try {
        await handleCreatePhoneLead().execute(
          {
            phone: this.computedPhoneNumber,
            url: this.getUrl,
            isCallMeBack: isCallMeBack,
            businessUnit: this.businessUnit,
          },
          {
            respondWithSuccess: () => {
              this.sendGtmEvent(isCallMeBack)
              this.onPhoneLeadCreated()
            },
            respondWithError: () => {
              this.hasPhoneError = true
            },
          },
        )
      } catch (e) {
        this.hasPhoneError = true
      }
      this.isLoading = false
    },

    onPhoneLeadCreated() {
      const NOTIFICATION_TIME_MS = 3000
      this.hasLegalError = this.hasAcceptedLegal = false
      this.isSuccessful = true
      this.phoneNumber = ''

      setTimeout(() => {
        this.isSuccessful = false
      }, NOTIFICATION_TIME_MS)
    },

    sendGtmEvent(isCallMeBack: boolean): void {
      const event = {
        event: 'gaEvent',
        eventAction: isCallMeBack ? 'Llamadme(CMB)' : 'Llamadme(CMN)',
        eventCategory: this.eventCategory,
        eventLabel: this.eventLabel,
        businessUnit: this.businessUnit,
        phone_number: this.computedPhoneNumber,
        url: this.getUrl,
        trigger: 'submit',
      }
      dataLayerPush(event)
    },

    validatePhone() {
      this.hasPhoneError =
        !phoneMatchLength(this.computedPhoneNumber) ||
        !isValidPhone(this.computedPhoneNumber)
    },
  },
  i18n: {
    messages: {
      es: {
        textButton: 'Llamadme',
        pattern: 'Sólo números y espacios',
        placeholder: 'Escribe tu número de teléfono',
        label: 'Si lo prefieres, te llamamos gratis',
        imageAlt: 'Teléfono',
        successMessage: '¡Recibido! Ahora mismo te llamamos',
        policyPrivacy: {
          text: 'Acepto recibir {link}. ',
          linkText: 'comunicaciones comerciales',
        },
      },
      ca: {
        textButton: 'Truqueu-me',
        pattern: "Només s'accepten dígits i espais",
        placeholder: 'Escriu el teu número de telèfon',
        label: 'Si ho prefereixes, et truquem',
        imageAlt: 'Telèfon',
        successMessage: 'Rebut! De seguida et truquem',
        policyPrivacy: {
          text: 'Accepto rebre {link}.',
          linkText: 'comunicacions comercials',
        },
      },
      en: {
        textButton: 'Call me',
        pattern: 'Only number and spaces',
        placeholder: 'Your phone number is...',
        label: 'Or let us call you for free',
        imageAlt: 'Phone',
        successMessage: "Copy that! We'll call you right away",
        policyPrivacy: {
          text: 'I agree to receive {link}.',
          linkText: 'commercial information',
        },
      },
    },
  },
}
</script>

<style src="./CallMe.css" scoped></style>
