import { Section } from "../../components/Section";
import { useViewMode } from "../../context/ViewModeContext";
import type { AllData } from "../../types/data";
import { useMemo } from "react";

const COLORS = ["#f1f5f9", "#c7d2fe", "#818cf8", "#4f46e5", "#312e81"];
const DEV_COLOR_MAP: Record<string, string[]> = {
  zzjjaayy: ["#f1f5f9", "#c7d2fe", "#818cf8", "#4f46e5", "#312e81"],
  ajay: ["#f1f5f9", "#bbf7d0", "#4ade80", "#16a34a", "#14532d"],
  vaibhav: ["#f1f5f9", "#fde68a", "#fbbf24", "#d97706", "#78350f"],
};

function getColor(count: number, max: number, palette: string[]) {
  if (count === 0) return palette[0];
  const q = count / max;
  if (q <= 0.25) return palette[1];
  if (q <= 0.5) return palette[2];
  if (q <= 0.75) return palette[3];
  return palette[4];
}

function Heatmap({ dayCounts, palette, label }: { dayCounts: Record<string, number>; palette: string[]; label: string }) {
  const allDates = Object.keys(dayCounts).sort();
  if (allDates.length === 0) return null;

  const maxCount = Math.max(...Object.values(dayCounts), 1);
  const totalSessions = Object.values(dayCounts).reduce((a, b) => a + b, 0);
  const activeDays = allDates.length;

  const earliest = new Date(allDates[0] + "T00:00:00");
  const latest = new Date(allDates[allDates.length - 1] + "T00:00:00");

  const startDate = new Date(earliest);
  startDate.setDate(startDate.getDate() - startDate.getDay());

  const totalWeeks = Math.ceil((latest.getTime() - startDate.getTime()) / (7 * 86400000)) + 2;
  const cellSize = 11;
  const cellGap = 2;
  const step = cellSize + cellGap;
  const dayLabelWidth = 20;
  const headerHeight = 16;

  const DAY_LABELS = ["", "M", "", "W", "", "F", ""];
  const cells: { x: number; y: number; date: string; count: number; color: string; label: string }[] = [];
  const monthLabels: { x: number; label: string }[] = [];

  let lastMonth = -1;
  for (let w = 0; w < totalWeeks; w++) {
    const weekStart = new Date(startDate);
    weekStart.setDate(weekStart.getDate() + w * 7);
    if (weekStart.getMonth() !== lastMonth) {
      lastMonth = weekStart.getMonth();
      monthLabels.push({
        x: dayLabelWidth + w * step,
        label: weekStart.toLocaleString("en-US", { month: "short" }),
      });
    }
    for (let d = 0; d < 7; d++) {
      const cellDate = new Date(startDate);
      cellDate.setDate(cellDate.getDate() + w * 7 + d);
      if (cellDate > latest || cellDate < earliest) continue;
      const dateStr = cellDate.toISOString().slice(0, 10);
      const count = dayCounts[dateStr] || 0;
      const dayName = cellDate.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });
      cells.push({
        x: dayLabelWidth + w * step,
        y: headerHeight + d * step,
        date: dateStr,
        count,
        color: getColor(count, maxCount, palette),
        label: `${dayName}: ${count} session${count !== 1 ? "s" : ""}`,
      });
    }
  }

  const svgWidth = dayLabelWidth + totalWeeks * step + 4;
  const svgHeight = headerHeight + 7 * step;

  return (
    <div className="bg-white rounded-lg border border-slate-200 p-4">
      <div className="flex items-center justify-between mb-3">
        <div>
          <h3 className="text-[12px] font-medium text-slate-700">{label}</h3>
          <p className="text-[11px] text-slate-400">{totalSessions} sessions across {activeDays} active days</p>
        </div>
        <div className="flex items-center gap-1 text-[9px] text-slate-400">
          <span>Less</span>
          {palette.map((c, i) => (
            <span key={i} className="w-2.5 h-2.5 rounded-sm inline-block" style={{ backgroundColor: c }} />
          ))}
          <span>More</span>
        </div>
      </div>
      <div className="overflow-x-auto scrollbar-none">
        <svg width={svgWidth} height={svgHeight} className="block">
          {DAY_LABELS.map((l, i) =>
            l ? (
              <text key={i} x={0} y={headerHeight + i * step + 9} fill="#94a3b8" fontSize={8} fontFamily="system-ui">
                {l}
              </text>
            ) : null
          )}
          {monthLabels.map((m) => (
            <text key={m.x} x={m.x} y={10} fill="#94a3b8" fontSize={8} fontFamily="system-ui">
              {m.label}
            </text>
          ))}
          {cells.map((c) => (
            <rect key={c.date} x={c.x} y={c.y} width={cellSize} height={cellSize} fill={c.color} rx={2}>
              <title>{c.label}</title>
            </rect>
          ))}
        </svg>
      </div>
    </div>
  );
}

export function ActivityHeatmapSection({ data }: { data: AllData }) {
  const { mode } = useViewMode();

  const { allDayCounts, devDayCounts } = useMemo(() => {
    const all: Record<string, number> = {};
    const byDev: Record<string, Record<string, number>> = {};

    for (const s of data.a07_conversation_dynamics.per_session) {
      if (!s.session_start) continue;
      const date = s.session_start.slice(0, 10);
      all[date] = (all[date] || 0) + 1;
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      const dev = (s as any).developer as string | undefined;
      if (dev) {
        if (!byDev[dev]) byDev[dev] = {};
        byDev[dev][date] = (byDev[dev][date] || 0) + 1;
      }
    }
    return { allDayCounts: all, devDayCounts: byDev };
  }, [data]);

  return (
    <Section id="activity" title="AI Activity" subtitle="Daily session activity across the team">
      <Heatmap dayCounts={allDayCounts} palette={COLORS} label="All Developers" />

      {mode === "dev" && (
        <div className="grid gap-3 mt-3">
          {Object.entries(devDayCounts).map(([dev, counts]) => (
            <Heatmap
              key={dev}
              dayCounts={counts}
              palette={DEV_COLOR_MAP[dev] ?? COLORS}
              label={dev}
            />
          ))}
        </div>
      )}
    </Section>
  );
}
