<script setup lang="ts">
import { reactive, onMounted, ref, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import useI18n from '@/hooks/useI18n';
import GraphEditModal from './components/GraphEditModal.vue';
import useGraph, { graphG6 } from './/hooks/useGraph';
import {
  delGraphData,
  getGraphData,
  getGraphGroups,
  saveGraphData,
} from '@/api/monitor/topology';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { Form, Modal, message } from 'ant-design-vue/lib';
const { t } = useI18n();
const { graphMode, graphModeOptions, handleRanderGraph, handleChangeMode } =
  useGraph();

/**图DOM节点实例对象 */
const graphG6Dom = ref<HTMLElement | undefined>(undefined);

/**图状态 */
const graphState = reactive<Record<string, any>>({
  /**当前图组名 */
  group: '',
  groupOptions: [],
  /**图数据 */
  data: {
    combos: [],
    edges: [],
    nodes: [],
  },
});

/**
 * 图组变更
 * @param value 变更值
 */
function fnGraphGroupChange(value: any) {
  if (value) {
    fnGraphDataLoad(true);
  }
}

/**
 * 获取图组名称数据
 * @param reload 是否重载数据
 */
function fnGraphDataGroups(reload: boolean = false) {
  getGraphGroups()
    .then(res => {
      if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
        graphState.groupOptions = res.data.map(str => {
          return { label: str, value: str };
        });
        // 非重载
        if (!reload) {
          graphState.group = res.data[0];
          fnGraphDataLoad(false);
        }
      }
    })
    .finally(() => {
      if (!graphState.group) {
        handleRanderGraph(graphG6Dom.value, graphState.data);
        message.warning({
          content: t('views.monitor.topologyBuild.noData'),
          duration: 5,
        });
      }
    });
}

/**
 * 获取图组数据渲染到画布
 * @param reload 是否重载数据
 */
function fnGraphDataLoad(reload: boolean = false) {
  getGraphData(graphState.group)
    .then(res => {
      if (res.code === RESULT_CODE_SUCCESS) {
        graphState.data = res.data;
      }
    })
    .finally(() => {
      // 重载数据
      if (reload) {
        graphG6.value.read(graphState.data);
      } else {
        handleRanderGraph(graphG6Dom.value, graphState.data);
      }
    });
}

/**对话框对象信息状态类型 */
type ModalStateType = {
  /**框是否显示 */
  visible: boolean;
  /**标题 */
  title: string;
  /**表单数据 */
  form: Record<string, any>;
  /**操作类型 */
  type: 'save' | 'delete';
  /**确定按钮 loading */
  confirmLoading: boolean;
};

/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
  visible: false,
  title: '图组',
  form: {
    group: '',
  },
  type: 'save',
  confirmLoading: false,
});

/**对话框内表单属性和校验规则 */
const modalStateFrom = Form.useForm(
  modalState.form,
  reactive({
    group: [
      {
        required: true,
        message: t('views.monitor.topologyBuild.groupPlease'),
      },
    ],
  })
);

/**
 * 对话框弹出确认执行函数
 * 进行表达规则校验
 */
function fnModalOk() {
  const from = toRaw(modalState.form);
  modalStateFrom
    .validate()
    .then(e => {
      modalState.confirmLoading = true;
      const hide = message.loading(t('common.loading'), 0);
      // 根据类型选择函数
      const groupName = from.group.trim()
      saveGraphData(groupName, graphG6.value.save())
        .then((res: any) => {
          if (res.code === RESULT_CODE_SUCCESS) {
            message.success({
              content: t('views.monitor.topologyBuild.saveOk', {
                group: groupName,
              }),
              duration: 3,
            });
            fnGraphDataGroups(true);
            graphState.group = groupName;
          } else {
            message.error({
              content: t('views.monitor.topologyBuild.saveFail', {
                group: groupName,
              }),
              duration: 3,
            });
          }
        })
        .finally(() => {
          hide();
          fnModalCancel();
          modalState.confirmLoading = false;
        });
    })
    .catch(e => {
      message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
    });
}

/**
 * 对话框弹出关闭执行函数
 * 进行表达规则校验
 */
function fnModalCancel() {
  modalState.type = 'save';
  modalState.visible = false;
  modalStateFrom.resetFields();
}

/**图组数据保存 */
function fnGraphDataSave() {
  modalState.form.group = graphState.group;
  modalState.type = 'save';
  (modalState.title = t('views.monitor.topologyBuild.saveTtite')),
    (modalState.visible = true);
}

/**图组数据删除 */
function fnGraphDataDelete() {
  if (!graphState.group) {
    handleRanderGraph(graphG6Dom.value, graphState.data);
    message.warning({
      content: t('views.monitor.topologyBuild.noData'),
      duration: 5,
    });
  }
  Modal.confirm({
    title: t('common.tipTitle'),
    content: t('views.monitor.topologyBuild.delTip', {
      group: graphState.group,
    }),
    onOk() {
      const hide = message.loading(t('common.loading'), 0);
      delGraphData(graphState.group)
        .then(res => {
          if (res.code === RESULT_CODE_SUCCESS) {
            message.success({
              content: t('common.msgSuccess', {
                msg: t('common.deleteText'),
              }),
              duration: 3,
            });
            // 重加载图组数据
            fnGraphDataGroups(true);
            if (graphState.groupOptions.length > 0) {
              graphState.group = graphState.groupOptions[0].value;
              fnGraphDataLoad(true);
            }
          } else {
            message.error({
              content: `${res.msg}`,
              duration: 3,
            });
          }
        })
        .finally(() => {
          hide();
        });
    },
  });
}

onMounted(() => {
  fnGraphDataGroups();
});
</script>

<template>
  <PageContainer>
    <a-card
      :bordered="false"
      :body-style="{ marginBottom: '24px', paddingBottom: 0 }"
    >
      <!-- 表格搜索栏 -->
      <a-form :model="graphState" name="graphState" layout="horizontal">
        <a-row :gutter="16">
          <a-col :lg="4" :md="12" :xs="24">
            <a-form-item
              :label="t('views.monitor.topologyBuild.graphMode')"
              name="graphMode"
            >
              <a-select
                :value="graphMode"
                :options="graphModeOptions"
                @change="handleChangeMode"
              >
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :lg="6" :md="12" :xs="24">
            <a-form-item
              :label="t('views.monitor.topologyBuild.graphGroup')"
              name="group "
            >
              <a-select
                v-model:value="graphState.group"
                :options="graphState.groupOptions"
                :placeholder="t('common.selectPlease')"
                @change="fnGraphGroupChange"
              />
            </a-form-item>
          </a-col>
        </a-row>
      </a-form>
    </a-card>

    <a-card :bordered="false" :body-style="{ padding: '0px' }">
      <!-- 插槽-卡片左侧侧 -->
      <template #title>
        <div class="button-container" style="margin-bottom: -12px">
          <span>
            {{ t('views.monitor.topologyBuild.graphGroup') }}：
            {{ graphState.group }}
          </span>
        </div>
      </template>

      <!-- 插槽-卡片右侧 -->
      <template #extra>
        <div class="button-container" style="margin-bottom: -12px">
          <template v-if="graphMode === 'edit'">
            <a-button type="primary" size="small" @click="fnGraphDataSave">
              <template #icon>
                <SaveOutlined />
              </template>
              {{ t('views.monitor.topologyBuild.graphSave') }}
            </a-button>

            <a-button
              type="ghost"
              danger
              size="small"
              @click="fnGraphDataDelete"
            >
              <template #icon>
                <DeleteOutlined />
              </template>
              {{ t('views.monitor.topologyBuild.graphDelete') }}
            </a-button>
          </template>
        </div>
      </template>

      <div ref="graphG6Dom" class="chart"></div>
    </a-card>

    <!-- 图元素修改框 -->
    <GraphEditModal></GraphEditModal>

    <!-- 图保存图组名修改框 -->
    <a-modal
      width="500px"
      :keyboard="false"
      :mask-closable="false"
      :visible="modalState.visible"
      :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="24" :md="24" :xs="24">
            <a-form-item
              :label="t('views.monitor.topologyBuild.graphGroup')"
              name="group"
              v-bind="modalStateFrom.validateInfos.group"
              :help="t('views.monitor.topologyBuild.graphGroupTip')"
            >
              <a-auto-complete
                v-model:value="modalState.form.group"
                :options="graphState.groupOptions"
                allow-clear
                :placeholder="t('views.monitor.topologyBuild.graphGroup')"
              />
            </a-form-item>
          </a-col>
        </a-row>
      </a-form>
    </a-modal>
  </PageContainer>
</template>

<style lang="less" scoped>
.chart {
  width: 100%;
  height: calc(100vh - 380px);
  background-color: rgb(43, 47, 51);
}
</style>
