<template>
  <!-- chart外层箱子 -->
  <div :class="{'panel-chart--fullscreen': isFullscreen}" class="panel-chart" :id="isFullscreen ? ('chart-screen-' + chartInfo.id ) : ('chart-local-' + chartInfo.id)"  v-my-loading="loading">
    <!--    全屏的header-->
    <chart-screen-header
      v-if="isFullscreen"
      :is-group="isGroup(chartInfo.type)"
      :isError="isError"
      :from="from"
      :chartData="chartData"
      :chart-info="chartInfo"
      :showAllData.sync="showAllData"
      :allDataLength="allDataLength"
      @loadMore="loadMore"
      @refresh="refresh"
      @dateChange="dateChange"
      @close="showFullscreen"
      class="alert-message-info-header"
    >
      <span slot="title-icon"> active </span>
    </chart-screen-header>
    <!-- chart -->
    <!-- 数据查询后传入chart组件，chart组件内不查询，只根据接传递的数据来渲染 -->
    <div class="alert-message-info-box">
      <div class="info-box-left">
        <chart
          ref="chart"
          :chart-data="chartData"
          :chart-info="chartInfo"
          :panelLock="panelLock"
          :filter="filter"
          :from="from"
          @refreshLogs="refreshLogs"
          :show-header="showHeader"
          :isError="isError"
          :loading="loading"
          :minusTime="minusTime"
          :multipleTime="multipleTime"
          :isFullscreen="isFullscreen"
          :showAllData="showAllData"
          v-if="!isGroup(chartInfo.type) || !chartInfo.param.collapse"
        ></chart>
        <alertMessageInfoTab class="alert-message-info-tab">
        </alertMessageInfoTab>
      </div>
      <div class="info-box-right">
        时间
      </div>
    </div>
  </div>
</template>

<script>
import ChartScreenHeader from '@/components/chart/ChartScreenHeader'
import chart from '@/components/chart/chart'
import { isChartPie, isTimeSeries, getGroupHeight, isGroup } from '@/components/chart/chart/tools'
import { chartType, fromRoute } from '@/components/common/js/constants'
import bus from '@/libs/bus'
import axios from 'axios'
import chartTempData from '@/components/charts/chartTempData'
import logsData from '@/components/chart/logsData'
import lodash from 'lodash'
import alertMessageInfoTab from '@/components/common/alert/alertMessageInfoTab'

export default {
  name: 'panelChart',
  components: {
    alertMessageInfoTab,
    chart,
    ChartScreenHeader
  },
  props: {
    chartInfo: Object, // 其中的param json串已转化为对象
    timeRange: Array, // 时间范围
    isFullscreen: Boolean,
    panelLock: Boolean,
    chartDetailInfo: Object,
    from: String,
    filter: {},
    showHeader: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      chartData: [],
      loading: true,
      isError: false,
      multipleTime: false,
      minusTime: '',
      showAllData: false,
      allDataLength: 0,
      severityData: this.$store.getters.severityData,
      severityDataWeight: this.$store.getters.severityDataWeight
    }
  },
  computed: {
    headerH () {
      return this.$store.getters.getHeaderH
    },
    headerHPadding () {
      return this.$store.getters.getHeaderHPadding
    }
  },
  methods: {
    isGroup,
    dateChange (filter, multipleTime) {
      this.loading = true
      // TODO assetInfo、endpointInfo、echarts等进行不同的处理
      let startTime = bus.formateTimeToTime(filter.start_time)
      let endTime = bus.formateTimeToTime(filter.end_time)
      const step = bus.getStep(startTime, endTime)
      startTime = this.$stringTimeParseToUnix(startTime)
      endTime = this.$stringTimeParseToUnix(endTime)
      const elements = this.chartInfo.elements || []
      if (multipleTime.length) {
        const minusTime = (new Date(bus.formateTimeToTime(filter.start_time)).getTime() - new Date(bus.formateTimeToTime(multipleTime[0])).getTime())
        this.minusTime = minusTime
        this.multipleTime = true
      } else {
        this.minusTime = ''
        this.multipleTime = false
      }
      this.chartInfo.loaded && this.query(elements, startTime, endTime, step)
    },
    // 参数 isRefresh 标识是否是刷新操作
    getChartData (isRefresh, params) {
      this.loading = true
      // TODO assetInfo、endpointInfo、echarts等进行不同的处理
      let startTime = ''
      let endTime = ''
      if (isRefresh) { // 刷新则视情况更新时间范围
        const now = new Date(bus.computeTimezone(new Date().getTime()))
        const origin = new Date(this.timeRange[1])
        const numInterval = now.getTime() - origin.getTime()
        if (numInterval >= 60000) { // 大于1分钟，则start、end均往后移numInterval，否则时间不变
          startTime = bus.getNewTime(bus.formateTimeToTime(this.timeRange[0]), numInterval)
          endTime = bus.timeFormate(now, 'YYYY-MM-DD HH:mm:ss')
        } else {
          startTime = bus.formateTimeToTime(this.timeRange[0])
          endTime = bus.formateTimeToTime(this.timeRange[1])
        }
      } else {
        startTime = bus.formateTimeToTime(this.timeRange[0])
        endTime = bus.formateTimeToTime(this.timeRange[1])
      }
      const step = bus.getStep(startTime, endTime)
      startTime = this.$stringTimeParseToUnix(startTime)
      endTime = this.$stringTimeParseToUnix(endTime)
      const elements = this.chartInfo.elements || []
      this.chartInfo.loaded && this.query(elements, startTime, endTime, step, params)
    },
    query (elements, startTime, endTime, step, params) {
      this.isError = false
      this.allDataLength = 0
      try {
        switch (this.chartInfo.datasource) {
          case 'metrics':
          case 'logs': {
            if (this.from === fromRoute.chartTemp) {
              setTimeout(() => {
                this.chartData = [chartTempData.data.result]
                this.chartData.forEach(item => {
                  item.forEach(children => {
                    children.elements = elements[0]
                  })
                })
                this.loading = false
              }, 100)
              return
            }
            let urlPre = ''
            if (this.chartInfo.datasource === 'metrics') {
              urlPre += '/prom'
            } else if (this.chartInfo.datasource === 'logs') {
              urlPre += '/logs/loki'
            }
            let requests = elements.map((element) => {
              if (this.from === fromRoute.chartTemp) {
                return chartTempData
              }
              let query = `${urlPre}/api/v1/query_range?start=${startTime}&end=${endTime}&step=${step}`
              if (isTimeSeries(this.chartInfo.type)) {
                query += `&nullType=${this.chartInfo.param.nullType || 'null'}`
              }
              if (element.filter) {
                query += `&filter=${element.filter}`
              }
              if (this.chartInfo.datasource === 'logs') {
                query += '&format=1'
                if (!params || params.descending) {
                  this.chartInfo.descending = true
                  query += '&direction=backward'
                } else {
                  this.chartInfo.descending = false
                  query += '&direction=forward'
                }
              }
              // if (isChartPie(this.chartInfo.type)) {
              //   query += `&statistics=${this.chartInfo.param.statistics || 'last'}`
              // }
              query += `&query=${encodeURIComponent(element.expression)}`
              return this.$get(query)
            })
            if (this.multipleTime) {
              const multipleRequests = elements.map((element) => {
                if (this.from === fromRoute.chartTemp) {
                  return chartTempData
                }
                let query = `${urlPre}/api/v1/query_range?start=${startTime - this.minusTime / 1000}&end=${endTime - this.minusTime / 1000}&step=${step}`
                if (isTimeSeries(this.chartInfo.type)) {
                  query += `&nullType=${this.chartInfo.param.nullType || 'null'}`
                }
                if (element.filter) {
                  query += `&filter=${element.filter}`
                }
                if (this.chartInfo.datasource === 'logs') {
                  query += '&format=1'
                }
                // if (isChartPie(this.chartInfo.type)) {
                //   query += `&statistics=${this.chartInfo.param.statistics || 'last'}`
                // }
                query += `&query=${encodeURIComponent(element.expression)}`
                return this.$get(query)
              })
              requests = requests.concat(multipleRequests)
            }
            const chartData = []
            axios.all(requests).then((res) => {
              res.forEach((r, rIndex) => {
                if (rIndex < elements.length) {
                  if (r.status === 'success') {
                    r.data.result.forEach(item => {
                      item.elements = elements[rIndex]
                      this.allDataLength++
                    })
                    chartData.push(r.data.result)
                  } else {
                    chartData.push({ error: r.msg || r.error || r })
                    this.isError = true
                  }
                } else {
                  if (r.status === 'success') {
                    r.data.result.forEach(item => {
                      this.allDataLength++
                      item.values.forEach(values => {
                        values[0] = values[0] + this.minusTime / 1000
                      })
                    })
                    chartData.push(r.data.result)
                  } else {
                    chartData.push({ error: r.msg || r.error || r })
                    this.isError = true
                  }
                }
              })
              this.chartData = chartData
              if (this.chartInfo.type === 'log') {
                this.logChartDataFormat()
              }
            }).catch(res => {
              console.info(res)
            }).finally(() => {
              this.loading = false
            })
            break
          }
        }
      } catch (e) {
        this.loading = false
      }
    },
    resize () {
      this.$refs.chart.resize()
    },
    refresh () {
      this.getChartData(true)
    },
    refreshLogs (params) {
      this.getChartData(true, params)
    },
    logChartDataFormat () {
      this.chartData.forEach((item, index) => {
        const elements = this.chartInfo.elements[index]
        item.forEach(row => {
          row.elements = elements
        })
      })
    },
    showMultiple (type) {
      switch (type) {
        case 'line' :
        case 'area' :
        case 'point' :
          return true
        default: return false
      }
    },
    loadMore () {
      this.showAllData = true
      this.$nextTick(() => {
        this.$refs.chart && this.$refs.chart.$refs['chart' + this.chartInfo.id].initChart()
      })
    },
    showFullscreen (show) {
      this.$emit('showFullscreen', show, this.chartInfo)
    }
  },
  watch: {
    timeRange: {
      deep: true,
      handler (n) {
        this.refresh()
      }
    },
    loading: {
      immediate: true,
      deep: true,
      handler (n) {
        // console.log(n)
      }
    }
  },
  mounted () {
    this.chartInfo.loaded && this.getChartData()
    this.showAllData = !this.showMultiple(this.chartInfo.type)
  }
}
</script>
