<template>
  <el-row :gutter="20">
    <el-col :span="6" :xs="24">
      <ContentWrap class="h-1/1">
        <el-input
          v-model="keyword"
          clearable
          placeholder="搜索设备或参数"
          class="!w-1/1"
          @input="handleKeywordChange"
        />
        <div class="mt-12px">
          <el-tree
            ref="treeRef"
            v-loading="treeLoading"
            :data="treeData"
            :props="treeProps"
            node-key="id"
            highlight-current
            :expand-on-click-node="false"
            :filter-node-method="filterTreeNode"
            @node-click="handleTreeNodeClick"
          />
        </div>
      </ContentWrap>
    </el-col>

    <el-col :span="18" :xs="24">
      <ContentWrap>
        <el-form class="-mb-15px" :inline="true">
          <el-form-item label="时间">
            <el-date-picker
              v-model="dateRange"
              type="daterange"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              value-format="YYYY-MM-DD"
              :shortcuts="dateShortcuts"
              :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
              class="!w-360px"
            />
          </el-form-item>
          <el-form-item>
            <el-button :disabled="!selectedParam" @click="handleQuery">
              <Icon icon="ep:search" class="mr-5px" /> 搜索
            </el-button>
            <el-button :disabled="!selectedParam" @click="resetQuery">
              <Icon icon="ep:refresh" class="mr-5px" /> 重置
            </el-button>
          </el-form-item>
        </el-form>
      </ContentWrap>

      <ContentWrap>
        <el-alert
          v-if="selectedParam"
          :title="selectedParamTitle"
          type="info"
          :closable="false"
          class="mb-12px"
        />
        <div v-loading="chartLoading">
          <el-empty v-if="!selectedParam" description="请选择左侧参数" />
          <EChart v-else :options="chartOption" height="520px" />
        </div>
      </ContentWrap>
    </el-col>
  </el-row>
</template>

<script setup lang="ts">
import type { EChartsOption } from 'echarts'
import dayjs from 'dayjs'
import { Echart as EChart } from '@/components/Echart'

defineOptions({ name: 'DeviceParamAnalysis' })

type TreeNodeType = 'device' | 'param'

type DeviceTreeNode = {
  id: string
  label: string
  type: TreeNodeType
  children?: DeviceTreeNode[]
  deviceId?: string
  paramKey?: string
  unit?: string
}

const message = useMessage()

const treeRef = ref()
const treeLoading = ref(false)
const keyword = ref('')
const treeProps = { children: 'children', label: 'label' }
const treeData = ref<DeviceTreeNode[]>([])

const selectedParam = ref<DeviceTreeNode | null>(null)
const chartLoading = ref(false)
const chartXAxis = ref<string[]>([])
const chartSeries = ref<number[]>([])

const buildDefaultDateRange = (): [string, string] => {
  const end = dayjs().endOf('day')
  const start = end.subtract(6, 'day').startOf('day')
  return [start.format('YYYY-MM-DD'), end.format('YYYY-MM-DD')]
}

const dateRange = ref<[string, string]>(buildDefaultDateRange())

const dateShortcuts = [
  {
    text: '最近 7 天',
    value: () => {
      const end = dayjs().endOf('day').toDate()
      const start = dayjs().subtract(6, 'day').startOf('day').toDate()
      return [start, end]
    }
  },
  {
    text: '上周',
    value: () => {
      const start = dayjs().subtract(1, 'week').startOf('week').toDate()
      const end = dayjs().subtract(1, 'week').endOf('week').toDate()
      return [start, end]
    }
  },
  {
    text: '上个月',
    value: () => {
      const start = dayjs().subtract(1, 'month').startOf('month').toDate()
      const end = dayjs().subtract(1, 'month').endOf('month').toDate()
      return [start, end]
    }
  },
  {
    text: '三个月内',
    value: () => {
      const end = dayjs().endOf('day').toDate()
      const start = dayjs().subtract(3, 'month').startOf('day').toDate()
      return [start, end]
    }
  }
]

const selectedParamTitle = computed(() => {
  const param = selectedParam.value
  if (!param) return ''
  const unitText = param.unit ? `（${param.unit}）` : ''
  return `参数：${param.label}${unitText}`
})

const chartOption = computed<EChartsOption>(() => {
  const unit = selectedParam.value?.unit
  return {
    tooltip: { trigger: 'axis' },
    grid: { left: 30, right: 20, top: 20, bottom: 40, containLabel: true },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: chartXAxis.value
    },
    yAxis: {
      type: 'value',
      name: unit || ''
    },
    series: [
      {
        type: 'line',
        name: selectedParam.value?.label || '参数',
        smooth: true,
        showSymbol: false,
        data: chartSeries.value
      }
    ]
  }
})

const handleKeywordChange = () => {
  treeRef.value?.filter(keyword.value)
}

const filterTreeNode = (value: string, data: DeviceTreeNode) => {
  if (!value) return true
  return data.label?.toLowerCase().includes(value.toLowerCase())
}

const mockFetchTree = async (): Promise<DeviceTreeNode[]> => {
  const devices = [
    { id: 'D-1001', label: '压合机-01' },
    { id: 'D-1002', label: '烘干线-02' },
    { id: 'D-1003', label: '制浆机-03' },
    { id: 'D-1004', label: '包装机-04' }
  ]

  const params = [
    { key: 'temp', label: '温度', unit: '℃' },
    { key: 'pressure', label: '压力', unit: 'kPa' },
    { key: 'speed', label: '速度', unit: 'm/s' },
    { key: 'power', label: '功率', unit: 'kW' },
    { key: 'current', label: '电流', unit: 'A' }
  ]

  await new Promise((resolve) => setTimeout(resolve, 200))

  return devices.map((d) => ({
    id: d.id,
    label: d.label,
    type: 'device',
    deviceId: d.id,
    children: params.map((p) => ({
      id: `${d.id}::${p.key}`,
      label: p.label,
      type: 'param',
      deviceId: d.id,
      paramKey: p.key,
      unit: p.unit
    }))
  }))
}

const buildSeriesSeed = (key: string) => {
  let hash = 0
  for (let i = 0; i < key.length; i++) {
    hash = (hash << 5) - hash + key.charCodeAt(i)
    hash |= 0
  }
  return Math.abs(hash)
}

const mockFetchSeries = async (args: { deviceId: string; paramKey: string; start: string; end: string }) => {
  await new Promise((resolve) => setTimeout(resolve, 250))

  const start = dayjs(args.start)
  const end = dayjs(args.end)
  const diff = Math.max(end.startOf('day').diff(start.startOf('day'), 'day'), 0)
  const count = Math.min(diff + 1, 366)
  const x: string[] = []
  const y: number[] = []
  const seed = buildSeriesSeed(`${args.deviceId}::${args.paramKey}`)
  const base = 20 + (seed % 30)
  const amp = 5 + (seed % 10)

  for (let i = 0; i < count; i++) {
    const d = start.add(i, 'day')
    x.push(d.format('YYYY-MM-DD'))
    const v = base + Math.sin(i / 2) * amp + ((seed % 7) - 3) * 0.6
    y.push(Number(v.toFixed(2)))
  }
  return { x, y }
}

const loadTree = async () => {
  treeLoading.value = true
  try {
    treeData.value = await mockFetchTree()
  } finally {
    treeLoading.value = false
  }
}

const ensureDateRange = () => {
  if (!dateRange.value || dateRange.value.length !== 2) {
    dateRange.value = buildDefaultDateRange()
  }
}

const fetchChart = async () => {
  const param = selectedParam.value
  if (!param?.deviceId || !param.paramKey) return

  ensureDateRange()
  const [start, end] = dateRange.value
  if (!start || !end) return

  chartLoading.value = true
  try {
    const res = await mockFetchSeries({ deviceId: param.deviceId, paramKey: param.paramKey, start, end })
    chartXAxis.value = res.x
    chartSeries.value = res.y
  } catch {
    message.error('获取图表数据失败')
  } finally {
    chartLoading.value = false
  }
}

const handleTreeNodeClick = async (data: DeviceTreeNode) => {
  if (data.type !== 'param') return
  selectedParam.value = data
  dateRange.value = buildDefaultDateRange()
  await fetchChart()
}

const handleQuery = async () => {
  if (!selectedParam.value) return
  await fetchChart()
}

const resetQuery = async () => {
  dateRange.value = buildDefaultDateRange()
  await fetchChart()
}

onMounted(async () => {
  await loadTree()
})
</script>

<style scoped lang="scss">
:deep(.el-tree) {
  max-height: calc(100vh - 280px);
  overflow: auto;
}
</style>
