<script setup lang="ts">
import NavHomeSelect from '@/assets/images/nav-home.select.png?url';
import { Notify, Toast } from '@/platform';

import {
  getCaptchaMethod,
  processMethod,
  registerAccountMethod,
  registerFieldsMethod,
  searchAccountMethod,
}                                     from '@/request/api';
import type { Fields, RegisterModel } from '@/request/model';
import { useRouteQuery }              from '@vueuse/router';

import { useCaptcha, useRequest, useSerialRequest } from 'alova/client';

import type { FormInstance }           from 'vant';
import { RadioGroup as vanRadioGroup } from 'vant';


const { data: fields, loading } = useRequest(registerFieldsMethod);

const formRef = useTemplateRef<FormInstance>('register-form');
const modelRef = ref<Partial<RegisterModel>>({ code: '' });

const router = useRouter();
const { loading: submitting, send: submit } = useSerialRequest([
  data => registerAccountMethod(data),
  () => processMethod(),
], { immediate: false })
  .onSuccess(({ data }) => {router.replace(data);})
  .onError(({ error }) => Notify.warning(error.message));

const { loading: searching, send: search } = useRequest((data) => searchAccountMethod(data), {
  immediate: false,
}).onSuccess(({ data }) => {
  modelRef.value = { ...modelRef.value, ...data };
});

let captchaLoaded = false;
const { loading: captchaLoading, countdown, send: getCaptcha } = useCaptcha(
  () => getCaptchaMethod(modelRef.value.phone!),
  { initialCountdown: 60 },
).onSuccess(({ data }) => {
  captchaLoaded = true;
  Toast.success(data ?? '获取成功')
});
const getCaptchaHandle = async () => {
  try {
    await formRef.value?.validate('phone');
    await getCaptcha();
    const field = fields.value.find(field => field.name === 'code');
    if ( field?.keyboard ) { field.keyboard.show = true; }
  } catch ( e: any ) {
    Toast.warning(e?.message);
  }
};

const searchHandle = async (key: 'cardno' | 'code') => {
  try {
    await formRef.value?.validate(key);
    await search(modelRef.value).catch();
  } catch ( e: any ) {
    Toast.warning(e?.message);
  }
};

function onKeyboardBlur(field: Fields[number]) {
  if ( field?.name === 'phone' && !captchaLoaded ) { getCaptchaHandle(); }
  if ( field?.name === 'cardno' ) { searchHandle('cardno'); }
  if ( field?.name === 'code' ) { searchHandle('code'); }
}

function onSubmitHandle() {
  submit(toValue(modelRef));
}

function fix(key: string) {
  for ( const field of fields.value ) {
    if (field.keyboard?.show && field.name !== key ) field.keyboard.show = false;
  }
}

const scan = useRouteQuery<string>('scan');
watch(scan, key => {
  if ( key ) {
    try {
      const { model } = JSON.parse(sessionStorage.getItem(`scan_${ key }`) ?? '');
      modelRef.value = { ...modelRef.value, ...model };
    } catch ( e: any ) {}
  }
}, { immediate: true });

onBeforeUnmount(() => {
  for ( let i = 0; i < sessionStorage.length; i++ ) {
    const key = sessionStorage.key(i);
    if ( key?.startsWith('scan_') ) sessionStorage.removeItem(key);
  }
});
</script>
<template>
  <div>
    <div class="page-header flex py-4 px-4">
      <div class="grow shrink-0 h-full min-w-16"></div>
      <div class="grow-[3] shrink mx-2 flex flex-col justify-center overflow-hidden">
        <div class="font-bold text-3xl text-nowrap text-center tracking-wide overflow-ellipsis overflow-hidden">
          建档
        </div>
      </div>
      <div class="grow shrink-0 h-full min-w-16 flex items-center justify-end overflow-hidden">
        <router-link :to="{ path: '/screen' }" replace>
          <img class="size-8 object-scale-down" :src="NavHomeSelect" alt="返回首页">
        </router-link>
      </div>
    </div>
    <div class="page-content p-6">
      <van-form class="register-form" ref="register-form" colon required="auto"
                scroll-to-error scroll-to-error-position="center"
                @submit="onSubmitHandle()"
      >
        <van-cell-group :border="false">
          <template v-for="field in fields" :key="field.name">
            <van-field v-model="modelRef[field.name]" :name="field.name" :id="field.name"
                       :rules="field.rules" v-bind="field.control"
                       :class="{'no-border': field.control?.border === false}"
                       :focused="field.keyboard?.show" @focus="field.keyboard && (field.keyboard.show = true)"
                       @blur="field.keyboard && (field.keyboard.show = false)"
                       :readonly="field.control.readonly" @click="field.keyboard && (field.keyboard.show = true)"
            >
              <template #input v-if="field.component?.name === 'radio'">
                <van-radio-group v-model="modelRef[field.name]" direction="horizontal" shape="dot">
                  <van-radio v-for="option in field.component?.options" :key="option.value" :name="option.value">
                    {{ option.label }}
                  </van-radio>
                </van-radio-group>
              </template>
              <template #input v-else-if="field.component?.name === 'code'">
                <van-password-input
                  style="width: 100%;"
                  v-model:value="modelRef[field.name]" v-bind="(field.component as any)!.props"
                  :focused="field.keyboard?.show" @focus="field.keyboard && (field.keyboard.show = true);fix('code')"
                />
              </template>
              <template #button>
                <div class="text-primary cursor-pointer">
                  <template v-if="field.component?.name === 'code'">
                    <div class="text-primary cursor-pointer" @click="getCaptchaHandle()">
                      {{ captchaLoading ? '发送中...' : countdown > 0 ? `${ countdown }后可重发` : '获取验证码' }}
                    </div>
                  </template>
                  <template v-else>{{ field.suffix }}</template>
                </div>
              </template>
            </van-field>
            <van-number-keyboard
              v-if="field.keyboard"
              v-model="modelRef[field.name]"
              v-bind="field.keyboard" :maxlength="field.control.maxlength"
              @blur="field.keyboard.show = false; onKeyboardBlur(field)"
            />
          </template>
        </van-cell-group>
      </van-form>
      <div class="m-4">
        <div class="m-auto size-16 cursor-pointer">
          <van-loading v-if="submitting || loading" type="spinner" size="64" color="#38ff6e" />
          <img v-else class="size-full"
               src="@/assets/images/next-step.svg" alt="提交" @click="formRef?.submit()"
          >
        </div>
      </div>
    </div>
  </div>
</template>
<style scoped lang="scss">
.register-form {
  .van-field {
    margin: 0;
    padding: 0;
  }

  .van-field.no-border {
    :deep(.van-field__control) {
      padding: 0;
      border: none;
      border-radius: 8px;
      text-align: center;
    }
  }

  :deep(.van-field__label) {
    margin-bottom: 24px;
    padding: 8px 0;
    min-width: 100px;
    font-size: 18px;
  }

  :deep(.van-field__control) {
    margin-bottom: 24px;
    padding: 8px;
    border: 1px solid #38ff6e;
    border-radius: 8px;
    text-align: center;
  }

  :deep(.van-field__clear) {
    align-self: flex-start;
    display: flex;
    align-items: center;
    height: 42px;
  }

  :deep(.van-field__button) {
    margin-bottom: 24px;
    padding: 8px var(--van-padding-xs);
    min-width: 100px;
    font-size: 18px;
    text-align: left;
  }

  :deep(.van-field__error-message) {
    position: absolute;
    top: 40px + 2px;
  }

  :deep(.van-password-input) {
    margin: 0;
  }

  :deep(.van-password-input__security) {
    justify-content: space-between;
    align-items: center;
    text-align: center;
    $size: 40px;
    height: $size + 2px;

    &::after {
      display: none;
    }

    li {
      height: $size;
      width: $size;
      flex: none;
      border: 1px solid #38ff6e;
      border-radius: 8px;
    }
  }
}

.van-radio-group {
  height: 40px + 2px;
}
</style>
