<script setup lang="ts">
import { reactive, onMounted, toRaw, watch } from 'vue';
import { message, Form } from 'ant-design-vue/lib';
import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeInfoStore from '@/store/modules/neinfo';
import { getNeInfo, addNeInfo, updateNeInfo } from '@/api/ne/neInfo';
import { NE_TYPE_LIST } from '@/constants/ne-constants';
import { testNeHost } from '@/api/ne/neHost';
import useDictStore from '@/store/modules/dict';
const { getDict } = useDictStore();
const { t } = useI18n();
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
const props = defineProps({
  visible: {
    type: Boolean,
    default: false,
  },
  editId: {
    type: String,
    default: '',
  },
});

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

/**
 * 对话框弹出测试连接
 */
function fnModalTest(row: Record<string, any>) {
  if (modalState.confirmLoading) return;
  modalState.confirmLoading = true;
  const hide = message.loading(t('common.loading'), 0);
  testNeHost(row)
    .then(res => {
      if (res.code === RESULT_CODE_SUCCESS) {
        message.success({
          content: `${row.addr}:${row.port} ${t('views.ne.neHost.testOk')}`,
          duration: 2,
        });
      } else {
        message.error({
          content: `${row.addr}:${row.port} ${res.msg}`,
          duration: 2,
        });
      }
    })
    .finally(() => {
      hide();
      modalState.confirmLoading = false;
    });
}

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

/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
  visibleByEdit: false,
  title: '网元',
  from: {
    id: undefined,
    neId: '001',
    neType: 'AMF',
    neName: '',
    ip: '',
    port: 33030,
    pvFlag: 'PNF',
    rmUid: '4400HX1AMF001',
    neAddress: '',
    dn: '',
    vendorName: '',
    province: '',
    // 主机
    hosts: [
      {
        hostId: undefined,
        hostType: 'ssh',
        groupId: '1',
        title: 'SSH_NE_22',
        addr: '',
        port: 22,
        user: 'user',
        authMode: '0',
        password: 'user',
        privateKey: '',
        passPhrase: '',
        remark: '',
      },
      {
        hostId: undefined,
        hostType: 'telnet',
        groupId: '1',
        title: 'Telnet_NE_4100',
        addr: '',
        port: 4100,
        user: 'user',
        authMode: '0',
        password: 'user',
        remark: '',
      },
    ],
  },
  confirmLoading: false,
});

/**对话框内表单属性和校验规则 */
const modalStateFrom = Form.useForm(
  modalState.from,
  reactive({
    neType: [
      {
        required: true,
        message: '请输入网元类型',
      },
    ],
    neId: [
      {
        required: true,
        message: '请输入网元标识',
      },
    ],
    rmUid: [
      {
        required: true,
        message: '请输入资源唯一标识',
      },
    ],
    ip: [
      {
        required: true,
        message: '请输入网元IP地址',
      },
    ],
    neName: [
      {
        required: true,
        message: '请输入网元名称',
      },
    ],
  })
);

/**
 * 对话框弹出显示为 新增或者修改
 * @param editId 网元id, 不传为新增
 */
function fnModalVisibleByEdit(editId: string) {
  if (!editId) {
    modalStateFrom.resetFields();
    modalState.title = t('views.configManage.neManage.addNe');
    modalState.visibleByEdit = true;
  } else {
    if (modalState.confirmLoading) return;
    const hide = message.loading(t('common.loading'), 0);
    modalState.confirmLoading = true;
    getNeInfo(editId).then(res => {
      modalState.confirmLoading = false;
      hide();
      if (res.code === RESULT_CODE_SUCCESS) {
        Object.assign(modalState.from, res.data);
        modalState.title = '编辑网元信息';
        modalState.visibleByEdit = true;
      } else {
        message.error(t('common.getInfoFail'), 2);
      }
    });
  }
}

/**
 * 对话框弹出确认执行函数
 * 进行表达规则校验
 */
function fnModalOk() {
  modalStateFrom
    .validate()
    .then(e => {
      modalState.confirmLoading = true;
      const from = toRaw(modalState.from);
      const result = from.id ? updateNeInfo(from) : addNeInfo(from);
      const hide = message.loading(t('common.loading'), 0);
      result
        .then(res => {
          if (res.code === RESULT_CODE_SUCCESS) {
            message.success({
              content: '操作成功',
              duration: 3,
            });
            // 刷新缓存的网元信息
            useNeInfoStore().fnRefreshNelist();
            emit('ok');
            fnModalCancel();
          } else {
            message.error({
              content: `${t('views.configManage.neManage.operFail')}`,
              duration: 3,
            });
          }
        })
        .finally(() => {
          hide();
          modalState.confirmLoading = false;
        });
    })
    .catch(e => {
      message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
    });
}

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

/**
 * 表单修改网元类型
 */
function fnNeTypeChange(v: any) {
  const hostsLen = modalState.from.hosts.length;
  // 网元默认只含22和4100
  if (hostsLen === 3 && v !== 'UPF') {
    modalState.from.hosts.pop();
  }
  // UPF标准版本可支持5002
  if (hostsLen === 2 && v === 'UPF') {
    modalState.from.hosts.push({
      hostId: undefined,
      hostType: 'telnet',
      groupId: '1',
      title: 'Telnet_NE_5002',
      addr: '',
      port: 5002,
      user: 'user',
      authMode: '0',
      password: 'user',
      remark: '',
    });
  }
}

/**
 * 表单修改网元IP
 */
function fnNeIPChange(e: any) {
  const v = e.target.value;
  if (v.length < 7) return;
  for (const host of modalState.from.hosts) {
    host.addr = v;
  }
}

/**监听是否显示，初始数据 */
watch(
  () => props.visible,
  val => {
    if (val) fnModalVisibleByEdit(props.editId);
  }
);

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') {
      dict.neHostGroupId = resArr[1].value;
    }
    if (resArr[2].status === 'fulfilled') {
      dict.neHostAuthMode = resArr[2].value;
    }
  });
});
</script>

<template>
  <DraggableModal
    width="800px"
    :body-style="{ maxHeight: '650px', 'overflow-y': 'auto' }"
    :keyboard="false"
    :mask-closable="false"
    :visible="modalState.visibleByEdit"
    :title="modalState.title"
    :confirm-loading="modalState.confirmLoading"
    @ok="fnModalOk"
    @cancel="fnModalCancel"
  >
    <a-form
      name="modalStateFrom"
      layout="horizontal"
      :label-col="{ span: 6 }"
      :labelWrap="true"
    >
      <a-row :gutter="16">
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item
            :label="t('views.configManage.neManage.neType')"
            name="neType"
            v-bind="modalStateFrom.validateInfos.neType"
          >
            <a-auto-complete
              v-model:value="modalState.from.neType"
              :options="NE_TYPE_LIST.map(v => ({ value: v }))"
              @change="fnNeTypeChange"
            >
              <a-input
                allow-clear
                :placeholder="t('common.inputPlease')"
                :maxlength="32"
              >
                <template #prefix>
                  <a-tooltip placement="topLeft">
                    <template #title>
                      {{ t('views.configManage.neManage.neTypeTip') }}
                    </template>
                    <InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
                  </a-tooltip>
                </template>
              </a-input>
            </a-auto-complete>
          </a-form-item>
        </a-col>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item
            :label="t('views.configManage.neManage.pvflag')"
            name="pvFlag"
            v-bind="modalStateFrom.validateInfos.pvFlag"
          >
            <a-select
              v-model:value="modalState.from.pvFlag"
              default-value="PNF"
            >
              <a-select-opt-group :label="t('views.configManage.neManage.pnf')">
                <a-select-option value="PNF">PNF</a-select-option>
              </a-select-opt-group>
              <a-select-opt-group :label="t('views.configManage.neManage.vnf')">
                <a-select-option value="VNF">VNF</a-select-option>
              </a-select-opt-group>
            </a-select>
          </a-form-item>
        </a-col>
      </a-row>

      <a-row :gutter="16">
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item
            :label="t('views.configManage.neManage.neId')"
            name="neId"
            v-bind="modalStateFrom.validateInfos.neId"
          >
            <a-input
              v-model:value="modalState.from.neId"
              allow-clear
              :placeholder="t('common.inputPlease')"
              :maxlength="32"
            ></a-input>
          </a-form-item>
        </a-col>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item
            :label="t('views.configManage.neManage.neName')"
            name="neName"
            v-bind="modalStateFrom.validateInfos.neName"
          >
            <a-input
              v-model:value="modalState.from.neName"
              allow-clear
              :placeholder="t('common.inputPlease')"
              :maxlength="64"
            >
            </a-input>
          </a-form-item>
        </a-col>
      </a-row>

      <a-row :gutter="16">
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item
            :label="t('views.configManage.neManage.ip')"
            name="ip"
            v-bind="modalStateFrom.validateInfos.ip"
          >
            <a-input
              v-model:value="modalState.from.ip"
              allow-clear
              :placeholder="t('common.inputPlease')"
              :maxlength="128"
              @change="fnNeIPChange"
            >
              <template #prefix>
                <a-tooltip placement="topLeft">
                  <template #title>
                    <div>
                      {{ t('views.ne.neInfo.ipAddr') }}
                    </div>
                  </template>
                  <InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
                </a-tooltip>
              </template>
            </a-input>
          </a-form-item>
        </a-col>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item
            :label="t('views.configManage.neManage.port')"
            name="port"
            v-bind="modalStateFrom.validateInfos.port"
          >
            <a-input-number
              v-model:value="modalState.from.port"
              style="width: 100%"
              :min="1"
              :max="65535"
              placeholder="<=65535"
            >
              <template #prefix>
                <a-tooltip placement="topLeft">
                  <template #title>
                    <div>{{ t('views.configManage.neManage.portTip') }}</div>
                  </template>
                  <InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
                </a-tooltip>
              </template>
            </a-input-number>
          </a-form-item>
        </a-col>
      </a-row>

      <a-form-item
        :label="t('views.configManage.neManage.uid')"
        name="rmUid"
        v-bind="modalStateFrom.validateInfos.rmUid"
        :label-col="{ span: 3 }"
        :labelWrap="true"
      >
        <a-input
          v-model:value="modalState.from.rmUid"
          allow-clear
          :placeholder="t('common.inputPlease')"
          :maxlength="40"
        >
          <template #prefix>
            <a-tooltip placement="topLeft">
              <template #title>
                <div>
                  {{ t('views.ne.neInfo.rmUID') }}
                </div>
              </template>
              <InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
            </a-tooltip>
          </template>
        </a-input>
      </a-form-item>

      <a-row :gutter="16">
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item
            :label="t('views.configManage.neManage.mac')"
            name="neAddress"
          >
            <a-input
              v-model:value="modalState.from.neAddress"
              allow-clear
              :placeholder="t('common.inputPlease')"
              :maxlength="64"
            >
              <template #prefix>
                <a-tooltip placement="topLeft">
                  <template #title>
                    <div>{{ t('views.configManage.neManage.macTip') }}</div>
                  </template>
                  <InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
                </a-tooltip>
              </template>
            </a-input>
          </a-form-item>
        </a-col>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item :label="t('views.configManage.neManage.dn')" name="dn">
            <a-input
              v-model:value="modalState.from.dn"
              allow-clear
              :placeholder="t('common.inputPlease')"
              :maxlength="255"
            ></a-input>
          </a-form-item>
        </a-col>
      </a-row>

      <a-row :gutter="16">
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item
            :label="t('views.configManage.neManage.vendorName')"
            name="vendorName"
          >
            <a-input
              v-model:value="modalState.from.vendorName"
              allow-clear
              :placeholder="t('common.inputPlease')"
              :maxlength="64"
            >
            </a-input>
          </a-form-item>
        </a-col>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item
            :label="t('views.configManage.neManage.province')"
            name="province"
          >
            <a-input
              v-model:value="modalState.from.province"
              allow-clear
              :placeholder="t('common.inputPlease')"
              :maxlength="32"
            ></a-input>
          </a-form-item>
        </a-col>
      </a-row>

      <a-divider orientation="left">
        {{ t('views.ne.neInfo.hostConfig') }}
      </a-divider>

      <!-- 主机连接配置 -->
      <a-collapse class="collapse" ghost>
        <a-collapse-panel
          v-for="host in modalState.from.hosts"
          :key="host.title"
          :header="`${host.hostType.toUpperCase()} ${host.port}`"
        >
          <a-row :gutter="16">
            <a-col :lg="12" :md="12" :xs="24">
              <a-form-item :label="t('views.ne.neHost.addr')">
                <a-input
                  v-model:value="host.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">
                <a-input-number
                  v-model:value="host.port"
                  :min="10"
                  :max="65535"
                  :step="1"
                  style="width: 100%"
                ></a-input-number>
              </a-form-item>
            </a-col>
          </a-row>

          <a-row :gutter="16">
            <a-col :lg="12" :md="12" :xs="24">
              <a-form-item :label="t('views.ne.neHost.user')">
                <a-input
                  v-model:value="host.user"
                  allow-clear
                  :maxlength="50"
                  :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')">
                <a-select
                  v-model:value="host.authMode"
                  default-value="0"
                  :options="dict.neHostAuthMode"
                  :disabled="host.hostType === 'telnet'"
                >
                </a-select>
              </a-form-item>
            </a-col>
          </a-row>

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

          <template v-if="host.authMode === '1'">
            <a-form-item
              :label="t('views.ne.neHost.privateKey')"
              :label-col="{ span: 3 }"
              :label-wrap="true"
            >
              <a-textarea
                v-model:value="host.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')"
              :label-col="{ span: 3 }"
              :label-wrap="true"
            >
              <a-input-password
                v-model:value="host.passPhrase"
                :maxlength="128"
                :placeholder="t('common.inputPlease')"
              >
              </a-input-password>
            </a-form-item>
          </template>

          <a-form-item
            :label="t('views.ne.neHost.remark')"
            :label-col="{ span: 3 }"
            :label-wrap="true"
          >
            <a-textarea
              v-model:value="host.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(host)"
              :loading="modalState.confirmLoading"
            >
              <template #icon><LinkOutlined /></template>
            </a-button>
          </a-form-item>
        </a-collapse-panel>
      </a-collapse>
    </a-form>
  </DraggableModal>
</template>

<style lang="less" scoped>
.collapse :deep(.ant-collapse-item) > .ant-collapse-header {
  padding-left: 0;
  padding-right: 0;
}
.collapse-header {
  flex: 1;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}
</style>
