/**
 * useTrendChart
 *
 * Composable that manages a combined bar+line ECharts trend chart.
 * Features:
 *  - Tree-shakeable ECharts import (core + only used chart types/components)
 *  - Auto resize via ResizeObserver
 *  - DataZoom slider for 30+ day ranges
 *  - Day-over-day delta in tooltips
 *  - Average markLine
 *  - Period summary callback
 *  - Proper cleanup on unmount
 */
import { ref, watch, nextTick, onUnmounted, type Ref } from 'vue'
import { init, use, graphic } from 'echarts/core'
import { BarChart, LineChart } from 'echarts/charts'
import {
  TooltipComponent,
  GridComponent,
  LegendComponent,
  DataZoomSliderComponent,
  MarkLineComponent,
} from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
import type { ECharts, EChartsCoreOption } from 'echarts/core'

// Register only the features we actually use
use([
  BarChart, LineChart,
  TooltipComponent, GridComponent, LegendComponent,
  DataZoomSliderComponent, MarkLineComponent,
  CanvasRenderer,
])

const { LinearGradient } = graphic

export interface TrendDataPoint {
  date: string
  searches: number
  saves: number
  searchDelta: number
  saveDelta: number
}

export interface TrendSummary {
  totalSearches: number
  totalSaves: number
  avgSearches: number
  avgSaves: number
  peakDay: string
  peakSearches: number
  peakSaves: number
  dayCount: number
}

export function useTrendChart(
  trendData: Ref<TrendDataPoint[]>,
  onSummary?: Ref<TrendSummary | null> | ((s: TrendSummary) => void),
) {
  const chartRef = ref<HTMLDivElement | null>(null)
  let chartInstance: ECharts | null = null
  let resizeObserver: ResizeObserver | null = null

  const BAR_WIDTH_PCT = '35%'
  const BAR_GAP_PCT = '30%'

  function computeSummary(data: TrendDataPoint[]): TrendSummary {
    const totalSearches = data.reduce((s, d) => s + d.searches, 0)
    const totalSaves = data.reduce((s, d) => s + d.saves, 0)
    const n = data.length || 1
    let peakIdx = 0
    let peakVal = 0
    data.forEach((d, i) => {
      const v = d.searches + d.saves
      if (v > peakVal) { peakVal = v; peakIdx = i }
    })
    return {
      totalSearches,
      totalSaves,
      avgSearches: Math.round(totalSearches / n),
      avgSaves: Math.round(totalSaves / n),
      peakDay: data[peakIdx]?.date?.slice(5) || '—',
      peakSearches: data[peakIdx]?.searches || 0,
      peakSaves: data[peakIdx]?.saves || 0,
      dayCount: n,
    }
  }

  function render() {
    const el = chartRef.value
    const data = trendData.value
    if (!el) return

    // Compute summary and emit
    const summary = computeSummary(data)
    if (typeof onSummary === 'function') {
      onSummary(summary)
    } else if (onSummary) {
      onSummary.value = summary
    }

    // Empty state
    if (!data.length) {
      if (chartInstance) {
        chartInstance.dispose()
        chartInstance = null
      }
      el.innerHTML = '<div style="display:flex;align-items:center;justify-content:center;height:100%;color:#909399;font-size:13px;">暂无使用数据</div>'
      return
    }

    // Handle DOM element recreation (v-if remounts chart div when navigating away & back)
    if (!chartInstance || chartInstance.getDom() !== el) {
      if (chartInstance) chartInstance.dispose()
      chartInstance = init(el)
      initResize()
    }

    const dates = data.map(d => d.date.slice(5)) // MM-DD
    const n = data.length
    const maxCount = Math.max(...data.map(d => Math.max(d.searches, d.saves)), 1)
    const yMax = Math.ceil(maxCount * 1.35) || 1
    const avgSearches = Math.round(summary.totalSearches / n)
    const showDataZoom = n >= 30

    const option: EChartsCoreOption = {
      tooltip: {
        trigger: 'axis',
        axisPointer: { type: 'shadow' },
        backgroundColor: 'rgba(255,255,255,0.97)',
        borderColor: '#e8e8e8',
        borderWidth: 1,
        borderRadius: 8,
        padding: [10, 14],
        textStyle: { fontSize: 12, color: '#303133' },
        formatter: (params: any) => {
          const idx = params[0]?.dataIndex ?? 0
          const dateLabel = data[idx]?.date || ''
          const d = data[idx]
          const seen = new Set<string>()
          const items = params.filter((p: any) => {
            const key = p.seriesName
            if (seen.has(key)) return false
            seen.add(key)
            return true
          })
          let html = `<div style="font-weight:700;font-size:13px;margin-bottom:8px;color:#1a1a2e">${dateLabel}</div>`
          items.forEach((p: any) => {
            const rawVal = p.value
            const val = Array.isArray(rawVal) ? rawVal[1] : rawVal
            const isBar = p.seriesType === 'bar'
            const isSearch = p.seriesName === '搜索'
            const delta = isSearch ? d?.searchDelta : d?.saveDelta
            const deltaStr = delta !== undefined && delta !== 0
              ? `<span style="margin-left:6px;font-size:11px;color:${delta > 0 ? '#f56c6c' : '#67c23a'}">${delta > 0 ? '↑' : '↓'}${Math.abs(delta)}</span>`
              : (delta === 0 ? '<span style="margin-left:6px;font-size:11px;color:#909399">→0</span>' : '')
            const icon = isBar
              ? `<span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:${p.color};vertical-align:middle"></span>`
              : `<span style="display:inline-block;width:14px;height:2px;background:${p.color};vertical-align:middle"></span>`
            html += `<div style="display:flex;align-items:center;gap:6px;margin-top:4px">${icon}<span>${p.seriesName}：<b>${val}</b> 次${deltaStr}</span></div>`
          })
          return html
        },
      },
      legend: {
        data: ['搜索', '保存'],
        bottom: showDataZoom ? 30 : 0,
        left: 'center',
        itemWidth: 14,
        itemHeight: 10,
        textStyle: { fontSize: 11, color: '#666' },
      },
      grid: {
        left: 8,
        right: 12,
        top: 28,
        bottom: showDataZoom ? 70 : 42,
        containLabel: true,
      },
      xAxis: {
        type: 'category',
        data: dates,
        axisLabel: {
          interval: 0,
          fontSize: 11,
          color: '#909399',
          rotate: n > 15 ? 45 : 0,
        },
        axisLine: { lineStyle: { color: '#e8e8e8' } },
        splitLine: { show: false },
        axisTick: { show: false },
      },
      yAxis: {
        type: 'value',
        name: '次',
        nameTextStyle: { fontSize: 10, color: '#909399' },
        min: 0,
        max: yMax,
        splitNumber: 4,
        axisLabel: {
          fontSize: 10, color: '#909399' },
        splitLine: { lineStyle: { color: '#f5f5f5', type: 'dashed' } },
      },
      series: [
        // Bar — 搜索
        {
          name: '搜索',
          type: 'bar',
          data: data.map(d => d.searches),
          barWidth: BAR_WIDTH_PCT,
          barGap: BAR_GAP_PCT,
          itemStyle: {
            color: new LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: '#6366f1' },
              { offset: 1, color: '#a5b4fc' },
            ]),
            borderRadius: [4, 4, 0, 0],
          },
          emphasis: {
            itemStyle: {
              color: new LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: '#4f46e5' },
                { offset: 1, color: '#818cf8' },
              ]),
            },
          },
          animationDuration: 500,
          animationEasing: 'cubicOut',
        },
        // Bar — 保存
        {
          name: '保存',
          type: 'bar',
          data: data.map(d => d.saves),
          barWidth: BAR_WIDTH_PCT,
          barGap: BAR_GAP_PCT,
          itemStyle: {
            color: new LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: '#10b981' },
              { offset: 1, color: '#6ee7b7' },
            ]),
            borderRadius: [4, 4, 0, 0],
          },
          emphasis: {
            itemStyle: {
              color: new LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: '#059669' },
                { offset: 1, color: '#34d399' },
              ]),
            },
          },
          animationDuration: 500,
          animationEasing: 'cubicOut',
        },
        // Line — 搜索
        {
          name: '搜索',
          type: 'line',
          smooth: true,
          symbol: 'circle',
          symbolSize: 5,
          data: data.map(d => d.searches),
          lineStyle: { width: 2.5, color: '#4f46e5' },
          itemStyle: { color: '#4f46e5', borderColor: '#fff', borderWidth: 2 },
          areaStyle: {
            color: new LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: 'rgba(99,102,241,0.12)' },
              { offset: 1, color: 'rgba(99,102,241,0.01)' },
            ]),
          },
          label: {
            show: false,
          },
          connectNulls: true,
          animationDuration: 700,
          animationEasing: 'cubicOut',
          z: 3,
          markLine: avgSearches > 0 ? {
            silent: true,
            symbol: 'none',
            lineStyle: { color: '#6366f1', type: 'dashed', width: 1, opacity: 0.5 },
            label: {
              formatter: `均 ${avgSearches}`,
              position: 'insideEndTop',
              fontSize: 10,
              color: '#6366f1',
            },
            data: [{ yAxis: avgSearches, name: '日均搜索' }],
          } : undefined,
        },
        // Line — 保存
        {
          name: '保存',
          type: 'line',
          smooth: true,
          symbol: 'circle',
          symbolSize: 5,
          data: data.map(d => d.saves),
          lineStyle: { width: 2.5, color: '#059669' },
          itemStyle: { color: '#059669', borderColor: '#fff', borderWidth: 2 },
          areaStyle: {
            color: new LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: 'rgba(16,185,129,0.12)' },
              { offset: 1, color: 'rgba(16,185,129,0.01)' },
            ]),
          },
          label: {
            show: false,
          },
          connectNulls: true,
          animationDuration: 700,
          animationEasing: 'cubicOut',
          z: 3,
          markLine: avgSearches > 0 ? {
            silent: true,
            symbol: 'none',
            lineStyle: { color: '#10b981', type: 'dashed', width: 1, opacity: 0.5 },
            label: {
              formatter: `均 ${Math.round(summary.totalSaves / n)}`,
              position: 'insideEndTop',
              fontSize: 10,
              color: '#10b981',
            },
            data: [{ yAxis: Math.round(summary.totalSaves / n), name: '日均保存' }],
          } : undefined,
        },
      ],
      // DataZoom slider for 30+ day views
      ...(showDataZoom ? {
        dataZoom: [{
          type: 'slider',
          bottom: 6,
          height: 20,
          start: 0,
          end: 100,
          borderColor: '#e8e8e8',
          fillerColor: 'rgba(99,102,241,0.08)',
          handleStyle: { color: '#6366f1', borderColor: '#6366f1' },
          textStyle: { fontSize: 10, color: '#909399' },
        }],
      } : {}),
    }

    chartInstance.setOption(option, true)
  }

  // Auto-render when data changes
  watch(
    trendData,
    () => {
      nextTick(() => render())
    },
    { deep: true },
  )

  // Setup ResizeObserver for responsive chart
  function initResize() {
    if (!chartRef.value) return
    if (resizeObserver) {
      resizeObserver.disconnect()
      resizeObserver = null
    }
    resizeObserver = new ResizeObserver(() => {
      chartInstance?.resize()
    })
    resizeObserver.observe(chartRef.value)
  }

  // Cleanup
  onUnmounted(() => {
    resizeObserver?.disconnect()
    resizeObserver = null
    chartInstance?.dispose()
    chartInstance = null
  })

  return {
    chartRef,
    render,
    initResize,
  }
}
