'use client';

/**
 * Operational — Berth utilisation heatmap (Report 04 Chart 1).
 *
 * Pure CSS grid (no chart library) — each cell coloured by occupancy %.
 * Months across the X-axis (most recent on the right), areas down the
 * Y-axis. Hover shows the occupancy % and underlying count.
 */

import { cn } from '@/lib/utils';

interface UtilisationCell {
  area: string;
  month: string;
  occupancyPct: number;
}

interface Props {
  cells: UtilisationCell[];
}

export function OperationalHeatmap({ cells }: Props) {
  if (cells.length === 0) {
    return (
      <div className="py-10 text-center text-sm text-muted-foreground">
        No berth history captured yet. The heatmap fills in as status changes accumulate.
      </div>
    );
  }

  // Build the unique area + month axes
  const areas = Array.from(new Set(cells.map((c) => c.area))).sort();
  const months = Array.from(new Set(cells.map((c) => c.month))).sort();

  // Build a lookup so we can render in O(1) per cell
  const byKey = new Map<string, UtilisationCell>();
  for (const c of cells) byKey.set(`${c.area}|${c.month}`, c);

  return (
    <div className="overflow-x-auto">
      <div className="inline-block min-w-full">
        <div
          className="grid gap-0.5"
          style={{ gridTemplateColumns: `120px repeat(${months.length}, 1fr)` }}
        >
          {/* Header row: month labels */}
          <div />
          {months.map((m) => (
            <div
              key={m}
              className="text-[10px] text-muted-foreground text-center font-mono"
              style={{ writingMode: months.length > 18 ? 'vertical-rl' : undefined }}
            >
              {formatMonth(m)}
            </div>
          ))}

          {/* Body */}
          {areas.map((area) => (
            <FragmentRow key={area} area={area} months={months} byKey={byKey} />
          ))}
        </div>

        {/* Legend */}
        <div className="mt-4 flex items-center gap-3 text-[11px] text-muted-foreground">
          <span>Occupancy:</span>
          <div className="flex items-center gap-0.5">
            {[0, 20, 40, 60, 80, 100].map((pct) => (
              <div key={pct} className={cn('h-3 w-6', colorForPct(pct))} title={`${pct}%`} />
            ))}
          </div>
          <span>0% → 100%</span>
        </div>
      </div>
    </div>
  );
}

function FragmentRow({
  area,
  months,
  byKey,
}: {
  area: string;
  months: string[];
  byKey: Map<string, UtilisationCell>;
}) {
  return (
    <>
      <div className="text-xs font-medium text-foreground truncate pr-2 self-center">{area}</div>
      {months.map((month) => {
        const cell = byKey.get(`${area}|${month}`);
        const pct = cell?.occupancyPct ?? 0;
        return (
          <div
            key={`${area}|${month}`}
            className={cn('h-7 rounded-sm transition-colors', colorForPct(pct))}
            title={`${area} · ${formatMonthLong(month)}: ${pct.toFixed(0)}%`}
          />
        );
      })}
    </>
  );
}

function colorForPct(pct: number): string {
  // 6-step ramp using the existing brand palette
  if (pct >= 90) return 'bg-brand-700';
  if (pct >= 70) return 'bg-brand-500';
  if (pct >= 50) return 'bg-brand-300';
  if (pct >= 30) return 'bg-brand-100';
  if (pct > 0) return 'bg-brand-50';
  return 'bg-muted/30';
}

function formatMonth(month: string): string {
  const [year, m] = month.split('-');
  if (!year || !m) return month;
  const d = new Date(parseInt(year), parseInt(m) - 1, 1);
  return d.toLocaleDateString(undefined, { month: 'short' });
}

function formatMonthLong(month: string): string {
  const [year, m] = month.split('-');
  if (!year || !m) return month;
  const d = new Date(parseInt(year), parseInt(m) - 1, 1);
  return d.toLocaleDateString(undefined, { month: 'long', year: 'numeric' });
}
