<template>
  <div class="collect-form">
    <div class="tip">
      请输入发送至
      <span class="highlight">
        {{ target }}
      </span>
      的6位验证码，有效期 10 分钟。如未收到，请尝试重新获取验证码。
    </div>
    <ElForm :rules="rules" :model="formModel" ref="formRef">
      <CustomizeFormItem prop="verifyInput" :error="error">
        <ul class="input-show" :class="{ 'has-error': errorTip !== '' }">
          <li
            v-for="item in 6"
            :class="{
              active: Number(item) === formModel.verifyInput.length + 1,
            }"
            :key="item"
          >
            {{ formModel.verifyInput[item - 1] }}
          </li>
        </ul>
        <input
          @input="inputVerify"
          ref="verifyInputRef"
          type="text"
          v-model="formModel.verifyInput"
          class="verify-input"
          maxlength="6"
        />
      </CustomizeFormItem>
    </ElForm>
    <div class="button-container" style="color: #b6b5ba">
      <div
        v-if="countDown === 60"
        class="cursor-pointer"
        @click="handleClickSendVerifyCode"
      >
        获取验证码
      </div>
      <span v-else>{{ countDown }}后可重新获取验证码</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { nextTick, onBeforeUnmount, onMounted, ref, watch } from "vue";
import { ElForm } from "element-plus";
import CustomizeFormItem from "../CustomizeFormItem.vue";
const props = defineProps<{
  target: string;
  fnSendVerificationCode: () => Promise<any>;
}>();

const formRef = ref<InstanceType<typeof ElForm>>();
const errorTip = ref("");
const countDown = ref(60);
const loading = ref(false);
const emit = defineEmits(["collect"]);
let t = NaN;

const formModel = ref({
  verifyInput: "",
});

const error = ref("");
let mark_error = 1;

function keyPress(e: KeyboardEvent) {
  if (e.key.match(/\d/)) {
    if (formModel.value.verifyInput.length === 6) return;
    formModel.value.verifyInput += e.key;
  } else if (e.key === "Backspace") {
    formModel.value.verifyInput = formModel.value.verifyInput.slice(0, -1);
  }
}

document.addEventListener("keydown", keyPress);
onBeforeUnmount(() => {
  document.removeEventListener("keydown", keyPress);
});

const setError = (str: string) => {
  error.value = str + " ".repeat(mark_error);
  console.log(error.value.length);
  mark_error = mark_error === 1 ? 2 : 1;
};

defineExpose({
  setError,
  setCode: (str: string) => {
    formModel.value.verifyInput = str;
  },
});

const rules = {
  phone: [
    {
      required: true,
      message: "请输入验证码",
    },
    {
      validator: (rule: any, value: any, callback: any) => {
        if (value.length !== 6) {
          callback("请输入6位验证码");
        } else {
          callback();
        }
      },
      trigger: "blur",
    },
  ],
};

const handleClickSendVerifyCode = async () => {
  if (loading.value) return;
  loading.value = true;
  await props.fnSendVerificationCode();
  loading.value = false;
  countDown.value--;
  t = window.setInterval(() => {
    countDown.value--;
    if (countDown.value === 0) {
      window.clearInterval(t);
      countDown.value = 60;
    }
  }, 1000);
};

onMounted(() => {
  handleClickSendVerifyCode();
});
onBeforeUnmount(() => {
  window.clearInterval(t);
});
const inputVerify = () => {
  if (errorTip.value === "") return;
  errorTip.value = "";
};
watch(
  () => formModel.value.verifyInput,
  (newV) => {
    formRef.value?.clearValidate();
    emit("collect", {
      value: newV,
      isValid: newV.length === 6,
    });
  }
);
</script>

<style lang="scss" scoped>
.tip {
  font-size: 14px;
  font-weight: 400;
  color: #8e8e8e;
}

.verify-input {
  position: absolute;
  z-index: -999;
  width: 0;
  border: none;
}

.el-form-item.is-error .input-show {
  li {
    border-color: #ff6268;
  }
}

.input-show {
  display: flex;
  margin-top: 20px;
  margin-bottom: 11px;

  li {
    width: 45px;
    height: 45px;
    border-radius: 4px;
    border: solid 1px var(--sy-gray);
    margin-right: 15px;
    flex-shrink: 0;
    font-size: 20px;
    font-weight: 500;
    color: black;
    line-height: 45px;
    text-align: center;

    &.active {
      border-color: var(--sy-blue);
    }
  }

  & > li:nth-child(3) {
    margin-right: 57px;
    position: relative;
    overflow: visible;

    &:after {
      width: 8px;
      border-bottom: 1px solid var(--sy-gray);
      position: absolute;
      right: -33px;
      top: 20px;
      content: " ";
    }
  }
}
</style>
