import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import {
  LineChart,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  ResponsiveContainer,
} from 'recharts';
import type { SeismicDto, PressureDto } from '../../services/sensorApi';

interface Props {
  seismicData: SeismicDto[];
  pressureData: PressureDto[];
  currentTime: number;
  historyMinutes: number;
}

const MINUTE = 60_000;
const BUCKET_COUNT = 48;

function formatTickTime(epoch: number): string {
  const d = new Date(epoch);
  const pad = (n: number) => String(n).padStart(2, '0');
  return `${pad(d.getMonth() + 1)}/${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
}

function buildTicks(currentTime: number, historyMinutes: number): number[] {
  const interval = historyMinutes * MINUTE;
  const ticks: number[] = [];
  for (let i = 8; i >= 0; i--) {
    ticks.push(currentTime - i * interval);
  }
  return ticks;
}

function aggregateSeismic(
  data: SeismicDto[],
  rangeStart: number,
  rangeEnd: number,
): { time: number; value: number }[] {
  const bucketSize = (rangeEnd - rangeStart) / BUCKET_COUNT;
  const buckets = Array.from({ length: BUCKET_COUNT }, (_, i) => ({
    time: rangeStart + (i + 0.5) * bucketSize,
    value: 0,
  }));
  for (const ev of data) {
    if (ev.timestamp < rangeStart || ev.timestamp > rangeEnd) continue;
    const idx = Math.min(Math.floor((ev.timestamp - rangeStart) / bucketSize), BUCKET_COUNT - 1);
    buckets[idx].value = Math.max(buckets[idx].value, ev.magnitude * 10);
  }
  return buckets;
}

function aggregatePressure(
  data: PressureDto[],
  rangeStart: number,
  rangeEnd: number,
): { time: number; value: number }[] {
  const bucketSize = (rangeEnd - rangeStart) / BUCKET_COUNT;
  const buckets = Array.from({ length: BUCKET_COUNT }, (_, i) => ({
    time: rangeStart + (i + 0.5) * bucketSize,
    values: [] as number[],
  }));
  for (const r of data) {
    if (r.timestamp < rangeStart || r.timestamp > rangeEnd) continue;
    const idx = Math.min(Math.floor((r.timestamp - rangeStart) / bucketSize), BUCKET_COUNT - 1);
    buckets[idx].values.push(r.pressureHpa);
  }
  return buckets.map(b => ({
    time: b.time,
    value: b.values.length > 0 ? b.values.reduce((a, c) => a + c, 0) / b.values.length : 0,
  }));
}

function generateDemoData(
  rangeStart: number,
  rangeEnd: number,
  baseValue: number,
  variance: number,
): { time: number; value: number }[] {
  const bucketSize = (rangeEnd - rangeStart) / BUCKET_COUNT;
  return Array.from({ length: BUCKET_COUNT }, (_, i) => {
    const t = rangeStart + (i + 0.5) * bucketSize;
    const seed = Math.sin(t / 100_000) * 10000;
    const noise = (seed - Math.floor(seed)) * 2 - 1;
    return { time: t, value: Math.max(0, baseValue + noise * variance) };
  });
}

export function SensorChart({ seismicData, pressureData, currentTime, historyMinutes }: Props) {
  const { t } = useTranslation();

  const totalMinutes = historyMinutes * 8;
  const rangeStart = currentTime - totalMinutes * MINUTE;
  const rangeEnd = currentTime;

  const ticks = useMemo(() => buildTicks(currentTime, historyMinutes), [currentTime, historyMinutes]);

  const seismicChart = useMemo(
    () => aggregateSeismic(seismicData, rangeStart, rangeEnd),
    [seismicData, rangeStart, rangeEnd],
  );
  const pressureChart = useMemo(
    () => aggregatePressure(pressureData, rangeStart, rangeEnd),
    [pressureData, rangeStart, rangeEnd],
  );
  const noiseChart = useMemo(
    () => generateDemoData(rangeStart, rangeEnd, 45, 30),
    [rangeStart, rangeEnd],
  );
  const radiationChart = useMemo(
    () => generateDemoData(rangeStart, rangeEnd, 0.08, 0.06),
    [rangeStart, rangeEnd],
  );

  const commonXAxis = {
    dataKey: 'time' as const,
    type: 'number' as const,
    domain: [rangeStart, rangeEnd] as [number, number],
    ticks,
    tickFormatter: formatTickTime,
    tick: { fontSize: 9, fill: '#888' },
  };

  return (
    <div className="sensor-chart">
      <h3>{t('sensor.title')}</h3>
      <div className="chart-grid">
        <div className="chart-item">
          <h4>{t('sensor.seismicActivity')}</h4>
          <ResponsiveContainer width="100%" height={80}>
            <LineChart data={seismicChart}>
              <CartesianGrid strokeDasharray="3 3" stroke="#333" />
              <XAxis {...commonXAxis} />
              <YAxis domain={[0, 100]} tick={{ fontSize: 10, fill: '#888' }} />
              <Tooltip
                contentStyle={{ background: '#1a1a2e', border: '1px solid #333' }}
                labelFormatter={formatTickTime}
                formatter={(v: number) => [v.toFixed(1), 'Magnitude×10']}
              />
              <Line type="monotone" dataKey="value" stroke="#ef4444" dot={false} strokeWidth={1.5} />
            </LineChart>
          </ResponsiveContainer>
        </div>

        <div className="chart-item">
          <h4>{t('sensor.airPressureHpa')}</h4>
          <ResponsiveContainer width="100%" height={80}>
            <LineChart data={pressureChart}>
              <CartesianGrid strokeDasharray="3 3" stroke="#333" />
              <XAxis {...commonXAxis} />
              <YAxis domain={[990, 1030]} tick={{ fontSize: 10, fill: '#888' }} />
              <Tooltip
                contentStyle={{ background: '#1a1a2e', border: '1px solid #333' }}
                labelFormatter={formatTickTime}
                formatter={(v: number) => [v.toFixed(1), 'hPa']}
              />
              <Line type="monotone" dataKey="value" stroke="#3b82f6" dot={false} strokeWidth={1.5} />
            </LineChart>
          </ResponsiveContainer>
        </div>

        <div className="chart-item">
          <h4>
            {t('sensor.noiseLevelDb')}{' '}
            <span className="chart-demo-label">(DEMO)</span>
          </h4>
          <ResponsiveContainer width="100%" height={80}>
            <LineChart data={noiseChart}>
              <CartesianGrid strokeDasharray="3 3" stroke="#333" />
              <XAxis {...commonXAxis} />
              <YAxis domain={[0, 140]} tick={{ fontSize: 10, fill: '#888' }} />
              <Tooltip
                contentStyle={{ background: '#1a1a2e', border: '1px solid #333' }}
                labelFormatter={formatTickTime}
                formatter={(v: number) => [v.toFixed(1), 'dB']}
              />
              <Line type="monotone" dataKey="value" stroke="#f97316" dot={false} strokeWidth={1.5} />
            </LineChart>
          </ResponsiveContainer>
        </div>

        <div className="chart-item">
          <h4>
            {t('sensor.radiationUsv')}{' '}
            <span className="chart-demo-label">(DEMO)</span>
          </h4>
          <ResponsiveContainer width="100%" height={80}>
            <LineChart data={radiationChart}>
              <CartesianGrid strokeDasharray="3 3" stroke="#333" />
              <XAxis {...commonXAxis} />
              <YAxis domain={[0, 0.3]} tick={{ fontSize: 10, fill: '#888' }} />
              <Tooltip
                contentStyle={{ background: '#1a1a2e', border: '1px solid #333' }}
                labelFormatter={formatTickTime}
                formatter={(v: number) => [v.toFixed(3), 'μSv/h']}
              />
              <Line type="monotone" dataKey="value" stroke="#22c55e" dot={false} strokeWidth={1.5} />
            </LineChart>
          </ResponsiveContainer>
        </div>
      </div>
    </div>
  );
}
