<template>
  <div class="integration__cont__map__cont">
    <Minheader
      :is-statuser="true"
      :is-Journal="true"
      @addJournalForm="logDialogShow"
    >
      <template #header>
        <div class="status flex-wrap">
          <div class="manageTitle">服务拓扑</div>
          <div class="typestart flex-wrap">
            <div class="name">
              <div class="log"></div>
              正常
            </div>
            <div class="name">
              <div class="log1"></div>
              异常
            </div>
          </div>
        </div>
      </template>
    </Minheader>
    <div class="integration__cont" ref="chartDom"></div>
    <Dialog
      width="1200px"
      :flag="flag"
      :type="type"
      :msg-title="msgTitle"
      @resetForm="logDialogHide"
    >
      <div class="diacont">
        <div class="interfaceLog_head flex">
          <div class="interfaceLog_head_time flex-act">
            <div class="header_name">当前服务：Kafka原始报文</div>
          </div>
          <div class="interfaceLog_head_btn flex">
            <div class="interfaceLog_head_time_start r12">
              <el-date-picker
                v-model="timeStart"
                size="default"
                type="datetime"
                placeholder="选择开始日期时间"
                format="YYYY-MM-DD HH:mm:ss"
                value-format="YYYY-MM-DD HH:mm:ss"
                :clearable="false"
                @change="timeSelectHandler"
              />
            </div>
            <div class="interfaceLog_head_time_end r16">
              <el-date-picker
                v-model="timeEnd"
                size="default"
                type="datetime"
                placeholder="选择结束日期时间"
                format="YYYY-MM-DD HH:mm:ss"
                value-format="YYYY-MM-DD HH:mm:ss"
                :clearable="false"
                @change="timeSelectHandler"
              />
            </div>
            <Search
              :is-title="false"
              @get-search-data="getSearchData"
              @clear-search-data="clearSearchData"
            />
          </div>
        </div>
        <div class="interfaceLog_content">
          <el-row :gutter="24">
            <el-col :span="19">
              <DataTable
                :table-header="tableColumns"
                :table-data="tableData"
                :table-property="{ rowKey: 'ID' }"
                @load="load"
                @row-click="rowClickHandler"
              />
            </el-col>
            <el-col :span="5">
              <div class="interfaceLog_content_progress">
                <el-timeline>
                  <el-timeline-item
                    v-for="(item, index) in progressList"
                    :key="index"
                  >
                    <div class="list">
                      <div class="list_status"></div>
                      <div class="list_title">{{ item.logType }}</div>
                      <div class="list_code">{{ item.resultCode }}</div>
                      <div class="list_time">{{ item.logTime }}</div>
                      <!-- <div class="list_detial">{{ item.resultDetails }}</div> -->
                    </div>
                  </el-timeline-item>
                </el-timeline>
              </div>
            </el-col>
          </el-row>
        </div>
      </div>
    </Dialog>
  </div>
</template>
<script setup lang="ts">
import Minheader from '@/components/minheader/index.vue'
import DataTable from '@/components/tableTemp/index.vue'
import Dialog from '@/components/dialog/index.vue'
import { Ref } from 'vue'
import * as echarts from 'echarts'
import _ from 'lodash'
import { ElMessage } from 'element-plus'
import { Query } from '@/api/webApi'
import { CommonTableColumn } from '~/common'
import img1 from '@/assets/integr/jiekou_blue.png'
import img2 from '@/assets/integr/jiekou_red.png'
import img3 from '@/assets/integr/pull_blue.png'
import img4 from '@/assets/integr/kafka_blue.png'
import img5 from '@/assets/integr/push_blue.png'
import img6 from '@/assets/integr/save_blue.png'
import img7 from '@/assets/integr/mysql_blue.png'
import img8 from '@/assets/integr/pull_red.png'

const route = useRoute()
const serviceID = Number(route.query.serviceID)
const serviceName = String(route.query.serviceName)
const getTopologyData = async () => {
  try {
    const {
      code,
      returnData: { listValues },
      message,
    } = await Query({
      id: DATACONTENT_ID.sysServiceTopology,
      dataContent: Array(6).fill(serviceID),
    })
    if (Number(code) !== 0) {
      throw new Error(message ?? '失败')
    }
    console.log(listValues)
  } catch (error: any) {
    console.error(error)
  }
}
getTopologyData()

const chartDom = ref<HTMLDivElement | null>(null)
const myChart = ref<Ref<echarts.ECharts> | null>(null)
const flag = ref(false) //弹窗开关
const type = ref('') //判断是否删除
const msgTitle = ref('查看日志') //弹窗标题
const getAssetsFile = (url: string) => {
  return new URL(`../assets/integr/${url}`, import.meta.url).href
}
const datas = ref<any[]>([])
const resizeDelay = 300
//默认节点
// const defaultImg = getAssetsFile("jiekou_blue.png");
const defaultImg = 'image://' + img1
//默认节点-错误
const defaultImgError = 'image://' + img2
//拉取节点
const pullImg = 'image://' + img3
//拉取节点-错误
const pullImgError = 'image://' + img8
//kafka节点
const kafkaImg = 'image://' + img4
//kafka节点-错误
const kafkaImgError = getAssetsFile('kafka_red.png')
//推送节点
const pushImg = 'image://' + img5
//推送节点-错误
const pushImgError = 'image://' + getAssetsFile('push_red.png')
//存储节点
const saveImg = 'image://' + img6
//存储节点-错误
const saveImgError = getAssetsFile('save_red.png')
//存储节点
const mysqlImg = 'image://' + img7
//存储节点-错误
const mysqlImgError = getAssetsFile('mysql_red.png')
const nodeDataList = ref([
  {
    name: '星盟SBH',
    linkTargetName: 'Kafka',
    linkValue: ' ',
    coordConfig: {
      level: '0',
    },
    value: [10, 245],
    draggable: false,
    fixed: true,
    symbol: defaultImg,
    symbolSize: 60,
  },
  {
    name: 'Kafka',
    linkTargetName: 'BSMBPM报文解析',
    linkValue: ' ',
    coordConfig: { level: '3' },
    symbolSize: 60,
    symbol: kafkaImg,
    draggable: false,
    value: [40, 245],
  },
  {
    name: 'BSMBPM报文解析',
    linkTargetName: 'BSM',
    linkValue: ' ',
    coordConfig: { level: '3' },
    symbolSize: 60,
    symbol: pullImgError,
    draggable: false,
    value: [70, 245],
  },
  {
    name: 'BSM',
    linkTargetName: '解析服务',
    linkValue: ' ',
    coordConfig: { level: '4' },
    symbolSize: 60,
    symbol: defaultImg,
    draggable: false,
    value: [100, 245],
  },
  {
    name: 'BPM',
    linkTargetName: '推送节点',
    linkValue: ' ',
    coordConfig: { level: '4' },
    symbolSize: 60,
    symbol: defaultImg,
    draggable: false,
    value: [100, 200],
  },
  {
    name: '航班',
    linkTargetName: '解析服务',
    linkValue: ' ',
    coordConfig: { level: '4' },
    symbolSize: 30,
    symbol: defaultImg,
    draggable: false,
    value: [160, 120],
  },
  {
    name: '行李投诉',
    linkTargetName: '解析服务',
    linkValue: ' ',
    coordConfig: { level: '4' },
    symbolSize: 30,
    symbol: defaultImg,
    draggable: false,
    value: [160, 90],
  },
  {
    name: '旅客',
    linkTargetName: '解析服务',
    linkValue: ' ',
    coordConfig: { level: '4' },
    symbolSize: 30,
    symbol: defaultImg,
    draggable: false,
    value: [160, 60],
  },
  {
    name: '推送节点',
    linkTargetName: '首都机场BHS ',
    linkValue: ' ',
    coordConfig: { level: '5' },
    symbolSize: 60,
    symbol: pushImg,
    draggable: false,
    value: [200, 160],
  },
  {
    name: '推送节点 ',
    linkTargetName: '星盟SBH ',
    linkValue: ' ',
    coordConfig: { level: '5' },
    symbolSize: 60,
    symbol: pushImg,
    draggable: false,
    label: {
      show: false,
    },
    value: [200, 160],
  },
  {
    name: '推送节点  ',
    linkTargetName: '局方公共平台 ',
    linkValue: ' ',
    coordConfig: { level: '5' },
    symbolSize: 60,
    symbol: pushImg,
    draggable: false,
    label: {
      show: false,
    },
    value: [200, 160],
  },
  {
    name: '推送节点   ',
    linkTargetName: '行李推送事件',
    linkValue: ' ',
    coordConfig: { level: '5' },
    symbolSize: 60,
    symbol: pushImg,
    draggable: false,
    label: {
      show: false,
    },
    value: [200, 160],
  },
  {
    name: '推送节点    ',
    linkTargetName: 'ES',
    linkValue: ' ',
    coordConfig: { level: '5' },
    symbolSize: 60,
    symbol: pushImg,
    draggable: false,
    label: {
      show: false,
    },
    value: [200, 160],
  },
  {
    name: '解析服务',
    linkTargetName: ' Kafka',
    linkValue: ' ',
    coordConfig: { level: '5' },
    symbolSize: 60,
    symbol: pushImg,
    draggable: false,
    value: [200, 100],
  },
  {
    name: '首都机场BHS ',
    linkTargetName: '首都机场BHS ',
    linkValue: ' ',
    coordConfig: { level: '6' },
    symbolSize: 30,
    symbol: defaultImg,
    draggable: false,
    value: [240, 220],
  },
  {
    name: '星盟SBH ',
    linkTargetName: '星盟SBH ',
    linkValue: ' ',
    coordConfig: { level: '6' },
    symbolSize: 30,
    symbol: defaultImg,
    draggable: false,
    value: [240, 190],
  },
  {
    name: '局方公共平台 ',
    linkTargetName: '局方公共平台 ',
    linkValue: ' ',
    coordConfig: { level: '6' },
    symbolSize: 30,
    symbol: defaultImg,
    draggable: false,
    value: [240, 160],
  },
  {
    name: '行李推送事件',
    linkTargetName: '行李推送事件',
    linkValue: ' ',
    coordConfig: { level: '6' },
    symbolSize: 30,
    symbol: defaultImg,
    draggable: false,
    value: [240, 130],
  },
  {
    name: 'ES',
    linkTargetName: 'ES',
    linkValue: ' ',
    coordConfig: { level: '6' },
    symbolSize: 30,
    symbol: defaultImg,
    draggable: false,
    value: [240, 100],
  },
  {
    name: ' Kafka',
    linkTargetName: '存储服务',
    linkValue: ' ',
    coordConfig: { level: '6' },
    symbolSize: 30,
    symbol: defaultImg,
    draggable: false,
    value: [240, 70],
  },
  {
    name: '存储服务',
    linkTargetName: 'Mysql',
    linkValue: ' ',
    coordConfig: { level: '7' },
    symbolSize: 60,
    symbol: saveImg,
    draggable: false,
    value: [280, 160],
  },
  {
    name: 'Mysql',
    linkTargetName: 'Mysql',
    linkValue: ' ',
    coordConfig: { level: '8' },
    symbolSize: 60,
    symbol: mysqlImg,
    draggable: false,
    value: [340, 160],
  },
])
const options = reactive({
  title: {
    text: `当前服务：${serviceName}`,
  },
  itemStyle: {
    normal: {
      color: '#67C23A',
    },
    shadowBlur: 0,
  },
  textStyle: {
    color: '#444',
    fontSize: 16,
    fontWeight: 600,
  },
  grid: {
    top: 60,
    bottom: 10,
    left: 0,
    right: 0,
  },
  legend: [
    {
      formatter: function (name) {
        return echarts.format.truncateText(name, 200, '12px', '…', {})
      },
      tooltip: {
        show: true,
      },
      selectedMode: 'false',
      bottom: 20,
    },
  ],
  animationDuration: 500,
  animationEasingUpdate: 'quinticInOut',
  xAxis: {
    show: false,
    type: 'value',
  },
  yAxis: {
    show: false,
    type: 'value',
  },
  series: [
    {
      type: 'graph',
      coordinateSystem: 'cartesian2d',
      //圆形上面的文字
      label: {
        position: 'bottom',
        show: true,
        fontSize: 12,
      },
      itemStyle: {
        color: '#409eff',

        shadowBlur: 0,
      },
      lineStyle: {
        width: 0,
        shadowColor: 'none',
        color: '#ff0000',
      },
      data: <any[]>[],
      links: <any[]>[],
    },
  ],
})
const getCoordDataList = (): any[] => {
  let coorDataDict = {}
  let defaultConfig = {
    type: 'lines', // 块1,2...n到节点A,B...N
    coordinateSystem: 'cartesian2d',
    // animationDelay: 10000,
    z: 1,
    effect: {
      show: true,
      smooth: true,
      trailLength: 0,
      symbol: 'arrow',
      color: '#92A7D5',
      symbolSize: 10,
      period: 3,
      delay: 1500,
      loop: true,
    },
    lineStyle: {
      normal: {
        curveness: 0,
        color: '#92A7D5',
        width: 1,
      },
    },
    data: [],
  }
  nodeDataList.value.map(item => {
    if (item.coordConfig !== undefined) {
      if (!(item.coordConfig.level in coorDataDict)) {
        let coorConfig = JSON.parse(JSON.stringify(defaultConfig))
        if (item.coordConfig.lineStyle !== undefined) {
          coorConfig.lineStyle = item.coordConfig.lineStyle
        }
        if (item.coordConfig.effect !== undefined) {
          coorConfig.effect = item.coordConfig.effect
        }
        coorDataDict[item.coordConfig.level] = coorConfig
      }

      let coordData = [
        item.value,
        nodeDataList.value.filter(i => i.name == item.linkTargetName)[0]
          .value ||
          nodeDataList.value.filter(i => i.name == item.linkTargetName)[1]
            .value,
      ]
      coorDataDict[item.coordConfig.level].data.push({
        coords: coordData,
      })
      if (item.coordConfig.bilateral) {
        coorDataDict[item.coordConfig.level].data.push({
          coords: coordData.reverse(),
        })
      }
    }
  })
  return Object.values(coorDataDict)
}
nodeDataList.value.forEach(item => {
  datas.value.push({
    source: item.name,
    value: item.linkValue,
    target: item.linkTargetName,
  })
})
const resizeHandler = () => {
  myChart.value?.resize()
}
onMounted(() => {
  options.series[0].data = nodeDataList.value
  options.series[0].links = datas.value
  options.series.push(...getCoordDataList())
  myChart.value = echarts.init(chartDom.value as HTMLDivElement)
  myChart.value.setOption(options as echarts.EChartOption, true)
  window.addEventListener('resize', _.debounce(resizeHandler, resizeDelay))
})
// // 事件
// myChart.on("click", (params) => {
//   console.log(params);
// });

//新增
const logDialogShow = () => {
  msgTitle.value = '查看日志'
  flag.value = true
  getToday()
  getTableData()
}
//取消
const logDialogHide = () => {
  flag.value = false
}

const getSearchData = (text: string) => {
  console.log(text)
}
const clearSearchData = () => {}

let page = 0
const loading = ref(false)
const noMore = ref(false)
const loadDisabled = computed(() => loading.value || noMore.value)
//表头
const tableColumns = ref<CommonTableColumn[]>([])
//列表
const tableData = ref<any[]>([])
const resetTable = () => {
  page = 0
  loading.value = false
  noMore.value = false
  tableData.value = []
}
const getTableData = async () => {
  try {
    loading.value = true
    const {
      code,
      returnData: { columnSet, listValues },
    } = await Query({
      id: DATACONTENT_ID.sysServiceTopologyTable,
      needPage: ++page,
      dataContent: [serviceID, timeStart.value, timeEnd.value],
    })
    if (Number(code) === 0) {
      tableColumns.value = columnSet.map(column => ({
        label: column.columnLabel,
        key: column.columnName,
        ...column,
      }))
      if (listValues.length === 0) {
        page--
        noMore.value = true
      }
      tableData.value.push(...listValues)
      loading.value = false
    } else {
      throw new Error('获取数据失败')
    }
  } catch (error: any) {
    page--
    loading.value = false
    ElMessage.error(error.message)
  }
}
const load = () => {
  if (loadDisabled.value) {
    return
  }
  getTableData()
}

const timeStart = ref('')
const timeEnd = ref('')
const getToday = () => {
  function numberFormat(number) {
    const string = '0' + number
    return string.slice(-2)
  }
  const now = new Date()
  const year = now.getFullYear()
  const month = now.getMonth() + 1
  const date = now.getDate()
  const today = `${year}-${numberFormat(month)}-${numberFormat(date)}`
  timeStart.value = `${today} 00:00:00`
  timeEnd.value = `${today} 23:59:59`
}
const timeSelectHandler = () => {
  const startTime = new Date(timeStart.value).getTime()
  const endTime = new Date(timeEnd.value).getTime()
  if (startTime > endTime) {
    ElMessage.error('开始时间不能大于结束时间')
    timeEnd.value = ''
    return
  }
  if (startTime < endTime - (3 * 24 * 60 * 60 - 1) * 1000) {
    ElMessage.error('间隔时间不能大于三天')
    timeEnd.value = ''
    return
  }
  resetTable()
  getTableData()
}

type progressItem = {
  logType: string
  resultCode: string
  logTime: string
  resultDetails?: string
}
const progressList = ref<progressItem[]>([])
// progressList.value.push(
//   ...Array.from({ length: 3 }).map(() => ({
//     logType: '更新 Github 模板',
//     resultCode: '989665554',
//     logTime: '2022-4-26 15:48:55',
//   }))
// )
const rowClickHandler = (row, column, event) => {
  progressList.value = []
  if (row.logObject) {
    tableData.value.forEach(record => {
      if (record.logObject == row.logObject) {
        progressList.value.push(record)
      }
    })
  } else {
    progressList.value.push(row)
  }
}
</script>
<style lang="scss" scoped>
.integration__cont__map__cont {
  width: 100%;
  height: 100%;
  .header_name {
    font-size: 16px;
    font-family: Microsoft YaHei;
    font-weight: bold;
    color: #303133;
  }
  .integration__cont {
    background: #ffffff;
    border-radius: 4px;
    padding: 35px;
    width: 100%;
    height: calc(100vh - 177px);
  }
  .typestart {
    height: 100%;
    .name {
      display: flex;
      align-items: center;
    }
    .name:nth-child(2) {
      margin-left: 24px;
    }
    .log {
      width: 14px;
      height: 14px;
      background: #041741;
      border-radius: 2px;
      margin-right: 12px;
    }
    .log1 {
      width: 14px;
      height: 14px;
      background: #e32d2d;
      border-radius: 2px;
      margin-right: 12px;
    }
  }
}
.interfaceLog_content {
  margin-top: 24px;
  // height: 452px;
  // overflow: hidden;
}
</style>
