"use client"

import React from 'react'
import { ChartDataPoint, ChartSeries } from '../components/advanced-chart'

interface UseChartOptions {
  data: ChartDataPoint[]
  series: ChartSeries[]
  realtime?: boolean
  refreshInterval?: number
  maxDataPoints?: number
}

interface UseChartReturn {
  data: ChartDataPoint[]
  series: ChartSeries[]
  isLoading: boolean
  error: string | null
  addDataPoint: (point: ChartDataPoint) => void
  updateSeries: (seriesUpdate: Partial<ChartSeries>[]) => void
  toggleSeries: (dataKey: string) => void
  resetData: () => void
  exportData: (format: 'csv' | 'json') => void
  getStats: () => {
    total: number
    average: number
    min: number
    max: number
    trend: 'up' | 'down' | 'neutral'
  }
}

export function useChart({
  data: initialData,
  series: initialSeries,
  realtime = false,
  refreshInterval = 5000,
  maxDataPoints = 100,
}: UseChartOptions): UseChartReturn {
  const [data, setData] = React.useState<ChartDataPoint[]>(initialData)
  const [series, setSeries] = React.useState<ChartSeries[]>(initialSeries)
  const [isLoading, setIsLoading] = React.useState(false)
  const [error, setError] = React.useState<string | null>(null)

  // Realtime data updates
  React.useEffect(() => {
    if (!realtime) return

    const interval = setInterval(() => {
      // This would typically fetch new data from an API
      // For demo purposes, we'll simulate data updates
      setData(prevData => {
        const newData = [...prevData]
        
        // Keep only the last maxDataPoints
        if (newData.length >= maxDataPoints) {
          newData.shift()
        }

        // Add simulated new data point
        const lastPoint = newData[newData.length - 1]
        if (lastPoint) {
          const newPoint: ChartDataPoint = { ...lastPoint }
          
          // Simulate data changes for each series
          series.forEach(s => {
            if (typeof lastPoint[s.dataKey] === 'number') {
              const currentValue = lastPoint[s.dataKey] as number
              const change = (Math.random() - 0.5) * currentValue * 0.1
              newPoint[s.dataKey] = Math.max(0, currentValue + change)
            }
          })

          // Update timestamp if exists
          if ('timestamp' in newPoint) {
            newPoint.timestamp = Date.now()
          }

          newData.push(newPoint)
        }

        return newData
      })
    }, refreshInterval)

    return () => clearInterval(interval)
  }, [realtime, refreshInterval, maxDataPoints, series])

  const addDataPoint = React.useCallback((point: ChartDataPoint) => {
    setData(prevData => {
      const newData = [...prevData, point]
      
      // Keep only the last maxDataPoints
      if (newData.length > maxDataPoints) {
        return newData.slice(-maxDataPoints)
      }
      
      return newData
    })
  }, [maxDataPoints])

  const updateSeries = React.useCallback((seriesUpdate: Partial<ChartSeries>[]) => {
    setSeries(prevSeries => {
      return prevSeries.map(s => {
        const update = seriesUpdate.find(u => u.dataKey === s.dataKey)
        return update ? { ...s, ...update } : s
      })
    })
  }, [])

  const toggleSeries = React.useCallback((dataKey: string) => {
    setSeries(prevSeries => {
      return prevSeries.map(s => 
        s.dataKey === dataKey ? { ...s, hide: !s.hide } : s
      )
    })
  }, [])

  const resetData = React.useCallback(() => {
    setData(initialData)
    setSeries(initialSeries)
    setError(null)
  }, [initialData, initialSeries])

  const exportData = React.useCallback((format: 'csv' | 'json') => {
    try {
      if (format === 'csv') {
        const headers = Object.keys(data[0] || {})
        const csvContent = [
          headers.join(','),
          ...data.map(row => 
            headers.map(header => {
              const value = row[header]
              if (typeof value === 'string' && (value.includes(',') || value.includes('"'))) {
                return `"${value.replace(/"/g, '""')}"`
              }
              return value
            }).join(',')
          )
        ].join('\n')

        const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
        const link = document.createElement('a')
        link.href = URL.createObjectURL(blob)
        link.download = 'chart-data.csv'
        link.click()
      } else if (format === 'json') {
        const jsonContent = JSON.stringify({ data, series }, null, 2)
        const blob = new Blob([jsonContent], { type: 'application/json;charset=utf-8;' })
        const link = document.createElement('a')
        link.href = URL.createObjectURL(blob)
        link.download = 'chart-data.json'
        link.click()
      }
    } catch (err) {
      setError('Failed to export data')
    }
  }, [data, series])

  const getStats = React.useCallback(() => {
    if (!data.length || !series.length) {
      return { total: 0, average: 0, min: 0, max: 0, trend: 'neutral' as const }
    }

    const firstSeries = series[0]
    const values = data
      .map(d => Number(d[firstSeries.dataKey]))
      .filter(v => !isNaN(v))

    if (!values.length) {
      return { total: 0, average: 0, min: 0, max: 0, trend: 'neutral' as const }
    }

    const total = values.reduce((sum, val) => sum + val, 0)
    const average = total / values.length
    const min = Math.min(...values)
    const max = Math.max(...values)

    // Calculate trend
    let trend: 'up' | 'down' | 'neutral' = 'neutral'
    if (values.length >= 2) {
      const first = values[0]
      const last = values[values.length - 1]
      const change = ((last - first) / first) * 100
      
      if (change > 5) trend = 'up'
      else if (change < -5) trend = 'down'
    }

    return { total, average, min, max, trend }
  }, [data, series])

  return {
    data,
    series,
    isLoading,
    error,
    addDataPoint,
    updateSeries,
    toggleSeries,
    resetData,
    exportData,
    getStats,
  }
}
