import { useMemo, useState } from 'react';
import styles from './DashboardTab.module.css';

export interface PunchcardCell {
  weekday: number;
  hour: number;
  totalCount: number;
  failedCount: number;
}

interface PunchcardHeatmapProps {
  cells: PunchcardCell[];
  timeRangeMs?: number;
}

type Mode = 'transactions' | 'errors';

const DAYS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
// Remap: backend DOW 0=Sun..6=Sat → display 0=Mon..6=Sun
function toDisplayDay(dow: number): number {
  return dow === 0 ? 6 : dow - 1;
}

function transactionColor(ratio: number): string {
  if (ratio === 0) return 'var(--bg-inset)';
  // Blue scale matching --running hue
  const alpha = 0.15 + ratio * 0.75;
  return `hsla(220, 65%, 50%, ${alpha.toFixed(2)})`;
}

function errorColor(ratio: number): string {
  if (ratio === 0) return 'var(--bg-inset)';
  const alpha = 0.15 + ratio * 0.75;
  return `hsla(0, 65%, 50%, ${alpha.toFixed(2)})`;
}

const CELL = 11;
const GAP = 2;
const LABEL_W = 28;
const LABEL_H = 14;

const TWO_DAYS_MS = 2 * 24 * 60 * 60 * 1000;

export function PunchcardHeatmap({ cells, timeRangeMs }: PunchcardHeatmapProps) {
  const [mode, setMode] = useState<Mode>('transactions');
  const insufficientData = timeRangeMs !== undefined && timeRangeMs < TWO_DAYS_MS;

  const { grid, maxVal } = useMemo(() => {
    const cellMap = new Map<string, PunchcardCell>();
    for (const c of cells) cellMap.set(`${toDisplayDay(c.weekday)}-${c.hour}`, c);

    let max = 0;
    const g: { day: number; hour: number; value: number }[] = [];
    for (let d = 0; d < 7; d++) {
      for (let h = 0; h < 24; h++) {
        const cell = cellMap.get(`${d}-${h}`);
        const val = cell ? (mode === 'errors' ? cell.failedCount : cell.totalCount) : 0;
        if (val > max) max = val;
        g.push({ day: d, hour: h, value: val });
      }
    }
    return { grid: g, maxVal: Math.max(max, 1) };
  }, [cells, mode]);

  const cols = 24;
  const rows = 7;
  const svgW = LABEL_W + cols * (CELL + GAP);
  const svgH = LABEL_H + rows * (CELL + GAP);

  if (insufficientData) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '2rem 1rem', color: 'var(--text-muted)', fontSize: '0.8125rem', fontStyle: 'italic' }}>
        Requires at least 2 days of data
      </div>
    );
  }

  return (
    <div>
      <div className={styles.toggleRow}>
        <button
          className={`${styles.toggleBtn} ${mode === 'transactions' ? styles.toggleActive : ''}`}
          onClick={() => setMode('transactions')}
        >
          Transactions
        </button>
        <button
          className={`${styles.toggleBtn} ${mode === 'errors' ? styles.toggleActive : ''}`}
          onClick={() => setMode('errors')}
        >
          Errors
        </button>
      </div>
      <svg viewBox={`0 0 ${svgW} ${svgH}`} style={{ width: '100%', height: 'auto', display: 'block' }}>
        {/* Hour labels (top, every 4 hours) */}
        {[0, 4, 8, 12, 16, 20].map(h => (
          <text
            key={h}
            x={LABEL_W + h * (CELL + GAP) + CELL / 2}
            y={10}
            textAnchor="middle"
            fill="var(--text-faint)"
            fontSize={7}
            fontFamily="var(--font-mono)"
          >
            {String(h).padStart(2, '0')}
          </text>
        ))}

        {/* Day labels (left) */}
        {DAYS.map((day, i) => (
          <text
            key={day}
            x={LABEL_W - 4}
            y={LABEL_H + i * (CELL + GAP) + CELL / 2 + 3}
            textAnchor="end"
            fill="var(--text-faint)"
            fontSize={7}
            fontFamily="var(--font-mono)"
          >
            {day}
          </text>
        ))}

        {/* Cells */}
        {grid.map(({ day, hour, value }) => {
          const ratio = value / maxVal;
          const fill = mode === 'errors' ? errorColor(ratio) : transactionColor(ratio);
          return (
            <rect
              key={`${day}-${hour}`}
              x={LABEL_W + hour * (CELL + GAP)}
              y={LABEL_H + day * (CELL + GAP)}
              width={CELL}
              height={CELL}
              rx={2}
              fill={fill}
            >
              <title>{`${DAYS[day]} ${String(hour).padStart(2, '0')}:00 — ${value.toLocaleString()} ${mode}`}</title>
            </rect>
          );
        })}
      </svg>
    </div>
  );
}
