'use client'

import { useMemo } from 'react'
import {
  AreaChart,
  Area,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  ResponsiveContainer,
  RadialBarChart,
  RadialBar,
  Legend
} from 'recharts'
import type { StatsDataPoint, StatsRange } from '@/lib/services/stats-collection-service'

// ============================================================================
// Types
// ============================================================================

interface ChartProps {
  data: StatsDataPoint[]
  height?: number
}

interface GaugeProps {
  value: number | null
  max?: number
  label: string
  unit?: string
  color?: string
}

interface RangeSelectorProps {
  value: StatsRange
  onChange: (range: StatsRange) => void
}

// ============================================================================
// Helpers
// ============================================================================

function formatTime(timestamp: Date | string): string {
  const date = new Date(timestamp)
  return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
}

function formatDate(timestamp: Date | string): string {
  const date = new Date(timestamp)
  return date.toLocaleDateString([], { month: 'short', day: 'numeric' })
}

function formatDateTime(timestamp: Date | string, range: StatsRange): string {
  const date = new Date(timestamp)
  if (range === '24h') {
    return formatTime(date)
  }
  return `${formatDate(date)} ${formatTime(date)}`
}

// ============================================================================
// Range Selector
// ============================================================================

export function RangeSelector({ value, onChange }: RangeSelectorProps) {
  const ranges: { value: StatsRange; label: string }[] = [
    { value: '24h', label: '24h' },
    { value: '7d', label: '7d' },
    { value: '30d', label: '30d' },
    { value: '90d', label: '90d' }
  ]

  return (
    <div className="inline-flex rounded-md shadow-sm">
      {ranges.map(({ value: rangeValue, label }) => (
        <button
          key={rangeValue}
          onClick={() => onChange(rangeValue)}
          className={`
            px-3 py-1.5 text-sm font-medium
            first:rounded-l-md last:rounded-r-md
            border border-gray-300
            ${value === rangeValue
              ? 'bg-blue-600 text-white border-blue-600'
              : 'bg-white text-gray-700 hover:bg-gray-50'
            }
            focus:z-10 focus:outline-none focus:ring-1 focus:ring-blue-500
          `}
        >
          {label}
        </button>
      ))}
    </div>
  )
}

// ============================================================================
// Stats Gauge
// ============================================================================

export function StatsGauge({ value, max = 100, label, unit = '%', color = '#3b82f6' }: GaugeProps) {
  const displayValue = value ?? 0
  const percentage = Math.min((displayValue / max) * 100, 100)

  const data = [
    { name: label, value: percentage, fill: color }
  ]

  return (
    <div className="flex flex-col items-center">
      <div className="w-24 h-24">
        <ResponsiveContainer width="100%" height="100%">
          <RadialBarChart
            cx="50%"
            cy="50%"
            innerRadius="60%"
            outerRadius="100%"
            barSize={10}
            data={data}
            startAngle={180}
            endAngle={0}
          >
            <RadialBar
              background={{ fill: '#e5e7eb' }}
              dataKey="value"
              cornerRadius={5}
            />
          </RadialBarChart>
        </ResponsiveContainer>
      </div>
      <div className="text-center mt-1">
        <div className="text-lg font-semibold text-gray-900">
          {value !== null ? `${displayValue.toFixed(1)}${unit}` : 'N/A'}
        </div>
        <div className="text-xs text-gray-500">{label}</div>
      </div>
    </div>
  )
}

// ============================================================================
// CPU Usage Chart
// ============================================================================

export function CpuUsageChart({ data, height = 200 }: ChartProps) {
  const chartData = useMemo(() =>
    data.map(d => ({
      time: new Date(d.timestamp).getTime(),
      cpu: d.cpuPercent ?? 0
    })),
    [data]
  )

  if (chartData.length === 0) {
    return <EmptyChart height={height} message="No CPU data available" />
  }

  return (
    <div className="w-full" style={{ height }}>
      <ResponsiveContainer width="100%" height="100%">
        <AreaChart data={chartData} margin={{ top: 10, right: 10, left: 0, bottom: 0 }}>
          <defs>
            <linearGradient id="cpuGradient" x1="0" y1="0" x2="0" y2="1">
              <stop offset="5%" stopColor="#3b82f6" stopOpacity={0.8} />
              <stop offset="95%" stopColor="#3b82f6" stopOpacity={0.1} />
            </linearGradient>
          </defs>
          <CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
          <XAxis
            dataKey="time"
            type="number"
            domain={['dataMin', 'dataMax']}
            tickFormatter={(value) => formatTime(value)}
            tick={{ fontSize: 11 }}
            stroke="#9ca3af"
          />
          <YAxis
            domain={[0, 100]}
            tickFormatter={(value) => `${value}%`}
            tick={{ fontSize: 11 }}
            stroke="#9ca3af"
            width={45}
          />
          <Tooltip
            labelFormatter={(value) => new Date(value as number).toLocaleString()}
            formatter={(value) => [`${(value as number).toFixed(1)}%`, 'CPU']}
            contentStyle={{ fontSize: 12 }}
          />
          <Area
            type="monotone"
            dataKey="cpu"
            stroke="#3b82f6"
            fillOpacity={1}
            fill="url(#cpuGradient)"
            strokeWidth={2}
          />
        </AreaChart>
      </ResponsiveContainer>
    </div>
  )
}

// ============================================================================
// Memory Usage Chart
// ============================================================================

export function MemoryUsageChart({ data, height = 200 }: ChartProps) {
  const chartData = useMemo(() =>
    data.map(d => ({
      time: new Date(d.timestamp).getTime(),
      used: d.memoryUsedMb ?? 0,
      total: d.memoryTotalMb ?? 0,
      percent: d.memoryPercent ?? 0
    })),
    [data]
  )

  if (chartData.length === 0) {
    return <EmptyChart height={height} message="No memory data available" />
  }

  return (
    <div className="w-full" style={{ height }}>
      <ResponsiveContainer width="100%" height="100%">
        <AreaChart data={chartData} margin={{ top: 10, right: 10, left: 0, bottom: 0 }}>
          <defs>
            <linearGradient id="memoryGradient" x1="0" y1="0" x2="0" y2="1">
              <stop offset="5%" stopColor="#10b981" stopOpacity={0.8} />
              <stop offset="95%" stopColor="#10b981" stopOpacity={0.1} />
            </linearGradient>
          </defs>
          <CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
          <XAxis
            dataKey="time"
            type="number"
            domain={['dataMin', 'dataMax']}
            tickFormatter={(value) => formatTime(value)}
            tick={{ fontSize: 11 }}
            stroke="#9ca3af"
          />
          <YAxis
            domain={[0, 100]}
            tickFormatter={(value) => `${value}%`}
            tick={{ fontSize: 11 }}
            stroke="#9ca3af"
            width={45}
          />
          <Tooltip
            labelFormatter={(value) => new Date(value as number).toLocaleString()}
            formatter={(value, name) => {
              const v = value as number
              if (name === 'percent') return [`${v.toFixed(1)}%`, 'Memory']
              return [`${v.toFixed(0)} MB`, name === 'used' ? 'Used' : 'Total']
            }}
            contentStyle={{ fontSize: 12 }}
          />
          <Area
            type="monotone"
            dataKey="percent"
            stroke="#10b981"
            fillOpacity={1}
            fill="url(#memoryGradient)"
            strokeWidth={2}
          />
        </AreaChart>
      </ResponsiveContainer>
    </div>
  )
}

// ============================================================================
// Disk I/O Chart
// ============================================================================

export function DiskIOChart({ data, height = 200 }: ChartProps) {
  const chartData = useMemo(() =>
    data.map(d => ({
      time: new Date(d.timestamp).getTime(),
      read: d.diskReadMbps ?? 0,
      write: d.diskWriteMbps ?? 0
    })),
    [data]
  )

  if (chartData.length === 0) {
    return <EmptyChart height={height} message="No disk I/O data available" />
  }

  return (
    <div className="w-full" style={{ height }}>
      <ResponsiveContainer width="100%" height="100%">
        <AreaChart data={chartData} margin={{ top: 10, right: 10, left: 0, bottom: 0 }}>
          <defs>
            <linearGradient id="readGradient" x1="0" y1="0" x2="0" y2="1">
              <stop offset="5%" stopColor="#8b5cf6" stopOpacity={0.8} />
              <stop offset="95%" stopColor="#8b5cf6" stopOpacity={0.1} />
            </linearGradient>
            <linearGradient id="writeGradient" x1="0" y1="0" x2="0" y2="1">
              <stop offset="5%" stopColor="#f59e0b" stopOpacity={0.8} />
              <stop offset="95%" stopColor="#f59e0b" stopOpacity={0.1} />
            </linearGradient>
          </defs>
          <CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
          <XAxis
            dataKey="time"
            type="number"
            domain={['dataMin', 'dataMax']}
            tickFormatter={(value) => formatTime(value)}
            tick={{ fontSize: 11 }}
            stroke="#9ca3af"
          />
          <YAxis
            tickFormatter={(value) => `${value.toFixed(1)}`}
            tick={{ fontSize: 11 }}
            stroke="#9ca3af"
            width={45}
          />
          <Tooltip
            labelFormatter={(value) => new Date(value as number).toLocaleString()}
            formatter={(value, name) => [
              `${(value as number).toFixed(2)} MB/s`,
              name === 'read' ? 'Read' : 'Write'
            ]}
            contentStyle={{ fontSize: 12 }}
          />
          <Legend
            formatter={(value) => value === 'read' ? 'Read' : 'Write'}
            wrapperStyle={{ fontSize: 12 }}
          />
          <Area
            type="monotone"
            dataKey="read"
            stroke="#8b5cf6"
            fillOpacity={1}
            fill="url(#readGradient)"
            strokeWidth={2}
          />
          <Area
            type="monotone"
            dataKey="write"
            stroke="#f59e0b"
            fillOpacity={1}
            fill="url(#writeGradient)"
            strokeWidth={2}
          />
        </AreaChart>
      </ResponsiveContainer>
    </div>
  )
}

// ============================================================================
// Network Chart
// ============================================================================

export function NetworkChart({ data, height = 200 }: ChartProps) {
  const chartData = useMemo(() =>
    data.map(d => ({
      time: new Date(d.timestamp).getTime(),
      inbound: d.networkInMbps ?? 0,
      outbound: d.networkOutMbps ?? 0
    })),
    [data]
  )

  if (chartData.length === 0) {
    return <EmptyChart height={height} message="No network data available" />
  }

  return (
    <div className="w-full" style={{ height }}>
      <ResponsiveContainer width="100%" height="100%">
        <AreaChart data={chartData} margin={{ top: 10, right: 10, left: 0, bottom: 0 }}>
          <defs>
            <linearGradient id="inboundGradient" x1="0" y1="0" x2="0" y2="1">
              <stop offset="5%" stopColor="#06b6d4" stopOpacity={0.8} />
              <stop offset="95%" stopColor="#06b6d4" stopOpacity={0.1} />
            </linearGradient>
            <linearGradient id="outboundGradient" x1="0" y1="0" x2="0" y2="1">
              <stop offset="5%" stopColor="#ec4899" stopOpacity={0.8} />
              <stop offset="95%" stopColor="#ec4899" stopOpacity={0.1} />
            </linearGradient>
          </defs>
          <CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
          <XAxis
            dataKey="time"
            type="number"
            domain={['dataMin', 'dataMax']}
            tickFormatter={(value) => formatTime(value)}
            tick={{ fontSize: 11 }}
            stroke="#9ca3af"
          />
          <YAxis
            tickFormatter={(value) => `${value.toFixed(1)}`}
            tick={{ fontSize: 11 }}
            stroke="#9ca3af"
            width={45}
          />
          <Tooltip
            labelFormatter={(value) => new Date(value as number).toLocaleString()}
            formatter={(value, name) => [
              `${(value as number).toFixed(2)} Mbps`,
              name === 'inbound' ? 'Inbound' : 'Outbound'
            ]}
            contentStyle={{ fontSize: 12 }}
          />
          <Legend
            formatter={(value) => value === 'inbound' ? 'Inbound' : 'Outbound'}
            wrapperStyle={{ fontSize: 12 }}
          />
          <Area
            type="monotone"
            dataKey="inbound"
            stroke="#06b6d4"
            fillOpacity={1}
            fill="url(#inboundGradient)"
            strokeWidth={2}
          />
          <Area
            type="monotone"
            dataKey="outbound"
            stroke="#ec4899"
            fillOpacity={1}
            fill="url(#outboundGradient)"
            strokeWidth={2}
          />
        </AreaChart>
      </ResponsiveContainer>
    </div>
  )
}

// ============================================================================
// Container Stats Chart
// ============================================================================

export function ContainerStatsChart({ data, height = 200 }: ChartProps) {
  const chartData = useMemo(() =>
    data.map(d => ({
      time: new Date(d.timestamp).getTime(),
      running: d.containersRunning ?? 0,
      stopped: d.containersStopped ?? 0
    })),
    [data]
  )

  if (chartData.length === 0 || chartData.every(d => d.running === 0 && d.stopped === 0)) {
    return <EmptyChart height={height} message="No container data available" />
  }

  return (
    <div className="w-full" style={{ height }}>
      <ResponsiveContainer width="100%" height="100%">
        <AreaChart data={chartData} margin={{ top: 10, right: 10, left: 0, bottom: 0 }}>
          <CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
          <XAxis
            dataKey="time"
            type="number"
            domain={['dataMin', 'dataMax']}
            tickFormatter={(value) => formatTime(value)}
            tick={{ fontSize: 11 }}
            stroke="#9ca3af"
          />
          <YAxis
            allowDecimals={false}
            tick={{ fontSize: 11 }}
            stroke="#9ca3af"
            width={30}
          />
          <Tooltip
            labelFormatter={(value) => new Date(value as number).toLocaleString()}
            formatter={(value, name) => [
              value as number,
              name === 'running' ? 'Running' : 'Stopped'
            ]}
            contentStyle={{ fontSize: 12 }}
          />
          <Legend
            formatter={(value) => value === 'running' ? 'Running' : 'Stopped'}
            wrapperStyle={{ fontSize: 12 }}
          />
          <Area
            type="stepAfter"
            dataKey="running"
            stackId="1"
            stroke="#22c55e"
            fill="#22c55e"
            fillOpacity={0.6}
          />
          <Area
            type="stepAfter"
            dataKey="stopped"
            stackId="1"
            stroke="#ef4444"
            fill="#ef4444"
            fillOpacity={0.6}
          />
        </AreaChart>
      </ResponsiveContainer>
    </div>
  )
}

// ============================================================================
// Empty Chart Placeholder
// ============================================================================

function EmptyChart({ height, message }: { height: number; message: string }) {
  return (
    <div
      className="flex items-center justify-center bg-gray-50 rounded-lg border border-dashed border-gray-300"
      style={{ height }}
    >
      <p className="text-sm text-gray-500">{message}</p>
    </div>
  )
}

// ============================================================================
// Stats Card
// ============================================================================

interface StatsCardProps {
  title: string
  value: string | number | null
  unit?: string
  icon?: React.ReactNode
  trend?: 'up' | 'down' | 'neutral'
  trendValue?: string
}

export function StatsCard({ title, value, unit, icon, trend, trendValue }: StatsCardProps) {
  const trendColors = {
    up: 'text-green-600',
    down: 'text-red-600',
    neutral: 'text-gray-500'
  }

  const trendIcons = {
    up: '↑',
    down: '↓',
    neutral: '→'
  }

  return (
    <div className="bg-white rounded-lg border border-gray-200 p-4">
      <div className="flex items-center justify-between">
        <span className="text-sm font-medium text-gray-500">{title}</span>
        {icon && <span className="text-gray-400">{icon}</span>}
      </div>
      <div className="mt-2 flex items-baseline">
        <span className="text-2xl font-semibold text-gray-900">
          {value !== null ? value : 'N/A'}
        </span>
        {unit && value !== null && (
          <span className="ml-1 text-sm text-gray-500">{unit}</span>
        )}
      </div>
      {trend && trendValue && (
        <div className={`mt-1 flex items-center text-sm ${trendColors[trend]}`}>
          <span>{trendIcons[trend]}</span>
          <span className="ml-1">{trendValue}</span>
        </div>
      )}
    </div>
  )
}
