<script setup lang="ts">
import { reactive, toRaw, watch } from 'vue';
import { ProModal } from 'antdv-pro-modal';
import { Form, Modal, Upload, message, notification } from 'ant-design-vue/es';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
import { FileType, UploadFile } from 'ant-design-vue/es/upload/interface';
import {
  exportNeConfigBackup,
  importNeConfigBackup,
  listNeConfigBackup,
} from '@/api/ne/neConfigBackup';
import saveAs from 'file-saver';
import { uploadFile } from '@/api/tool/file';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
const emit = defineEmits(['ok', 'cancel', 'update:open']);
const props = defineProps({
  open: {
    type: Boolean,
    default: false,
  },
  /**网元ID */
  neId: {
    type: String,
    default: '',
  },
  neType: {
    type: String,
    default: '',
  },
});

/**导入状态数据 */
const importState = reactive({
  typeOption: [
    { label: t('views.ne.neInfo.backConf.server'), value: 'backup' },
    { label: t('views.ne.neInfo.backConf.local'), value: 'upload' },
  ],
  backupData: <any[]>[],
});

/**查询网元远程服务器备份文件 */
function backupSearch(name?: string) {
  const { neType, neId } = modalState.from;
  listNeConfigBackup({
    neType,
    neId,
    name,
    pageNum: 1,
    pageSize: 20,
  }).then(res => {
     if (res.code === RESULT_CODE_SUCCESS) {
      importState.backupData = [];
      res.data.rows.forEach((item: any) => {
        importState.backupData.push({
          label: item.name,
          value: item.path,
        });
      });
    }
  });
}

/**服务器备份文件选择切换 */
function backupChange(value: any) {
  if (!value) {
    backupSearch();
  }
}

/**类型切换 */
function typeChange(value: any) {
  modalState.from.path = undefined;
  if (value === 'backup') {
    backupSearch();
  }
}

/**对话框对象信息状态类型 */
type ModalStateType = {
  /**新增框或修改框是否显示 */
  openByEdit: boolean;
  /**标题 */
  title: string;
  /**表单数据 */
  from: {
    neType: string;
    neId: string;
    type: 'upload' | 'backup';
    path: string | undefined;
  };
  /**确定按钮 loading */
  confirmLoading: boolean;
  /**上传文件 */
  uploadFiles: any[];
};

/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
  openByEdit: false,
  title: '配置文件导入',
  from: {
    neType: '',
    neId: '',
    type: 'upload',
    path: undefined,
  },
  confirmLoading: false,
  uploadFiles: [],
});

/**对话框内表单属性和校验规则 */
const modalStateFrom = Form.useForm(
  modalState.from,
  reactive({
    path: [
      {
        required: true,
        message: t('views.ne.neInfo.backConf.pathPlease'),
      },
    ],
  })
);

/**
 * 对话框弹出确认执行函数
 * 进行表达规则校验
 */
function fnModalOk() {
  if (modalState.confirmLoading) return;
  const from = toRaw(modalState.from);
  modalStateFrom
    .validate()
    .then(e => {
      modalState.confirmLoading = true;
      const hide = message.loading(t('common.loading'), 0);
      importNeConfigBackup(from)
        .then(res => {
          if (res.code === RESULT_CODE_SUCCESS) {
            message.success(t('common.operateOk'), 3);
            // 返回无引用信息
            emit('ok', JSON.parse(JSON.stringify(from)));
            fnModalCancel();
          } else {
            message.error({
              content: `${res.msg}`,
              duration: 3,
            });
          }
        })
        .finally(() => {
          hide();
          modalState.confirmLoading = false;
        });
    })
    .catch(e => {
      message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
    });
}

/**
 * 对话框弹出关闭执行函数
 * 进行表达规则校验
 */
function fnModalCancel() {
  modalState.openByEdit = false;
  modalState.confirmLoading = false;
  modalStateFrom.resetFields();
  modalState.uploadFiles = [];
  emit('cancel');
  emit('update:open', false);
}

/**表单上传前删除 */
function fnBeforeRemoveFile(file: UploadFile) {
  modalState.from.path = undefined;
  return true;
}

/**表单上传前检查或转换压缩 */
function fnBeforeUploadFile(file: FileType) {
  if (modalState.confirmLoading) return false;
  if (!file.name.endsWith('.zip')) {
    const msg = `${t('components.UploadModal.onlyAllow')} .zip`;
    message.error(msg, 3);
    return Upload.LIST_IGNORE;
  }
  const isLt3M = file.size / 1024 / 1024 < 100;
  if (!isLt3M) {
    const msg = `${t('components.UploadModal.allowFilter')} 100MB`;
    message.error(msg, 3);
    return Upload.LIST_IGNORE;
  }
  return true;
}

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

/**监听是否显示，初始数据 */
watch(
  () => props.open,
  val => {
    if (val) {
      if (props.neType && props.neId) {
        modalState.from.neType = props.neType;
        modalState.from.neId = props.neId;
        modalState.title = t('views.ne.neInfo.backConf.title');
        modalState.openByEdit = true;
      }
    }
  }
);

/**
 * 网元导出配置
 * @param row 网元编号ID
 */
function fnExportConf(neType: string, neId: string) {
  Modal.confirm({
    title: t('common.tipTitle'),
    content: t('views.ne.neInfo.backConf.exportTip'),
    onOk() {
      const hide = message.loading(t('common.loading'), 0);
      exportNeConfigBackup({ neType, neId })
        .then(res => {
          if (res.code === RESULT_CODE_SUCCESS) {
            notification.success({
              message: t('common.tipTitle'),
              description: t('views.ne.neInfo.backConf.exportMsg'),
            });
            saveAs(
              res.data,
              `${neType}_${neId}_config_backup_${Date.now()}.zip`
            );
          } else {
            message.error(`${res.msg}`, 3);
          }
        })
        .finally(() => {
          hide();
        });
    },
  });
}

// 给组件设置属性 ref="xxxBackConf"
// setup内使用 const xxxBackConf = ref();
defineExpose({
  /**导出文件 */
  exportConf: fnExportConf,
});
</script>

<template>
  <ProModal
    :drag="true"
    :width="800"
    :keyboard="false"
    :mask-closable="false"
    :open="modalState.openByEdit"
    :title="modalState.title"
    :confirm-loading="modalState.confirmLoading"
    @ok="fnModalOk"
    @cancel="fnModalCancel"
  >
    <a-form name="modalStateFrom" layout="horizontal" :label-col="{ span: 6 }">
      <a-row>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item :label="t('views.ne.common.neType')" name="neType">
            {{ modalState.from.neType }}
          </a-form-item>
          <a-form-item
            :label="t('views.ne.neInfo.backConf.importType')"
            name="type"
          >
            <a-select
              v-model:value="modalState.from.type"
              default-value="server"
              :options="importState.typeOption"
              @change="typeChange"
            >
            </a-select>
          </a-form-item>
        </a-col>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item :label="t('views.ne.common.neId')" name="neId">
            {{ modalState.from.neId }}
          </a-form-item>
          <a-form-item
            :label="t('views.ne.neInfo.backConf.server')"
            name="fileName"
            v-bind="modalStateFrom.validateInfos.path"
            v-if="modalState.from.type === 'backup'"
          >
            <a-select
              v-model:value="modalState.from.path"
              :options="importState.backupData"
              :placeholder="t('common.selectPlease')"
              :show-search="true"
              :default-active-first-option="false"
              :show-arrow="false"
              :allow-clear="true"
              :filter-option="false"
              :not-found-content="null"
              @search="backupSearch"
              @change="backupChange"
            >
            </a-select>
          </a-form-item>

          <a-form-item
            :label="t('views.ne.neInfo.backConf.local')"
            name="file"
            v-bind="modalStateFrom.validateInfos.path"
            v-if="modalState.from.type === 'upload'"
          >
            <a-upload
              name="file"
              v-model:file-list="modalState.uploadFiles"
              accept=".zip"
              list-type="text"
              :max-count="1"
              :show-upload-list="{
                showPreviewIcon: false,
                showRemoveIcon: true,
                showDownloadIcon: false,
              }"
              @remove="fnBeforeRemoveFile"
              :before-upload="fnBeforeUploadFile"
              :custom-request="fnUploadFile"
              :disabled="modalState.confirmLoading"
            >
              <a-button type="primary">
                <template #icon>
                  <UploadOutlined />
                </template>
                {{ t('views.ne.neInfo.backConf.localUpload') }}
              </a-button>
            </a-upload>
          </a-form-item>
        </a-col>
      </a-row>
    </a-form>
  </ProModal>
</template>

<style lang="less" scoped></style>
