<template>
  <q-dialog ref="dialogRef" @hide="onDialogHide">
    <q-card class="q-dialog-plugin" style="width: 700px; max-width: 90vw">
      <DefaultDialogHeader :title="title" @close="onDialogCancel" />
      <q-form ref="formRef" @submit="onOKClick">
        <q-card-section class="row q-col-gutter-sm">
          <q-input
            v-model="form.card_number"
            :label="$t('client_payment_methods.card_number')"
            :rules="[inputRules.required, validateCardNumber]"
            :error="!!serverErrors?.card_number"
            :error-message="serverErrors?.card_number"
            :mask="cardNumberMask"
            unmasked-value
            class="col-12"
            @focus="onCardNumberFocus"
            @update:model-value="onCardNumberChange"
          >
            <template #append>
              <q-icon name="mdi-credit-card-outline" />
            </template>
          </q-input>

          <q-input
            v-model="form.holder_name"
            :label="$t('client_payment_methods.holder_name')"
            :rules="[inputRules.required]"
            :error="!!serverErrors?.holder_name"
            :error-message="serverErrors?.holder_name"
            class="col-12"
            @update:model-value="serverErrors.holder_name = null"
          />

          <q-input
            v-model="form.expiration"
            :label="$t('client_payment_methods.expiration')"
            :rules="[inputRules.required, validateExpiration]"
            :error="!!serverErrors?.expiration"
            :error-message="serverErrors?.expiration"
            mask="##/####"
            placeholder="MM/YYYY"
            class="col-md-6 col-12"
            @update:model-value="serverErrors.expiration = null"
          >
            <template #append>
              <q-icon name="mdi-calendar-outline" />
            </template>
          </q-input>

          <q-input
            v-model="form.cvv"
            :label="$t('client_payment_methods.cvv')"
            :rules="[inputRules.required]"
            :error="!!serverErrors?.cvv"
            :error-message="serverErrors?.cvv"
            mask="####"
            unmasked-value
            type="password"
            class="col-md-6 col-12"
            @update:model-value="serverErrors.cvv = null"
          >
            <template #append>
              <q-icon name="mdi-lock-outline" />
            </template>
          </q-input>

          <q-input
            v-model="form.card_name"
            :label="$t('client_payment_methods.card_name')"
            :error="!!serverErrors?.card_name"
            :error-message="serverErrors?.card_name"
            class="col-md-6 col-12"
            @update:model-value="serverErrors.card_name = null"
          />

          <q-input
            v-model="form.brand"
            :label="$t('client_payment_methods.brand')"
            :error="!!serverErrors?.brand"
            :error-message="serverErrors?.brand"
            readonly
            class="col-md-6 col-12"
          >
            <template #append>
              <q-icon name="mdi-credit-card-check-outline" />
            </template>
          </q-input>

          <q-checkbox
            v-model="form.is_active"
            :label="$t('client_payment_methods.is_active')"
            class="col-12"
          />
        </q-card-section>

        <q-card-actions align="right">
          <q-btn
            flat
            :label="$t('common.actions.cancel')"
            color="negative"
            @click="onDialogCancel"
          />
          <q-btn
            type="submit"
            :label="$t('common.actions.save')"
            :loading="loading"
            :disable="!hasUpdatedFields"
            color="primary"
          />
        </q-card-actions>
      </q-form>
    </q-card>
  </q-dialog>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { useDialogPluginComponent } from 'quasar'
import { useI18n } from 'vue-i18n'
import { useFormUpdateTracker } from 'src/composables/useFormUpdateTracker'
import { useSubmitHandler } from 'src/composables/useSubmitHandler'
import {
  createClientPaymentMethod,
  updateClientPaymentMethod
} from 'src/api/clientPaymentMethod'
import DefaultDialogHeader from 'src/components/defaults/DefaultDialogHeader.vue'
import { useInputRules } from 'src/composables/useInputRules'
import {
  validateCardNumberLuhn,
  detectCardBrand,
  validateCardExpiration
} from 'src/helpers/utils'

const props = defineProps({
  paymentMethod: {
    type: Object,
    default: null
  },
  clientId: {
    type: Number,
    required: true
  },
  title: {
    type: Function,
    default: () => ''
  }
})

defineEmits([...useDialogPluginComponent.emits])
const { t } = useI18n()
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
const { inputRules } = useInputRules()
const formRef = ref(null)

const { form, getUpdatedFields, hasUpdatedFields } = useFormUpdateTracker({
  client_id: props.paymentMethod ? props.paymentMethod.client_id : props.clientId,
  card_number: props.paymentMethod ? props.paymentMethod.card_number : null,
  holder_name: props.paymentMethod ? props.paymentMethod.holder_name : null,
  expiration: props.paymentMethod ? props.paymentMethod.expiration : null,
  cvv: props.paymentMethod ? props.paymentMethod.cvv : null,
  card_name: props.paymentMethod ? props.paymentMethod.card_name : null,
  brand: props.paymentMethod ? props.paymentMethod.brand : null,
  last_four_digits: props.paymentMethod ? props.paymentMethod.last_four_digits : null,
  is_active: props.paymentMethod ? props.paymentMethod.is_active : true
})

const {
  loading,
  serverErrors,
  execute: submitForm,
} = useSubmitHandler({
  onSuccess: () => onDialogOK(true),
  formRef: formRef,
})

const validateCardNumber = (val) => {
  if (!val) return true
  if (!validateCardNumberLuhn(val)) {
    return t('client_payment_methods.invalid_card_number')
  }
  return true
}

const validateExpiration = (val) => {
  if (!val) return true
  if (!validateCardExpiration(val)) {
    return t('client_payment_methods.expired_card')
  }
  return true
}

const cardNumberMask = computed(() => {
  const cardNumber = String(form.card_number || '')
  if (cardNumber.includes('*')) {
    return '**** **** **** ####'
  }

  const digits = cardNumber.replace(/\D/g, '')
  return digits.length > 16 ? '#### #### #### #### ###' : '#### #### #### ####'
})

const onCardNumberChange = () => {
  serverErrors.card_number = null
  
  if (form.card_number && form.card_number.length >= 6 && !form.card_number.includes('*')) {
    const brand = detectCardBrand(form.card_number)
    if (brand) {
      form.brand = brand
    }
    
    const digits = form.card_number.replace(/\D/g, '')
    if (digits.length >= 4) {
      form.last_four_digits = digits.slice(-4)
    }
  }
}

const onCardNumberFocus = () => {
  if (String(form.card_number || '').includes('*')) {
    form.card_number = ''
  }
}

const onOKClick = async () => {
  if (props.paymentMethod) {
    await submitForm(() => updateClientPaymentMethod(props.paymentMethod.id, getUpdatedFields.value))
  } else {
    await submitForm(() => createClientPaymentMethod({ ...form }))
  }
}

onMounted(() => {
  if (props.clientId) {
    form.client_id = props.clientId
  }
})
</script>
