import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { BarChart3 } from 'lucide-react';
import {
  AreaChart,
  Area,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  ResponsiveContainer,
  Legend,
} from 'recharts';
import { MonitoringMessage, LLMCall } from '../../types/monitoring';

interface TrafficChartProps {
  messages: MonitoringMessage[];
  llmCalls: LLMCall[];
  loading?: boolean;
}

interface ChartDataPoint {
  time: string;
  timestamp: number;
  messages: number;
  llmCalls: number;
}

export default function TrafficChart({
  messages,
  llmCalls,
  loading,
}: TrafficChartProps) {
  const { t } = useTranslation();

  const chartData = useMemo(() => {
    const safeMessages = Array.isArray(messages) ? messages : [];
    const safeLlmCalls = Array.isArray(llmCalls) ? llmCalls : [];
    if (!safeMessages.length && !safeLlmCalls.length) {
      return [];
    }

    // Combine all timestamps and find the range
    const allTimestamps = [
      ...safeMessages.map((m) => m.timestamp.getTime()),
      ...safeLlmCalls.map((c) => c.timestamp.getTime()),
    ];

    if (allTimestamps.length === 0) return [];

    const minTime = Math.min(...allTimestamps);
    const maxTime = Math.max(...allTimestamps);
    const timeRange = maxTime - minTime;

    // Determine bucket size based on time range
    let bucketSize: number;
    let formatTime: (date: Date) => string;

    if (timeRange <= 60 * 60 * 1000) {
      // <= 1 hour: 5-minute buckets
      bucketSize = 5 * 60 * 1000;
      formatTime = (date) =>
        date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
    } else if (timeRange <= 6 * 60 * 60 * 1000) {
      // <= 6 hours: 15-minute buckets
      bucketSize = 15 * 60 * 1000;
      formatTime = (date) =>
        date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
    } else if (timeRange <= 24 * 60 * 60 * 1000) {
      // <= 24 hours: 1-hour buckets
      bucketSize = 60 * 60 * 1000;
      formatTime = (date) =>
        date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
    } else if (timeRange <= 7 * 24 * 60 * 60 * 1000) {
      // <= 7 days: 4-hour buckets
      bucketSize = 4 * 60 * 60 * 1000;
      formatTime = (date) =>
        `${date.toLocaleDateString([], {
          month: 'short',
          day: 'numeric',
        })} ${date.toLocaleTimeString([], { hour: '2-digit' })}`;
    } else {
      // > 7 days: 1-day buckets
      bucketSize = 24 * 60 * 60 * 1000;
      formatTime = (date) =>
        date.toLocaleDateString([], { month: 'short', day: 'numeric' });
    }

    // Create buckets
    const buckets: Map<number, ChartDataPoint> = new Map();
    const startBucket = Math.floor(minTime / bucketSize) * bucketSize;
    const endBucket = Math.ceil(maxTime / bucketSize) * bucketSize;

    for (let bucket = startBucket; bucket <= endBucket; bucket += bucketSize) {
      buckets.set(bucket, {
        time: formatTime(new Date(bucket)),
        timestamp: bucket,
        messages: 0,
        llmCalls: 0,
      });
    }

    // Count messages per bucket
    safeMessages.forEach((msg) => {
      const bucket =
        Math.floor(msg.timestamp.getTime() / bucketSize) * bucketSize;
      const point = buckets.get(bucket);
      if (point) {
        point.messages++;
      }
    });

    // Count LLM calls per bucket
    safeLlmCalls.forEach((call) => {
      const bucket =
        Math.floor(call.timestamp.getTime() / bucketSize) * bucketSize;
      const point = buckets.get(bucket);
      if (point) {
        point.llmCalls++;
      }
    });

    return Array.from(buckets.values()).sort(
      (a, b) => a.timestamp - b.timestamp,
    );
  }, [messages, llmCalls]);

  if (loading) {
    return (
      <div className="bg-card rounded-xl border p-6">
        <div className="flex items-center justify-between mb-4">
          <div className="h-5 w-32 bg-muted animate-pulse rounded"></div>
          <div className="flex gap-4">
            <div className="h-4 w-24 bg-muted animate-pulse rounded"></div>
            <div className="h-4 w-24 bg-muted animate-pulse rounded"></div>
          </div>
        </div>
        <div className="h-[300px] flex items-center justify-center">
          <div className="animate-pulse w-full h-full bg-muted rounded"></div>
        </div>
      </div>
    );
  }

  if (chartData.length === 0) {
    return (
      <div className="bg-card rounded-xl border p-6">
        <h3 className="text-base font-semibold text-foreground mb-4">
          {t('monitoring.trafficChart.title')}
        </h3>
        <div className="h-[300px] flex flex-col items-center justify-center text-muted-foreground gap-2">
          <BarChart3 className="h-[3rem] w-[3rem]" />
          <div className="text-sm">{t('monitoring.trafficChart.noData')}</div>
        </div>
      </div>
    );
  }

  return (
    <div className="bg-card rounded-xl border p-6 transition-shadow duration-300">
      <h3 className="text-base font-semibold text-foreground mb-6">
        {t('monitoring.trafficChart.title')}
      </h3>
      <div className="h-[300px]">
        <ResponsiveContainer width="100%" height="100%">
          <AreaChart
            data={chartData}
            margin={{ top: 10, right: 20, left: 0, bottom: 0 }}
          >
            <defs>
              <linearGradient id="colorMessages" x1="0" y1="0" x2="0" y2="1">
                <stop offset="5%" stopColor="#3b82f6" stopOpacity={0.4} />
                <stop offset="95%" stopColor="#3b82f6" stopOpacity={0.05} />
              </linearGradient>
              <linearGradient id="colorLLMCalls" x1="0" y1="0" x2="0" y2="1">
                <stop offset="5%" stopColor="#8b5cf6" stopOpacity={0.4} />
                <stop offset="95%" stopColor="#8b5cf6" stopOpacity={0.05} />
              </linearGradient>
            </defs>
            <CartesianGrid
              strokeDasharray="3 3"
              stroke="var(--border)"
              vertical={false}
            />
            <XAxis
              dataKey="time"
              tick={{ fontSize: 12, fill: 'var(--muted-foreground)' }}
              tickLine={false}
              axisLine={{ stroke: 'var(--border)' }}
              dy={10}
            />
            <YAxis
              tick={{ fontSize: 12, fill: 'var(--muted-foreground)' }}
              tickLine={false}
              axisLine={{ stroke: 'var(--border)' }}
              width={40}
              allowDecimals={false}
            />
            <Tooltip
              contentStyle={{
                backgroundColor: 'var(--card)',
                border: '1px solid var(--border)',
                borderRadius: '12px',
                boxShadow:
                  '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
                fontSize: '13px',
                padding: '12px',
                color: 'var(--foreground)',
              }}
              labelStyle={{
                fontWeight: 600,
                marginBottom: '8px',
                color: 'var(--foreground)',
              }}
              itemStyle={{ padding: '4px 0' }}
            />
            <Legend
              wrapperStyle={{
                fontSize: '13px',
                paddingTop: '16px',
                fontWeight: 500,
              }}
              iconType="circle"
              iconSize={10}
            />
            <Area
              type="monotone"
              dataKey="messages"
              name={t('monitoring.trafficChart.messages')}
              stroke="#3b82f6"
              strokeWidth={2.5}
              fillOpacity={1}
              fill="url(#colorMessages)"
              dot={false}
              activeDot={{ r: 6, strokeWidth: 2 }}
            />
            <Area
              type="monotone"
              dataKey="llmCalls"
              name={t('monitoring.trafficChart.llmCalls')}
              stroke="#8b5cf6"
              strokeWidth={2.5}
              fillOpacity={1}
              fill="url(#colorLLMCalls)"
              dot={false}
              activeDot={{ r: 6, strokeWidth: 2 }}
            />
          </AreaChart>
        </ResponsiveContainer>
      </div>
    </div>
  );
}
