<template>
  <view>
    <view class="form_item">
      <view class="form_item_key font-bold" :class="{ 'require': required }">{{ phoneLabel }}</view>
      <view class="form_item_val">
        <input
          class="input"
          type="number"
          :disabled="readOnly"
          placeholder="请输入手机号"
          :value="phoneValue"
          @input="onPhoneInputChange"
        />
      </view>
    </view>

    <view class="form_item">
      <view class="form_item_key font-bold" :class="{ 'require': required }">{{ codeLabel }}</view>
      <view class="form_item_val">
        <input
          class="input"
          type="number"
          placeholder="请输入验证码"
          :value="codeValue"
          @input="onCodeInputChange"
        />
      </view>
      <button
        class="img_captcha"
        @click="sendCode"
        :disabled="isCountingDown"
      >
        {{ isCountingDown ? countdownFormatter(countdownText, countdown) : sendCodeText }}
      </button>
    </view>
  </view>
</template>

<script setup lang="ts">
import { defineProps, defineEmits, ref, defineExpose } from 'vue';

const props = defineProps({
  phoneLabel: {
    type: String,
    default: '手机号'
  },
  codeLabel: {
    type: String,
    default: '验证码'
  },
  sendCodeText: {
    type: String,
    default: '发送验证码'
  },
  countdownText: {
    type: String,
    default: '重新发送(%s)s'
  },
  readOnly: {
    type: Boolean,
    default: false
  },
  required: {
    type: Boolean,
    default: false
  },
  errorMsg: {
    type: String,
    default: '输入不合法'
  },
  phoneValue: {
    type: String,
    default: '',
  },
  codeValue: {
    type: String,
    default: ''
  },
});

const emit = defineEmits(['phoneInputChange', 'codeInputChange', 'sendCodeRequest', 'update:phoneValue', 'update:codeValue']);

const isCountingDown = ref(false);
const countdown = ref(0);
const phoneError = ref(false);
const codeError = ref(false);

const onPhoneInputChange = (e: any) => {
  const val = e.detail.value;
  emit('phoneInputChange', { phoneValue: val });
  emit('update:phoneValue', val);
};

const onCodeInputChange = (e: any) => {
  const val = e.detail.value;
  emit('codeInputChange', { codeValue: val });
  emit('update:codeValue', val);
};

const sendCode = () => {
  emit('sendCodeRequest', { phoneValue: props.phoneValue });
};

const startCountdown = () => {
  let cd = 60;
  isCountingDown.value = true;
  countdown.value = cd;
  
  const timer = setInterval(() => {
    cd--;
    if (cd <= 0) {
      clearInterval(timer);
      isCountingDown.value = false;
      countdown.value = 0;
    } else {
      countdown.value = cd;
    }
  }, 1000);
};

const handleValidationResult = (e: any) => {
  const { key, isValid } = e.detail || e;
  if (key === 'phone') {
    phoneError.value = !isValid;
  } else if (key === 'code') {
    codeError.value = !isValid;
  }
};

const countdownFormatter = (text: string, count: number) => {
  if (!text) return "";
  return text.replace(/%s/g, count.toString());
};

defineExpose({
  startCountdown,
  handleValidationResult
});
</script>

<style>
/* 表单 start */
.form_item {
  position: relative;
  width: inherit;
  padding: 0 10upx;
  font-size: 30upx;
  height: 120upx;
  display: flex;
  align-items: center;
}

.form_item + .form_item {
  border-top: 2upx solid #e5e5e5;
}

.form_item .form_item_key {
  padding-left: 20upx;
  position: relative;
  width: 220upx;
}

.form_item .form_item_val {
  flex: 1 0 0;
  text-align: right;
  height: inherit;
  padding: 0 20upx;
}

.form_item .form_item_val .input {
  height: inherit;
}

.img_captcha {
  width: 180upx !important;
  height: 70%;
  min-width: 80upx;
  background-color: var(--dominantColor);
  color: #fff;
  font-size: 30upx;
  display: flex;
  align-items: center;
  justify-content: center;
}

.require::after {
  content: '*';
  position: absolute;
  color: #FF1D1F;
  top: 10%;
  left: 0;
}
/* 表单 end */

.font-bold {
  font-weight: bold;
}
</style>
