<script setup lang="ts">
import { reactive, onMounted, toRaw, onUnmounted } from 'vue';
import { message, Modal, Upload } from 'ant-design-vue/lib';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { useClipboard } from '@vueuse/core';
import { FileType } from 'ant-design-vue/lib/upload/interface';
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
import { uploadFile } from '@/api/tool/file';
import {
  codeNeLicense,
  changeNeLicense,
  stateNeLicense,
} from '@/api/ne/neLicense';
import useI18n from '@/hooks/useI18n';
import { stepState } from '../hooks/useStep';
import saveAs from 'file-saver';
const { copy } = useClipboard({ legacy: true });
const { t } = useI18n();

/**授权激活对象信息状态类型 */
type LicenseStateType = {
  /**步骤 */
  setp: 'license' | 'verify';
  /**表单数据 */
  from: {
    neType: string;
    neId: string;
    activationRequestCode: string;
    licensePath: string;
    reload: boolean;
  };
  /**确定按钮 loading */
  confirmLoading: boolean;
  /**上传文件 */
  uploadFiles: any[];
};

/**授权激活对象信息状态 */
const licenseState: LicenseStateType = reactive({
  setp: 'license',
  from: {
    neType: '',
    neId: '',
    activationRequestCode: '',
    licensePath: '',
    reload: true,
  },
  confirmLoading: false,
  uploadFiles: [],
});

/**表单上传前检查或转换压缩 */
function fnBeforeUploadFile(file: FileType) {
  if (licenseState.confirmLoading) return false;
  if (!file.name.endsWith('.ini')) {
    message.error('只支持上传文件格式 .ini', 3);
    return Upload.LIST_IGNORE;
  }
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isLt2M) {
    message.error('文件必须小于2MB', 3);
    return Upload.LIST_IGNORE;
  }
  return true;
}

/**表单上传文件 */
function fnUploadFile(up: UploadRequestOption) {
  // 发送请求
  const hide = message.loading(t('common.loading'), 0);
  licenseState.confirmLoading = true;
  let formData = new FormData();
  formData.append('file', up.file);
  formData.append('subPath', 'license');
  uploadFile(formData)
    .then(res => {
      if (res.code === RESULT_CODE_SUCCESS) {
        message.success('上传成功', 3);
        // 改为完成状态
        const file = licenseState.uploadFiles[0];
        file.percent = 100;
        file.status = 'done';
        // 预置到表单
        const { fileName } = res.data;
        licenseState.from.licensePath = fileName;
      } else {
        message.error(res.msg, 3);
      }
    })
    .finally(() => {
      hide();
      licenseState.confirmLoading = false;
    });
}

/**复制授权申请码 */
function fnCopyCode() {
  const code = licenseState.from.activationRequestCode;
  if (!code) return;
  copy(code).then(() => {
    message.success('已成功复制', 3);
  });
}

/**下载授权申请码文件 */
function fnDownCode() {
  const { activationRequestCode, neType, neId } = licenseState.from;
  if (!activationRequestCode) return;
  Modal.confirm({
    title: t('common.tipTitle'),
    content: '确认将授权申请码下载为文件进行保存？',
    onOk() {
      const blob = new Blob([activationRequestCode], {
        type: 'text/plain',
      });
      saveAs(blob, `${neType}_${neId}_code.txt`);
    },
  });
}

/**读取授权申请码 */
function fnGetCode() {
  const { neType, neId } = licenseState.from;
  licenseState.confirmLoading = true;
  codeNeLicense(neType, neId).then(res => {
    if (res.code === RESULT_CODE_SUCCESS) {
      licenseState.from.activationRequestCode = res.data;
      licenseState.confirmLoading = false;
    } else {
      message.error(res.msg, 3);
    }
  });
}

/**启动服务验证 */
function fnRunCheck() {
  if (licenseState.confirmLoading) return;
  const form = toRaw(licenseState.from);
  if (form.licensePath === '') {
    message.error(t('common.errorFields', { num: 1 }), 3);
    return;
  }
  licenseState.confirmLoading = true;
  const hide = message.loading(t('common.loading'), 0);
  changeNeLicense(form)
    .then(res => {
      if (res.code === RESULT_CODE_SUCCESS) {
        message.success('网元开始进行校验', 3);
        fnVerifyTask();
      } else {
        message.error(res.msg, 3);
      }
    })
    .finally(() => {
      hide();
      licenseState.confirmLoading = false;
    });
}

/**校验状态 */
const verifyState = reactive({
  timer: null as any,
  /**执行次数 */
  count: 0,
  /**信息日志 */
  msgArr: [] as string[],
  /**数据 sn expire */
  data: null as any,
});

/**巡检校验任务 */
function fnVerifyTask() {
  licenseState.setp = 'verify';
  verifyState.timer = setInterval(() => {
    if (verifyState.count > 15) {
      clearTimeout(verifyState.timer);
      verifyState.msgArr.unshift(
        `第 ${verifyState.count} 次：网元验证激活失败，请重新上传有效激活文件。`
      );
      return;
    }
    const { neType, neId } = licenseState.from;
    stateNeLicense(neType, neId).then(res => {
      if (res.code === RESULT_CODE_SUCCESS && res.data && res.data.sn) {
        message.success(`${neType} ${neId} 网元激活成功`, 3);
        verifyState.data = res.data;
        // 记录当前步骤状态信息
        stepState.states[stepState.current] = { from: res.data };
        stepState.stepNext = true;
      }
      verifyState.count += 1;
      verifyState.msgArr.unshift(`第 ${verifyState.count} 次：${res.msg}`);
    });
  }, 2_000);
}

/**巡检重新校验 */
function fnVerifyTaskStop() {
  clearTimeout(verifyState.timer);
  verifyState.count = 0;
  verifyState.msgArr = [];
  licenseState.setp = 'license';
}

onMounted(() => {
  // 读取步骤：网元信息
  const stepPrevFrom = stepState.states[1].from;
  const { neType, neId } = stepPrevFrom;
  licenseState.from.neType = neType;
  licenseState.from.neId = neId;
  // 获取code
  fnGetCode();
});

onUnmounted(() => {
  clearTimeout(verifyState.timer);
});
</script>

<template>
  <a-form
    name="modalStateFrom"
    layout="horizontal"
    autocomplete="off"
    :validate-on-rule-change="false"
    :validateTrigger="[]"
    :label-col="{ span: 3 }"
    :wrapper-col="{ span: 12 }"
    :label-wrap="true"
  >
    <div>---- 授权申请</div>

    <template v-if="licenseState.setp === 'license'">
      <a-form-item label="授权申请码" name="comment" :required="true">
        <a-input-group compact>
          <a-input
            v-model:value="licenseState.from.activationRequestCode"
            :disabled="true"
            style="width: calc(100% - 64px)"
          />
          <a-tooltip title="复制">
            <a-button type="default" @click="fnCopyCode()">
              <template #icon><CopyOutlined /></template>
            </a-button>
          </a-tooltip>
          <a-tooltip title="下载">
            <a-button type="primary" @click="fnDownCode()">
              <template #icon><DownloadOutlined /></template>
            </a-button>
          </a-tooltip>
        </a-input-group>
      </a-form-item>

      <a-form-item label="授权激活文件" name="file" :required="true">
        <a-upload
          name="file"
          v-model:file-list="licenseState.uploadFiles"
          accept=".ini"
          list-type="text"
          :max-count="1"
          :show-upload-list="{
            showPreviewIcon: false,
            showRemoveIcon: false,
            showDownloadIcon: false,
          }"
          :before-upload="fnBeforeUploadFile"
          :custom-request="fnUploadFile"
          :disabled="licenseState.confirmLoading"
        >
          <a-button type="default"> 上传文件 </a-button>
        </a-upload>
      </a-form-item>

      <a-form-item name="check" :wrapper-col="{ span: 14, offset: 3 }">
        <div style="align-items: center">
          <a-button
            type="primary"
            shape="round"
            @click="fnRunCheck()"
            :loading="licenseState.confirmLoading"
          >
            <template #icon><LinkOutlined /></template>
            授权校验
          </a-button>
        </div>
      </a-form-item>
    </template>

    <div>---- 校验信息</div>

    <template v-if="licenseState.setp === 'verify'">
      <a-form-item
        name="info"
        label="巡检信息"
        :label-col="{ span: 3 }"
        :wrapper-col="{ span: 24 }"
        :label-wrap="true"
      >
        <a-result
          :status="verifyState.data ? 'success' : 'info'"
          :title="verifyState.data ? '成功激活' : '请等待网元验证结果'"
        >
          <template #extra>
            <a-button
              @click="fnVerifyTaskStop()"
              v-if="verifyState.data === null"
            >
              返回重新校验
            </a-button>
          </template>

          <div class="verify-msg" v-if="verifyState.data === null">
            <p
              style="font-size: 16px"
              v-for="(s, i) in verifyState.msgArr"
              :key="i"
            >
              <close-circle-outlined :style="{ color: 'red' }" />
              {{ s }}
            </p>
          </div>
          <div v-else>
            <p style="font-size: 16px">序列号：{{ verifyState.data.sn }}</p>
            <p style="font-size: 16px">
              许可证到期时间：{{ verifyState.data.expire }}
            </p>
          </div>
        </a-result>
      </a-form-item>
    </template>
  </a-form>
</template>

<style lang="less" scoped>
.verify-msg {
  height: 200px;
  overflow-y: auto;
}
</style>
