<script setup lang="ts">
import { computed, reactive, ref, shallowRef } from 'vue';

import UseGuidance from '@/layout/UseGuidance.vue';
import { t } from '@/i18n';
import { ProtocolConfigMethod } from '@/constants';

import SelectConfigMethod from './SelectConfigMethod.vue';
import SelectProtocolType from './SelectProtocolType.vue';

import type { UploadProps } from 'ant-design-vue';
import type { FormRules, RuleValidator, SetupProtocolForm, UseGuideStepItem } from '@/types';

const steps = ref<UseGuideStepItem[]>([
  {
    title: t('setupProtocol.selectProtocolType'),
    stepDescription: t('setupProtocol.selectProtocolTypeTip'),
    component: shallowRef(SelectProtocolType),
  },
  {
    title: t('setupProtocol.selectConfigMethod'),
    stepDescription: t('setupProtocol.selectConfigMethodTip'),
    component: shallowRef(SelectConfigMethod),
    formLayout: 'vertical',
  },
]);

const setupProtocolForm = reactive<SetupProtocolForm>({
  protocolType: undefined,
  protocolInfo: {
    id: undefined,
    protocolName: '',
    protocolType: undefined,
    deviceType: undefined,
    dataBit: 5,
    parityBit: 'N',
    stopBit: '1',
    baudRate: undefined,
    dataSendInterval: undefined,
    highFreqSendInterval: undefined,
    readTimeout: undefined,
    nextDataReadDelay: undefined,
    nextRoundDataReadDelay: undefined,
    readContinuousAddr: '关',
    readContinuousAddrCode: 0,
    readContinuousAddrLength: undefined,
    byteOrder: undefined,
    byteOrderCode: undefined,
    addrOrder: undefined,
    addrOrderCode: undefined,
  },
  protocolFile: [],
  configMethod: ProtocolConfigMethod.ImportFromTemplate,
  deviceType: undefined,
});

const rules = computed<FormRules<SetupProtocolForm>>(() => {
  return {
    protocolType: [
      {
        required: true,
        message: t('setupProtocol.plzSelectProtocolType'),
        trigger: 'blur',
      },
    ],
    protocolFile: [
      {
        validator: validateProtocolFile,
        trigger: 'change',
      },
    ],
    configMethod: [
      {
        required: true,
        message: t('common.plzSelect', { name: t('setupProtocol.configMethod') }),
        trigger: 'blur',
      },
    ],
    deviceType: [
      {
        required: true,
        message: t('common.plzSelect', { name: t('setupProtocol.deviceType') }),
        trigger: 'blur',
      },
    ],
  };
});

/**
 * 文件大小最大值（MB）
 */
const MAX_FILE_SIZE = 10;

const validateProtocolFile: RuleValidator<UploadProps['fileList']> = (_rule, value) => {
  if (!value?.length) {
    return Promise.reject(t('setupProtocol.plzSelectProtocolFile'));
  }

  const file = value[0];
  const excelFileRegExp = /\.(xls|xlsx)$/i;

  if (!excelFileRegExp.test(file.name)) {
    return Promise.reject(t('setupProtocol.wrongProtocolFileType'));
  }

  const fileSize = (file.size || 0) / 1024 / 1024;

  if (fileSize > MAX_FILE_SIZE) {
    return Promise.reject(t('setupProtocol.wrongProtocolFileFize', { size: MAX_FILE_SIZE }));
  }

  return Promise.resolve();
};
</script>

<template>
  <UseGuidance :title="$t('setupProtocol.setupProtocol')" :steps="steps" :form="setupProtocolForm" :rules="rules" />
</template>
