<script setup lang="ts">
import dayjs from 'dayjs'
import type { ECharts } from 'echarts/core'
import { DataZoomComponent } from 'echarts/components'
import {
  IotRhDailyReportApi,
  type IotRhDailyReportTotalWorkloadVO
} from '@/api/pms/iotrhdailyreport'
import { useDebounceFn } from '@vueuse/core'
import CountTo from '@/components/count-to1.vue'
import echarts from '@/plugins/echarts'
import UnfilledReportDialog from '../UnfilledReportDialog.vue'

import { Motion, AnimatePresence } from 'motion-v'

import download from '@/utils/download'

import { useTableComponents } from '@/components/ZmTable/useTableComponents'

echarts.use([DataZoomComponent])

interface Query {
  pageNo: number
  pageSize: number
  deptId: number
  contractName?: string
  taskName?: string
  createTime: string[]
}

const props = defineProps<{
  query: Query
  deptName: string
  defaultView?: '表格' | '看板'
  refreshKey: number
}>()

const totalWorkKeys: [string, string, string, string, number][] = [
  ['totalGasInjection', '万方', '累计注气量', 'i-material-symbols:cloud-outline text-sky', 2],
  [
    'totalWaterInjection',
    '万方',
    '累计注水量',
    'i-material-symbols:water-drop-outline-rounded text-sky',
    2
  ],
  [
    'utilizationRate',
    '%',
    '设备利用率',
    'i-material-symbols:check-circle-outline-rounded text-emerald',
    2
  ],
  [
    'totalPowerConsumption',
    'MWh',
    '累计用电量',
    'i-material-symbols:electric-bolt-outline-rounded text-sky',
    2
  ],
  [
    'totalFuelConsumption',
    '升',
    '累计油耗',
    'i-material-symbols:directions-car-outline-rounded text-sky',
    2
  ],
  ['totalCount', '个', '总数', 'i-tabler:report-analytics text-sky', 0],
  [
    'alreadyReported',
    '个',
    '已填报',
    'i-material-symbols:check-circle-outline-rounded text-emerald',
    0
  ],
  ['notReported', '个', '未填报', 'i-material-symbols:cancel-outline-rounded text-rose', 0]
]

const totalWork = ref({
  totalCount: 0,
  alreadyReported: 0,
  notReported: 0,
  totalFuelConsumption: 0,
  totalPowerConsumption: 0,
  totalWaterInjection: 0,
  totalGasInjection: 0,
  utilizationRate: 0
})

const totalLoading = ref(false)

const totalWorkloadDetail = ref({
  totalN2GasInjection: 0,
  totalNaturalGasInjection: 0
})

const formatGasInjectionTooltipValue = (value?: number | null) => ((value || 0) / 10000).toFixed(4)

const getTotal = useDebounceFn(async () => {
  totalLoading.value = true

  const { pageNo, pageSize, ...other } = props.query

  try {
    let res1: any[]
    if (props.query.createTime && props.query.createTime.length === 2) {
      res1 = await IotRhDailyReportApi.rhDailyReportStatistics({
        createTime: props.query.createTime,
        deptId: props.query.deptId
      })

      totalWork.value.totalCount = res1[0].count
      totalWork.value.alreadyReported = res1[1].count
      totalWork.value.notReported = res1[2].count
    }

    const res2: IotRhDailyReportTotalWorkloadVO = await IotRhDailyReportApi.totalWorkload(other)

    totalWorkloadDetail.value = {
      totalN2GasInjection: res2.totalN2GasInjection || 0,
      totalNaturalGasInjection: res2.totalNaturalGasInjection || 0
    }

    totalWork.value = {
      ...totalWork.value,
      ...res2,
      totalPowerConsumption: (res2.totalPowerConsumption || 0) / 1000,
      totalWaterInjection: (res2.totalWaterInjection || 0) / 10000,
      totalGasInjection: (res2.totalGasInjection || 0) / 10000,
      totalFuelConsumption: res2.totalFuelConsumption || 0,
      utilizationRate: Number(((res2.utilizationRate || 0) * 100).toFixed(2))
    }
  } finally {
    totalLoading.value = false
  }
}, 500)

interface List {
  id: number | null
  name: string | null
  type: '1' | '2' | '3'
  cumulativeGasInjection: number | null
  cumulativeWaterInjection: number | null
  cumulativePowerConsumption: number | null
  cumulativeFuelConsumption: number | null
  transitTime: number | null
  nonProductiveTime: number | null
  utilizationRate: number | null
}

const list = ref<List[]>([])

const type = ref('2')

function checkIsSameDay(createTime: string[]): boolean {
  if (!createTime || createTime.length < 2) {
    return false
  }

  const [startTime, endTime] = createTime

  return dayjs(startTime).isSame(endTime, 'day')
}

const columns = (type: string) => {
  return [
    {
      label: type === '2' ? '项目部' : '队伍',
      prop: 'name'
    },
    {
      label: '累计注气量(万方)',
      prop: 'cumulativeGasInjection'
    },
    {
      label: '累计注水量(万方)',
      prop: 'cumulativeWaterInjection'
    },
    {
      label: '累计用电量(MWh)',
      prop: 'cumulativePowerConsumption'
    },
    {
      label: '累计油耗(升)',
      prop: 'cumulativeFuelConsumption'
    },
    {
      label: '平均时效(%)',
      prop: 'hourUtilizationRate'
    },
    {
      label: '非生产时效(%)',
      prop: 'nonProductiveTime'
    },
    ...(type === '2' && checkIsSameDay(props.query.createTime)
      ? [
          {
            label: '队伍总数',
            prop: 'teamCount'
          },
          {
            label: '驻地待命',
            prop: 'zddmTeamCount'
          },
          {
            label: '施工准备',
            prop: 'zbTeamCount'
          },
          {
            label: '施工队伍',
            prop: 'sgTeamCount'
          }
        ]
      : []),
    {
      label: '设备利用率(%)',
      prop: 'utilizationRate',
      action: true
    }
  ]
}

const listLoading = ref(false)

const formatter = (row: List, column: any) => {
  if (column.property === 'transitTime') {
    return (Number(row.transitTime ?? 0) * 100).toFixed(2) + '%'
  } else if (column.property === 'nonProductiveTime') {
    return (Number(row.nonProductiveTime ?? 0) * 100).toFixed(2) + '%'
  } else if (column.property === 'utilizationRate') {
    return (Number(row.utilizationRate ?? 0) * 100).toFixed(2) + '%'
  } else return row[column.property] ?? 0
}

const getList = useDebounceFn(async () => {
  listLoading.value = true
  try {
    const res = await IotRhDailyReportApi.getIotRhDailyReportSummary(props.query)

    const { list: reslist } = res

    type.value = reslist[0]?.type || '2'

    list.value = reslist.map(
      ({ id, projectDeptId, projectDeptName, teamId, teamName, sort, taskId, type, ...other }) => {
        return {
          id: type === '2' ? projectDeptId : teamId,
          name: type === '2' ? projectDeptName : teamName,
          ...other,
          cumulativeGasInjection: ((other.cumulativeGasInjection || 0) / 10000).toFixed(4),
          cumulativeWaterInjection: ((other.cumulativeWaterInjection || 0) / 10000).toFixed(2),
          cumulativePowerConsumption: ((other.cumulativePowerConsumption || 0) / 1000).toFixed(2),
          cumulativeFuelConsumption: (other.cumulativeFuelConsumption || 0).toFixed(2),
          utilizationRate: other.utilizationRate || 0,
          hourUtilizationRate: ((other.hourUtilizationRate || 0) * 100).toFixed(2) + '%'
        }
      }
    )
  } finally {
    listLoading.value = false
  }
}, 500)

const tab = ref<'表格' | '看板'>('表格')

const currentTab = ref<'表格' | '看板'>('表格')

const direction = ref<'left' | 'right'>('right')

const handleSelectTab = (val: '表格' | '看板') => {
  if (tab.value === val && currentTab.value === val) return

  tab.value = val
  direction.value = val === '看板' ? 'right' : 'left'
  nextTick(() => {
    currentTab.value = val
    setTimeout(() => {
      if (val === '看板') scheduleChartRender()
    })
  })
}

watch(
  () => props.defaultView,
  (val) => {
    handleSelectTab(val || '表格')
  },
  { immediate: true }
)

const chartRef = ref<HTMLDivElement | null>(null)
let chart: ECharts | null = null
let chartContainerEl: HTMLDivElement | null = null
let chartRenderRaf = 0

const xAxisData = ref<string[]>([])

type ChartKey =
  | 'cumulativeFuelConsumption'
  | 'cumulativeGasInjection'
  | 'cumulativePowerConsumption'
  | 'cumulativeWaterInjection'
  | 'transitTime'
  | 'utilizationRate'

interface LegendItem {
  name: string
  key: ChartKey
  unit: string
  decimals: number
}

const legendItems: LegendItem[] = [
  { name: '累计油耗 (升)', key: 'cumulativeFuelConsumption', unit: '升', decimals: 2 },
  { name: '累计注气量 (万方)', key: 'cumulativeGasInjection', unit: '万方', decimals: 2 },
  { name: '累计用电量 (KWh)', key: 'cumulativePowerConsumption', unit: 'KWh', decimals: 2 },
  { name: '累计注水量 (方)', key: 'cumulativeWaterInjection', unit: '方', decimals: 2 },
  { name: '平均时效 (%)', key: 'transitTime', unit: '%', decimals: 2 },
  { name: '设备利用率 (%)', key: 'utilizationRate', unit: '%', decimals: 2 }
]

const legendItemMap = legendItems.reduce<Record<string, LegendItem>>((map, item) => {
  map[item.name] = item
  return map
}, {})

const chartData = ref<Record<ChartKey, number[]>>({
  cumulativeFuelConsumption: [],
  cumulativeGasInjection: [],
  cumulativePowerConsumption: [],
  cumulativeWaterInjection: [],
  transitTime: [],
  utilizationRate: []
})

let chartLoading = ref(false)

const getChart = useDebounceFn(async () => {
  chartLoading.value = true

  try {
    const res = await IotRhDailyReportApi.getIotRhDailyReportSummaryPolyline(props.query)

    chartData.value = {
      cumulativeFuelConsumption: res.map((item) => item.cumulativeFuelConsumption || 0),
      // cumulativeFuelConsumption: res.map((item) => (item.cumulativeFuelConsumption || 0) / 10000),
      cumulativeGasInjection: res.map((item) => (item.cumulativeGasInjection || 0) / 10000),
      cumulativePowerConsumption: res.map((item) => item.cumulativePowerConsumption || 0),
      // cumulativePowerConsumption: res.map((item) => (item.cumulativePowerConsumption || 0) / 1000),
      cumulativeWaterInjection: res.map((item) => item.cumulativeWaterInjection || 0),
      // cumulativeWaterInjection: res.map((item) => (item.cumulativeWaterInjection || 0) / 10000),
      transitTime: res.map((item) => (item.transitTime || 0) * 100),
      utilizationRate: res.map((item) => Number(((item.utilizationRate || 0) * 100).toFixed(2)))
    }

    xAxisData.value = res.map((item) => item.reportDate || '')
    resetVisibleZoomRange()
  } finally {
    chartLoading.value = false
  }
}, 500)

const resizer = useDebounceFn(() => {
  chart?.resize()
}, 100)

const selectedLegends = ref<Record<string, boolean>>({})
const visibleZoomRange = ref({
  startIndex: 0,
  endIndex: 0
})

const NORMALIZED_AXIS_MIN = 0
const NORMALIZED_AXIS_MAX = 100
const NORMALIZED_AXIS_CENTER = 50
const NORMALIZED_AXIS_PADDING = 4

const ensureLegendSelection = () => {
  legendItems.forEach(({ name }) => {
    if (selectedLegends.value[name] === undefined) {
      selectedLegends.value[name] = true
    }
  })
}

const resetVisibleZoomRange = () => {
  const lastIndex = Math.max(xAxisData.value.length - 1, 0)

  visibleZoomRange.value = {
    startIndex: 0,
    endIndex: lastIndex
  }
}

const clampZoomIndex = (value: number, lastIndex: number) => {
  return Math.min(Math.max(Math.round(value), 0), lastIndex)
}

const syncVisibleZoomRangeFromChart = () => {
  const lastIndex = Math.max(xAxisData.value.length - 1, 0)

  if (!chart || lastIndex <= 0) {
    resetVisibleZoomRange()
    return
  }

  const dataZoomOptions = chart.getOption().dataZoom
  const primaryDataZoom = Array.isArray(dataZoomOptions) ? dataZoomOptions[0] : undefined

  if (!primaryDataZoom) {
    resetVisibleZoomRange()
    return
  }

  const startValue = Number(primaryDataZoom.startValue)
  const endValue = Number(primaryDataZoom.endValue)

  let nextStartIndex = 0
  let nextEndIndex = lastIndex

  if (Number.isFinite(startValue) && Number.isFinite(endValue)) {
    nextStartIndex = clampZoomIndex(startValue, lastIndex)
    nextEndIndex = clampZoomIndex(endValue, lastIndex)
  } else {
    const startPercent = Number(primaryDataZoom.start ?? 0)
    const endPercent = Number(primaryDataZoom.end ?? 100)

    nextStartIndex = clampZoomIndex((startPercent / 100) * lastIndex, lastIndex)
    nextEndIndex = clampZoomIndex((endPercent / 100) * lastIndex, lastIndex)
  }

  visibleZoomRange.value = {
    startIndex: Math.min(nextStartIndex, nextEndIndex),
    endIndex: Math.max(nextStartIndex, nextEndIndex)
  }
}

const getVisibleDatasetValues = (dataset: number[]) => {
  if (!dataset.length) return []

  const lastIndex = dataset.length - 1
  const startIndex = clampZoomIndex(visibleZoomRange.value.startIndex, lastIndex)
  const endIndex = Math.max(startIndex, clampZoomIndex(visibleZoomRange.value.endIndex, lastIndex))

  return dataset.slice(startIndex, endIndex + 1).filter((value) => Number.isFinite(value))
}

const normalizeSeriesData = (dataset: number[]) => {
  if (!dataset.length) return []

  const validValues = getVisibleDatasetValues(dataset)

  if (!validValues.length) {
    return dataset.map(() => NORMALIZED_AXIS_MIN)
  }

  const min = Math.min(...validValues)
  const max = Math.max(...validValues)

  if (min === max) {
    return dataset.map(() => (min === 0 ? NORMALIZED_AXIS_MIN : NORMALIZED_AXIS_CENTER))
  }

  const usableHeight = NORMALIZED_AXIS_MAX - NORMALIZED_AXIS_MIN - NORMALIZED_AXIS_PADDING * 2

  return dataset.map((value) =>
    Number((NORMALIZED_AXIS_PADDING + ((value - min) / (max - min)) * usableHeight).toFixed(2))
  )
}

const formatTrendAxisLabel = (value: number) => {
  if (value === NORMALIZED_AXIS_MIN) return '低'
  if (value === NORMALIZED_AXIS_CENTER) return '中'
  if (value === NORMALIZED_AXIS_MAX) return '高'
  return ''
}

const formatSeriesValue = (name: string, value: number) => {
  const item = legendItemMap[name]
  const safeValue = Number.isFinite(value) ? value : 0

  if (!item) return safeValue.toFixed(2)

  return `${safeValue.toFixed(item.decimals)} ${item.unit}`
}

const getSeries = () => {
  const enableSampling = xAxisData.value.length > 120

  return legendItems.map((item) => ({
    name: item.name,
    type: 'line',
    smooth: false,
    showSymbol: true,
    symbol: 'circle',
    symbolSize: 6,
    connectNulls: true,
    lineStyle: {
      width: 2
    },
    emphasis: {
      focus: 'series'
    },
    sampling: enableSampling ? 'lttb' : undefined,
    progressive: 300,
    progressiveThreshold: 1500,
    data: normalizeSeriesData(chartData.value[item.key])
  }))
}

const getChartOption = () => ({
  animation: xAxisData.value.length <= 120,
  animationDuration: 280,
  animationDurationUpdate: 180,
  grid: {
    top: 72,
    right: 24,
    bottom: 68,
    left: 48,
    containLabel: true
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: { type: 'line' },
    formatter: (params: any) => {
      const list = Array.isArray(params) ? params : [params]

      if (!list.length) return ''

      const content = list.map((item: any) => {
        const legendItem = legendItemMap[item.seriesName]
        const realValue = legendItem ? (chartData.value[legendItem.key][item.dataIndex] ?? 0) : 0

        return `<div class="flex items-center justify-between mt-1 gap-1">
            <span>${item.marker} ${item.seriesName}</span>
            <span>${formatSeriesValue(item.seriesName, realValue)}</span>
          </div>`
      })

      return `${list[0].axisValueLabel}<br>${content.join('')}`
    }
  },
  legend: {
    type: 'scroll',
    top: 16,
    data: legendItems.map((item) => item.name),
    selected: selectedLegends.value,
    show: true
  },
  xAxis: {
    type: 'category',
    boundaryGap: false,
    data: xAxisData.value,
    axisLabel: {
      hideOverlap: true
    }
  },
  dataZoom: [
    {
      type: 'inside',
      xAxisIndex: 0,
      filterMode: 'none',
      throttle: 50,
      startValue: visibleZoomRange.value.startIndex,
      endValue: visibleZoomRange.value.endIndex
    },
    {
      type: 'slider',
      xAxisIndex: 0,
      filterMode: 'none',
      height: 18,
      bottom: 8,
      brushSelect: false,
      showDetail: false,
      moveHandleSize: 0,
      throttle: 50,
      startValue: visibleZoomRange.value.startIndex,
      endValue: visibleZoomRange.value.endIndex
    }
  ],
  yAxis: {
    type: 'value',
    min: NORMALIZED_AXIS_MIN,
    max: NORMALIZED_AXIS_MAX,
    splitNumber: 4,
    name: '相对趋势',
    nameGap: 16,
    axisLabel: {
      formatter: formatTrendAxisLabel
    },
    splitLine: {
      lineStyle: {
        type: 'dashed'
      }
    }
  },
  series: getSeries()
})

const initChart = () => {
  if (!chartRef.value) return

  if (chart && chartContainerEl === chartRef.value) {
    return
  }

  chart?.dispose()
  window.removeEventListener('resize', resizer)
  chart = echarts.init(chartRef.value, undefined, { renderer: 'canvas', useDirtyRect: true })
  chartContainerEl = chartRef.value
  window.addEventListener('resize', resizer)

  chart.off('legendselectchanged')
  chart.on('legendselectchanged', (params: any) => {
    selectedLegends.value = { ...params.selected }
  })

  chart.off('datazoom')
  chart.on('datazoom', () => {
    syncVisibleZoomRangeFromChart()
    chart?.setOption(
      {
        series: getSeries()
      },
      { lazyUpdate: true }
    )
  })
}

const render = () => {
  if (!chartRef.value) return

  initChart()

  ensureLegendSelection()

  chart?.setOption(getChartOption(), { notMerge: true, lazyUpdate: true })
}

const scheduleChartRender = (attempt = 0) => {
  cancelAnimationFrame(chartRenderRaf)

  chartRenderRaf = requestAnimationFrame(() => {
    chartRenderRaf = 0

    if (currentTab.value !== '看板') return

    const chartEl = chartRef.value

    if (!chartEl || !chartEl.clientWidth || !chartEl.clientHeight) {
      if (attempt < 20) scheduleChartRender(attempt + 1)
      return
    }

    render()
    requestAnimationFrame(() => {
      chart?.resize()
    })
  })
}

onUnmounted(() => {
  cancelAnimationFrame(chartRenderRaf)
  window.removeEventListener('resize', resizer)
  chart?.dispose()
  chart = null
  chartContainerEl = null
})

const handleQuery = () => {
  getChart().then(() => {
    if (currentTab.value === '看板') {
      scheduleChartRender()
    }
  })
  getList()
  getTotal()
}

watch(
  () => [
    props.refreshKey,
    props.query.deptId,
    props.query.contractName,
    props.query.taskName,
    props.query.createTime?.[0],
    props.query.createTime?.[1]
  ],
  () => {
    if (!props.query.createTime) {
      totalWork.value.totalCount = 0
      totalWork.value.notReported = 0
      totalWork.value.alreadyReported = 0
    }
    handleQuery()
  },
  { immediate: true }
)

const exportChart = () => {
  if (!chart) return
  let img = new Image()
  img.src = chart.getDataURL({
    type: 'png',
    pixelRatio: 1,
    backgroundColor: '#fff'
  })

  img.onload = function () {
    let canvas = document.createElement('canvas')
    canvas.width = img.width
    canvas.height = img.height
    let ctx = canvas.getContext('2d')
    ctx?.drawImage(img, 0, 0)
    let dataURL = canvas.toDataURL('image/png')

    let a = document.createElement('a')

    let event = new MouseEvent('click')

    a.href = dataURL
    a.download = `瑞恒日报统计数据.png`
    a.dispatchEvent(event)
  }
}

const exportData = async () => {
  const res = await IotRhDailyReportApi.exportRhDailyReportStatistics(props.query)

  download.excel(res, '瑞恒日报统计数据.xlsx')
}

const exportAll = async () => {
  if (tab.value === '看板') exportChart()
  else exportData()
}

const message = useMessage()

const unfilledDialogRef = ref()

const openUnfilledDialog = () => {
  // 检查是否选择了创建时间
  if (!props.query.createTime || props.query.createTime.length === 0) {
    message.warning('请先选择创建时间范围')
    return
  }

  // 打开弹窗
  unfilledDialogRef.value?.open()
}

const router = useRouter()

const tolist = (id: number, non: boolean = false) => {
  const { pageNo, pageSize, ...rest } = props.query

  router.push({
    path: '/iotdayilyreport/IotRhDailyReport',
    query: {
      ...rest,
      deptId: id,
      ...(non ? { nonProductFlag: 'Y' } : {})
    }
  })
}

const { ZmTable, ZmTableColumn } = useTableComponents()
</script>

<template>
  <div class="grid grid-rows-[96px_1fr] gap-2 h-full min-h-0">
    <div class="grid grid-cols-8 gap-4">
      <template v-for="info in totalWorkKeys" :key="info[0]">
        <el-tooltip :disabled="info[0] !== 'totalGasInjection'" placement="top">
          <template #content>
            <div>
              累计氮气注气量：{{
                formatGasInjectionTooltipValue(totalWorkloadDetail.totalN2GasInjection)
              }}
              万方
            </div>
            <div>
              累计天然气注气量：{{
                formatGasInjectionTooltipValue(totalWorkloadDetail.totalNaturalGasInjection)
              }}
              万方
            </div>
          </template>
          <div
            class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-1 py-2 flex flex-col items-center justify-center gap-0.5 min-w-0">
            <div class="size-6.5" :class="info[3]"></div>

            <count-to
              class="text-xl font-medium leading-6"
              :class="{ 'cursor-help': info[0] === 'totalGasInjection' }"
              :start-val="0"
              :end-val="totalWork[info[0]]"
              :decimals="info[4]"
              @click="info[2] === '未填报' ? openUnfilledDialog() : ''">
              <span class="text-xs leading-8 text-[var(--el-text-color-regular)]">暂无数据</span>
            </count-to>

            <div
              class="text-xs font-medium leading-5 text-[var(--el-text-color-regular)] whitespace-nowrap">
              {{ info[1] ? info[2] + '(' + info[1] + ')' : info[2] }}
            </div>
          </div>
        </el-tooltip>
      </template>
    </div>

    <div class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow flex flex-col p-3 gap-2 min-h-0">
      <div class="flex h-10 items-center justify-between">
        <el-button-group>
          <el-button
            size="default"
            :type="tab === '表格' ? 'primary' : 'default'"
            @click="handleSelectTab('表格')"
            >表格
          </el-button>
          <el-button
            size="default"
            :type="tab === '看板' ? 'primary' : 'default'"
            @click="handleSelectTab('看板')"
            >看板
          </el-button>
        </el-button-group>
        <h3 class="text-xl font-medium">{{ `${props.deptName}-${tab}` }}</h3>
        <el-button size="default" type="primary" @click="exportAll">导出</el-button>
      </div>
      <div class="flex-1 relative min-h-0">
        <el-auto-resizer class="absolute">
          <template #default="{ height }">
            <Motion
              as="div"
              :style="{ position: 'relative', overflow: 'hidden' }"
              :animate="{ height: `${height}px`, width: `100%` }"
              :transition="{ type: 'spring', stiffness: 200, damping: 25, duration: 0.3 }">
              <AnimatePresence :initial="false" mode="sync">
                <Motion
                  :key="currentTab"
                  as="div"
                  :initial="{ x: direction === 'left' ? '-100%' : '100%', opacity: 0 }"
                  :animate="{ x: '0%', opacity: 1 }"
                  :exit="{ x: direction === 'left' ? '50%' : '-50%', opacity: 0 }"
                  :transition="{ type: 'tween', stiffness: 300, damping: 30, duration: 0.3 }"
                  :style="{ position: 'absolute', left: 0, right: 0, top: 0 }">
                  <div :style="{ width: `100%`, height: `${height}px` }">
                    <zm-table
                      v-if="currentTab === '表格'"
                      :loading="listLoading"
                      :data="list"
                      :height="height"
                      :settings-cache="true"
                      settings-cache-key="rhSummary"
                      show-border>
                      <template v-for="item in columns(type)" :key="item.prop">
                        <zm-table-column
                          v-if="item.prop !== 'name' && item.prop !== 'nonProductiveTime'"
                          :label="item.label"
                          :prop="item.prop"
                          :formatter="formatter"
                          :action="item.action" />
                        <zm-table-column
                          v-else-if="item.prop === 'name'"
                          :label="item.label"
                          :prop="item.prop">
                          <template #default="{ row }">
                            <el-button text type="primary" @click.prevent="tolist(row.id)">{{
                              row.name
                            }}</el-button>
                          </template>
                        </zm-table-column>
                        <zm-table-column v-else :label="item.label" :prop="item.prop">
                          <template #default="{ row }">
                            <el-button
                              v-if="row.nonProductiveTime > 0"
                              text
                              type="primary"
                              @click.prevent="tolist(row.id, true)">
                              {{ (Number(row.nonProductiveTime ?? 0) * 100).toFixed(2) + '%' }}
                            </el-button>
                            <span v-else>
                              {{ (Number(row.nonProductiveTime ?? 0) * 100).toFixed(2) + '%' }}
                            </span>
                          </template>
                        </zm-table-column>
                      </template>
                    </zm-table>
                    <div
                      ref="chartRef"
                      v-loading="chartLoading"
                      v-else
                      :style="{ width: `100%`, height: `${height}px` }">
                    </div>
                  </div>
                </Motion>
              </AnimatePresence>
            </Motion>
          </template>
        </el-auto-resizer>
      </div>
    </div>
  </div>

  <UnfilledReportDialog ref="unfilledDialogRef" :query-params="props.query" />
</template>
