<script setup lang="ts">
import { reactive, onMounted, toRaw, watch } from 'vue';
import { ProModal } from 'antdv-pro-modal';
import { Form, message } from 'ant-design-vue/es';
import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useDictStore from '@/store/modules/dict';
const { getDict } = useDictStore();
import {
  addNeHost,
  getNeHost,
  testNeHost,
  updateNeHost,
} from '@/api/ne/neHost';
const { t } = useI18n();
const emit = defineEmits(['ok', 'cancel', 'update:open']);
const props = defineProps({
  open: {
    type: Boolean,
    default: false,
  },
  /**记录ID */
  editId: {
    type: String,
    default: '',
  },
  /**分组可选网元 */
  neGroup: {
    type: Boolean,
    default: false,
  },
});

/**字典数据 */
let dict: {
  /**主机类型 */
  neHostType: DictType[];
  /**分组 */
  neHostGroupId: DictType[];
  /**认证模式 */
  neHostAuthMode: DictType[];
} = reactive({
  neHostType: [],
  neHostGroupId: [],
  neHostAuthMode: [],
});

/**对话框对象信息状态类型 */
type ModalStateType = {
  /**新增框或修改框是否显示 */
  openByEdit: boolean;
  /**标题 */
  title: string;
  /**表单数据 */
  from: Record<string, any>;
  /**确定按钮 loading */
  confirmLoading: boolean;
};

/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
  openByEdit: false,
  title: '信息',
  from: {
    hostId: undefined,
    hostType: 'ssh',
    groupId: '0',
    title: '',
    addr: '',
    port: 22,
    user: '',
    authMode: '0',
    password: '',
    privateKey: '',
    passPhrase: '',
    remark: '',
  },
  confirmLoading: false,
  uploadFiles: [],
});

/**对话框内表单属性和校验规则 */
const modalStateFrom = Form.useForm(
  modalState.from,
  reactive({
    title: [
      {
        required: true,
        min: 1,
        max: 50,
        message: t('views.ne.neHost.titlePlease'),
      },
    ],
    addr: [
      {
        required: true,
        min: 1,
        max: 128,
        message: t('views.ne.neHost.addrPlease'),
      },
    ],
    port: [
      {
        required: true,
        message: t('views.ne.neHost.portPlease'),
      },
    ],
    user: [
      {
        required: true,
        min: 1,
        max: 50,
        message: t('views.ne.neHost.userPlease'),
      },
    ],
    password: [
      {
        required: true,
        min: 1,
        max: 128,
        message: t('views.ne.neHost.passwordPlease'),
      },
    ],
    privateKey: [
      {
        required: true,
        min: 1,
        max: 3000,
        message: t('views.ne.neHost.privateKeyPlease'),
      },
    ],
  })
);

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

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

/**
 * 对话框弹出显示为 ID编辑
 * @param id id
 */
function fnModalVisibleById(id: string) {
  if (modalState.confirmLoading) return;
  const hide = message.loading(t('common.loading'), 0);
  modalState.confirmLoading = true;
  getNeHost(id)
    .then(res => {
      if (res.code === RESULT_CODE_SUCCESS && res.data) {
        modalState.from = Object.assign(modalState.from, res.data);
        modalState.title = t('views.ne.neHost.editTitle');
        modalState.openByEdit = true;
      } else {
        message.error(t('common.getInfoFail'), 2);
      }
    })
    .finally(() => {
      modalState.confirmLoading = false;
      hide();
    });
}

/**
 * 对话框弹出测试连接
 */
function fnModalTest() {
  if (modalState.confirmLoading) return;
  const form = toRaw(modalState.from);
  const validateArr = ['title', 'addr', 'port', 'user'];
  if (form.authMode === '0') {
    validateArr.push('password');
  }
  if (form.authMode === '1') {
    validateArr.push('privateKey');
  }
  modalStateFrom
    .validate(validateArr)
    .then(() => {
      modalState.confirmLoading = true;
      const hide = message.loading(t('common.loading'), 0);
      testNeHost(form)
        .then(res => {
          if (res.code === RESULT_CODE_SUCCESS) {
            message.success({
              content: t('views.ne.neHost.testOk'),
              duration: 2,
            });
          } else {
            message.error({
              content: `${res.msg}`,
              duration: 2,
            });
          }
        })
        .finally(() => {
          modalState.confirmLoading = false;
          hide();
        });
    })
    .catch(e => {
      message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
    });
}

/**监听是否显示，初始数据 */
watch(
  () => props.open,
  val => {
    if (val) {
      if (props.editId) {
        fnModalVisibleById(props.editId);
      } else {
        modalStateFrom.resetFields();
        modalState.title = t('views.ne.neHost.addTitle');
        modalState.openByEdit = true;
      }
    }
  }
);

onMounted(() => {
  // 初始字典数据
  Promise.allSettled([
    getDict('ne_host_type'),
    getDict('ne_host_groupId'),
    getDict('ne_host_authMode'),
  ]).then(resArr => {
    if (resArr[0].status === 'fulfilled') {
      dict.neHostType = resArr[0].value;
    }
    if (resArr[1].status === 'fulfilled') {
      if (props.neGroup) {
        dict.neHostGroupId = resArr[1].value.filter(item => item.value !== '1');
      } else {
        dict.neHostGroupId = resArr[1].value;
      }
    }
    if (resArr[2].status === 'fulfilled') {
      dict.neHostAuthMode = resArr[2].value;
    }
  });
});
</script>

<template>
  <ProModal
    :drag="true"
    :width="800"
    :destroyOnClose="true"
    :keyboard="false"
    :mask-closable="false"
    :open="modalState.openByEdit"
    :title="modalState.title"
    :confirm-loading="modalState.confirmLoading"
    @ok="fnModalOk"
    @cancel="fnModalCancel"
  >
    <a-form
      name="modalStateFromByEdit"
      layout="horizontal"
      :label-col="{ span: 6 }"
      :label-wrap="true"
    >
      <a-row>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item :label="t('views.ne.neHost.hostType')" name="hostType">
            <a-select
              v-model:value="modalState.from.hostType"
              default-value="ssh"
              :options="dict.neHostType"
              :disabled="!!modalState.from.hostId"
            >
            </a-select>
          </a-form-item>
        </a-col>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item :label="t('views.ne.neHost.groupId')" name="groupId">
            <a-select
              v-model:value="modalState.from.groupId"
              default-value="0"
              :options="dict.neHostGroupId"
              :disabled="!!modalState.from.hostId"
            >
            </a-select>
          </a-form-item>
        </a-col>
      </a-row>

      <a-form-item
        :label="t('views.ne.neHost.title')"
        name="title"
        v-bind="modalStateFrom.validateInfos.title"
        :label-col="{ span: 3 }"
        :label-wrap="true"
      >
        <a-input
          v-model:value="modalState.from.title"
          allow-clear
          :maxlength="50"
          :placeholder="t('common.inputPlease')"
        >
        </a-input>
      </a-form-item>

      <a-row>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item
            :label="t('views.ne.neHost.addr')"
            name="addr"
            v-bind="modalStateFrom.validateInfos.addr"
          >
            <a-input
              v-model:value="modalState.from.addr"
              allow-clear
              :maxlength="128"
              :placeholder="t('common.inputPlease')"
            >
            </a-input>
          </a-form-item>
        </a-col>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item
            :label="t('views.ne.neHost.port')"
            name="port"
            v-bind="modalStateFrom.validateInfos.port"
          >
            <a-input-number
              v-model:value="modalState.from.port"
              :min="10"
              :max="65535"
              :step="1"
              :maxlength="5"
              style="width: 100%"
            ></a-input-number>
          </a-form-item>
        </a-col>
      </a-row>

      <a-row>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item
            :label="t('views.ne.neHost.user')"
            name="user"
            v-bind="modalStateFrom.validateInfos.user"
          >
            <a-input
              v-model:value="modalState.from.user"
              allow-clear
              :maxlength="32"
              :placeholder="t('common.inputPlease')"
            >
            </a-input>
          </a-form-item>
        </a-col>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item :label="t('views.ne.neHost.authMode')" name="authMode">
            <a-select
              v-model:value="modalState.from.authMode"
              default-value="0"
              :options="dict.neHostAuthMode"
            >
            </a-select>
          </a-form-item>
        </a-col>
      </a-row>

      <a-form-item
        v-if="modalState.from.authMode === '0'"
        :label="t('views.ne.neHost.password')"
        name="password"
        v-bind="modalStateFrom.validateInfos.password"
        :label-col="{ span: 3 }"
        :label-wrap="true"
      >
        <a-input-password
          v-model:value="modalState.from.password"
          :maxlength="128"
          :placeholder="t('common.inputPlease')"
        >
        </a-input-password>
      </a-form-item>

      <template v-if="modalState.from.authMode === '1'">
        <a-form-item
          :label="t('views.ne.neHost.privateKey')"
          name="privateKey"
          v-bind="modalStateFrom.validateInfos.privateKey"
          :label-col="{ span: 3 }"
          :label-wrap="true"
        >
          <a-textarea
            v-model:value="modalState.from.privateKey"
            :auto-size="{ minRows: 4, maxRows: 6 }"
            :maxlength="3000"
            :show-count="true"
            :placeholder="t('views.ne.neHost.privateKeyPlease')"
          />
        </a-form-item>

        <a-form-item
          :label="t('views.ne.neHost.passPhrase')"
          name="passPhrase"
          :label-col="{ span: 3 }"
          :label-wrap="true"
        >
          <a-input-password
            v-model:value="modalState.from.passPhrase"
            :maxlength="128"
            :placeholder="t('common.inputPlease')"
          >
          </a-input-password>
        </a-form-item>
      </template>

      <a-form-item
        :label="t('common.remark')"
        name="remark"
        :label-col="{ span: 3 }"
        :label-wrap="true"
      >
        <a-textarea
          v-model:value="modalState.from.remark"
          :auto-size="{ minRows: 1, maxRows: 6 }"
          :maxlength="450"
          :show-count="true"
          :placeholder="t('common.inputPlease')"
        />
      </a-form-item>

      <a-form-item
        :label="t('views.ne.neHost.test')"
        name="test"
        :label-col="{ span: 3 }"
        :label-wrap="true"
      >
        <a-button
          type="primary"
          shape="round"
          @click="fnModalTest"
          :loading="modalState.confirmLoading"
        >
          <template #icon><LinkOutlined /></template>
        </a-button>
      </a-form-item>
    </a-form>
  </ProModal>
</template>

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