import React, { useState, useMemo } from 'react'
import { Line, Bar } from 'react-chartjs-2'
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  BarElement,
  Title,
  Tooltip,
  Legend,
  Filler,
  TimeScale,
} from 'chart.js'
import 'chartjs-adapter-date-fns'
import { 
  TrendingUp, 
  TrendingDown, 
  BarChart3, 
  LineChart, 
  Download,
  Maximize2,
  Settings,
  Calendar,
  Filter
} from 'lucide-react'

ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  BarElement,
  Title,
  Tooltip,
  Legend,
  Filler,
  TimeScale
)

const TimeSeriesChart = ({ 
  data = [], 
  type = 'line',
  height = 400,
  title = 'Time Series Analysis',
  subtitle = '',
  showControls = true,
  showTrends = true,
  showForecast = false,
  forecastData = [],
  onExport,
  onFullscreen
}) => {
  const [chartType, setChartType] = useState(type)
  const [timeRange, setTimeRange] = useState('all')
  const [showSettings, setShowSettings] = useState(false)
  const [chartSettings, setChartSettings] = useState({
    showGrid: true,
    showLegend: true,
    showDataLabels: false,
    smoothLines: true,
    fillArea: true
  })

  // Process data based on time range
  const processedData = useMemo(() => {
    if (!data || data.length === 0) return { labels: [], datasets: [] }

    let filteredData = [...data]
    const now = new Date()

    // Apply time range filter
    switch (timeRange) {
      case '7d':
        filteredData = data.filter(item => 
          new Date(item.date) >= new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000)
        )
        break
      case '30d':
        filteredData = data.filter(item => 
          new Date(item.date) >= new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000)
        )
        break
      case '90d':
        filteredData = data.filter(item => 
          new Date(item.date) >= new Date(now.getTime() - 90 * 24 * 60 * 60 * 1000)
        )
        break
      case '1y':
        filteredData = data.filter(item => 
          new Date(item.date) >= new Date(now.getTime() - 365 * 24 * 60 * 60 * 1000)
        )
        break
      default:
        filteredData = data
    }

    // Sort by date
    filteredData.sort((a, b) => new Date(a.date) - new Date(b.date))

    const labels = filteredData.map(item => 
      new Date(item.date).toLocaleDateString('en-US', { 
        month: 'short', 
        day: 'numeric',
        ...(timeRange === '1y' || timeRange === 'all' ? { year: '2-digit' } : {})
      })
    )

    // Calculate trends
    const calculateTrend = (values) => {
      if (values.length < 2) return 0
      const first = values[0]
      const last = values[values.length - 1]
      return ((last - first) / first) * 100
    }

    const transactionValues = filteredData.map(item => item.transactions || item.value || 0)
    const valueValues = filteredData.map(item => item.value || 0)

    const transactionTrend = calculateTrend(transactionValues)
    const valueTrend = calculateTrend(valueValues)

    const datasets = [
      {
        label: 'Transactions',
        data: transactionValues,
        borderColor: 'rgb(59, 130, 246)',
        backgroundColor: chartSettings.fillArea ? 'rgba(59, 130, 246, 0.1)' : 'transparent',
        tension: chartSettings.smoothLines ? 0.4 : 0,
        fill: chartSettings.fillArea,
        pointRadius: chartSettings.showDataLabels ? 4 : 0,
        pointHoverRadius: 6,
        pointBackgroundColor: 'rgb(59, 130, 246)',
        pointBorderColor: '#ffffff',
        pointBorderWidth: 2,
        trend: transactionTrend
      }
    ]

    // Add value dataset if available
    if (filteredData.some(item => item.value)) {
      datasets.push({
        label: 'Value (AED)',
        data: valueValues.map(val => val / 1000000), // Convert to millions
        borderColor: 'rgb(16, 185, 129)',
        backgroundColor: chartSettings.fillArea ? 'rgba(16, 185, 129, 0.1)' : 'transparent',
        tension: chartSettings.smoothLines ? 0.4 : 0,
        fill: chartSettings.fillArea,
        pointRadius: chartSettings.showDataLabels ? 4 : 0,
        pointHoverRadius: 6,
        pointBackgroundColor: 'rgb(16, 185, 129)',
        pointBorderColor: '#ffffff',
        pointBorderWidth: 2,
        yAxisID: 'y1',
        trend: valueTrend
      })
    }

    // Add forecast data if available
    if (showForecast && forecastData.length > 0) {
      const forecastLabels = forecastData.map(item => 
        new Date(item.date).toLocaleDateString('en-US', { 
          month: 'short', 
          day: 'numeric',
          ...(timeRange === '1y' || timeRange === 'all' ? { year: '2-digit' } : {})
        })
      )
      
      datasets.push({
        label: 'Forecast',
        data: forecastData.map(item => item.predicted_value || item.value || 0),
        borderColor: 'rgb(168, 85, 247)',
        backgroundColor: 'transparent',
        borderDash: [5, 5],
        tension: 0.4,
        fill: false,
        pointRadius: 0,
        pointHoverRadius: 4,
        pointBackgroundColor: 'rgb(168, 85, 247)',
        pointBorderColor: '#ffffff',
        pointBorderWidth: 2
      })

      return {
        labels: [...labels, ...forecastLabels],
        datasets: datasets.map(dataset => ({
          ...dataset,
          data: [...dataset.data, ...(dataset.label === 'Forecast' ? 
            forecastData.map(item => item.predicted_value || item.value || 0) : 
            new Array(forecastData.length).fill(null)
          )]
        }))
      }
    }

    return { labels, datasets }
  }, [data, timeRange, chartSettings, showForecast, forecastData])

  const chartOptions = {
    responsive: true,
    maintainAspectRatio: false,
    interaction: {
      mode: 'index',
      intersect: false,
    },
    plugins: {
      legend: {
        display: chartSettings.showLegend,
        position: 'top',
        labels: {
          usePointStyle: true,
          padding: 20,
          font: {
            size: 12,
            weight: '500'
          }
        }
      },
      tooltip: {
        mode: 'index',
        intersect: false,
        backgroundColor: 'rgba(0, 0, 0, 0.8)',
        titleColor: 'white',
        bodyColor: 'white',
        borderColor: 'rgba(255, 255, 255, 0.1)',
        borderWidth: 1,
        cornerRadius: 8,
        displayColors: true,
        callbacks: {
          label: function(context) {
            if (context.datasetIndex === 1) {
              return `${context.dataset.label}: AED ${context.parsed.y.toFixed(1)}M`
            }
            return `${context.dataset.label}: ${context.parsed.y.toLocaleString()}`
          }
        }
      }
    },
    scales: {
      x: {
        display: true,
        grid: {
          display: chartSettings.showGrid,
          color: 'rgba(0, 0, 0, 0.05)',
          drawBorder: false
        },
        ticks: {
          font: {
            size: 11
          },
          color: '#6B7280',
          maxRotation: 45,
          minRotation: 0
        }
      },
      y: {
        type: 'linear',
        display: true,
        position: 'left',
        beginAtZero: true,
        grid: {
          display: chartSettings.showGrid,
          color: 'rgba(0, 0, 0, 0.05)',
          drawBorder: false
        },
        ticks: {
          callback: function(value) {
            return value.toLocaleString()
          },
          font: {
            size: 11
          },
          color: '#6B7280'
        }
      },
      y1: {
        type: 'linear',
        display: true,
        position: 'right',
        beginAtZero: true,
        grid: {
          drawOnChartArea: false,
        },
        ticks: {
          callback: function(value) {
            return `AED ${value.toFixed(1)}M`
          },
          font: {
            size: 11
          },
          color: '#6B7280'
        }
      }
    },
    elements: {
      line: {
        tension: chartSettings.smoothLines ? 0.4 : 0,
        borderWidth: 3
      },
      point: {
        radius: chartSettings.showDataLabels ? 4 : 0,
        hoverRadius: 6,
        borderWidth: 2
      }
    }
  }

  const handleExport = () => {
    if (onExport) {
      onExport(processedData)
    }
  }

  const handleFullscreen = () => {
    if (onFullscreen) {
      onFullscreen(processedData)
    }
  }

  const renderChart = () => {
    if (chartType === 'bar') {
      return <Bar data={processedData} options={chartOptions} />
    }
    return <Line data={processedData} options={chartOptions} />
  }

  return (
    <div className="bg-white dark:bg-gray-800 rounded-2xl shadow-xl border border-gray-200 dark:border-gray-700">
      {/* Header */}
      <div className="p-6 border-b border-gray-200 dark:border-gray-700">
        <div className="flex items-center justify-between mb-4">
          <div>
            <h3 className="text-lg font-bold text-gray-900 dark:text-white mb-1">
              {title}
            </h3>
            {subtitle && (
              <p className="text-sm text-gray-600 dark:text-gray-400">
                {subtitle}
              </p>
            )}
          </div>
          
          {showControls && (
            <div className="flex items-center space-x-2">
              <button
                onClick={() => setShowSettings(!showSettings)}
                className="p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
                title="Chart Settings"
              >
                <Settings className="h-4 w-4" />
              </button>
              <button
                onClick={handleExport}
                className="p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
                title="Export Chart"
              >
                <Download className="h-4 w-4" />
              </button>
              <button
                onClick={handleFullscreen}
                className="p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
                title="Fullscreen"
              >
                <Maximize2 className="h-4 w-4" />
              </button>
            </div>
          )}
        </div>

        {/* Controls */}
        <div className="flex items-center justify-between">
          <div className="flex items-center space-x-4">
            <div className="flex items-center space-x-2">
              <Calendar className="h-4 w-4 text-gray-400" />
              <select
                value={timeRange}
                onChange={(e) => setTimeRange(e.target.value)}
                className="text-sm border border-gray-300 dark:border-gray-600 rounded-lg px-3 py-1 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
              >
                <option value="7d">Last 7 days</option>
                <option value="30d">Last 30 days</option>
                <option value="90d">Last 90 days</option>
                <option value="1y">Last year</option>
                <option value="all">All time</option>
              </select>
            </div>
            
            <div className="flex items-center space-x-2">
              <button
                onClick={() => setChartType('line')}
                className={`p-2 rounded-lg transition-colors ${
                  chartType === 'line' 
                    ? 'bg-blue-100 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400' 
                    : 'text-gray-400 hover:text-gray-600 dark:hover:text-gray-300'
                }`}
                title="Line Chart"
              >
                <LineChart className="h-4 w-4" />
              </button>
              <button
                onClick={() => setChartType('bar')}
                className={`p-2 rounded-lg transition-colors ${
                  chartType === 'bar' 
                    ? 'bg-blue-100 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400' 
                    : 'text-gray-400 hover:text-gray-600 dark:hover:text-gray-300'
                }`}
                title="Bar Chart"
              >
                <BarChart3 className="h-4 w-4" />
              </button>
            </div>
          </div>

          {/* Trend Indicators */}
          {showTrends && processedData.datasets.length > 0 && (
            <div className="flex items-center space-x-4">
              {processedData.datasets.map((dataset, index) => (
                dataset.trend !== undefined && (
                  <div key={index} className="flex items-center space-x-1">
                    {dataset.trend >= 0 ? (
                      <TrendingUp className="h-4 w-4 text-green-500" />
                    ) : (
                      <TrendingDown className="h-4 w-4 text-red-500" />
                    )}
                    <span className={`text-sm font-medium ${
                      dataset.trend >= 0 ? 'text-green-600' : 'text-red-600'
                    }`}>
                      {Math.abs(dataset.trend).toFixed(1)}%
                    </span>
                    <span className="text-xs text-gray-500">{dataset.label}</span>
                  </div>
                )
              ))}
            </div>
          )}
        </div>

        {/* Settings Panel */}
        {showSettings && (
          <div className="mt-4 p-4 bg-gray-50 dark:bg-gray-700 rounded-lg">
            <h4 className="text-sm font-semibold text-gray-900 dark:text-white mb-3">Chart Settings</h4>
            <div className="grid grid-cols-2 gap-4">
              <label className="flex items-center space-x-2">
                <input
                  type="checkbox"
                  checked={chartSettings.showGrid}
                  onChange={(e) => setChartSettings(prev => ({ ...prev, showGrid: e.target.checked }))}
                  className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
                />
                <span className="text-sm text-gray-700 dark:text-gray-300">Show Grid</span>
              </label>
              <label className="flex items-center space-x-2">
                <input
                  type="checkbox"
                  checked={chartSettings.showLegend}
                  onChange={(e) => setChartSettings(prev => ({ ...prev, showLegend: e.target.checked }))}
                  className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
                />
                <span className="text-sm text-gray-700 dark:text-gray-300">Show Legend</span>
              </label>
              <label className="flex items-center space-x-2">
                <input
                  type="checkbox"
                  checked={chartSettings.showDataLabels}
                  onChange={(e) => setChartSettings(prev => ({ ...prev, showDataLabels: e.target.checked }))}
                  className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
                />
                <span className="text-sm text-gray-700 dark:text-gray-300">Show Data Points</span>
              </label>
              <label className="flex items-center space-x-2">
                <input
                  type="checkbox"
                  checked={chartSettings.smoothLines}
                  onChange={(e) => setChartSettings(prev => ({ ...prev, smoothLines: e.target.checked }))}
                  className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
                />
                <span className="text-sm text-gray-700 dark:text-gray-300">Smooth Lines</span>
              </label>
              <label className="flex items-center space-x-2">
                <input
                  type="checkbox"
                  checked={chartSettings.fillArea}
                  onChange={(e) => setChartSettings(prev => ({ ...prev, fillArea: e.target.checked }))}
                  className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
                />
                <span className="text-sm text-gray-700 dark:text-gray-300">Fill Area</span>
              </label>
            </div>
          </div>
        )}
      </div>

      {/* Chart */}
      <div className="p-6">
        <div style={{ height: `${height}px` }}>
          {processedData.labels.length > 0 ? (
            renderChart()
          ) : (
            <div className="flex items-center justify-center h-full">
              <div className="text-center">
                <TrendingUp className="h-16 w-16 text-gray-400 mx-auto mb-4" />
                <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
                  No Time Series Data
                </h3>
                <p className="text-gray-500 dark:text-gray-400">
                  No data available for the selected time period
                </p>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  )
}

export default TimeSeriesChart
