import { Gantt } from "@svar-ui/react-gantt";
import "@svar-ui/react-gantt/style.css";
import type { DemandPlanningRollupDto, GanttTaskDto, PlanningExceptionDto, PlanningTimelineDto } from "@mrp/shared";
import { useEffect, useMemo, useState } from "react";
import { Link } from "react-router-dom";

import { useAuth } from "../../auth/AuthProvider";
import { ApiError, api } from "../../lib/api";
import { useTheme } from "../../theme/ThemeProvider";

type WorkbenchMode = "overview" | "gantt" | "heatmap" | "agenda";
type FocusRecord = {
  id: string;
  title: string;
  kind: "PROJECT" | "WORK_ORDER" | "OPERATION" | "MILESTONE";
  status: string;
  ownerLabel: string | null;
  start: string;
  end: string;
  progress: number;
  detailHref: string | null;
  parentId: string | null;
};

type HeatmapCell = {
  dateKey: string;
  count: number;
  lateCount: number;
  blockedCount: number;
  tasks: FocusRecord[];
};

const DAY_MS = 24 * 60 * 60 * 1000;

function formatDate(value: string | null, options?: Intl.DateTimeFormatOptions) {
  if (!value) {
    return "Unscheduled";
  }

  return new Intl.DateTimeFormat("en-US", options ?? {
    month: "short",
    day: "numeric",
  }).format(new Date(value));
}

function startOfDay(value: Date) {
  return new Date(value.getFullYear(), value.getMonth(), value.getDate());
}

function dateKey(value: Date) {
  return value.toISOString().slice(0, 10);
}

function parseFocusKind(task: GanttTaskDto): FocusRecord["kind"] {
  if (task.type === "project") {
    return "PROJECT";
  }
  if (task.type === "milestone") {
    return "MILESTONE";
  }
  if (task.id.startsWith("work-order-operation-")) {
    return "OPERATION";
  }
  return "WORK_ORDER";
}

function densityTone(cell: HeatmapCell) {
  if (cell.lateCount > 0) {
    return "border-rose-400/60 bg-rose-500/25";
  }
  if (cell.blockedCount > 0) {
    return "border-amber-300/60 bg-amber-400/25";
  }
  if (cell.count >= 4) {
    return "border-brand/80 bg-brand/35";
  }
  if (cell.count >= 2) {
    return "border-brand/50 bg-brand/20";
  }
  if (cell.count === 1) {
    return "border-line/80 bg-page/80";
  }
  return "border-line/60 bg-surface/70";
}

function buildFocusRecords(tasks: GanttTaskDto[]) {
  return tasks.map((task) => ({
    id: task.id,
    title: task.text,
    kind: parseFocusKind(task),
    status: task.status ?? "PLANNED",
    ownerLabel: task.ownerLabel ?? null,
    start: task.start,
    end: task.end,
    progress: task.progress,
    detailHref: task.detailHref ?? null,
    parentId: task.parentId ?? null,
  }));
}

export function GanttPage() {
  const { token } = useAuth();
  const { mode } = useTheme();
  const [timeline, setTimeline] = useState<PlanningTimelineDto | null>(null);
  const [planningRollup, setPlanningRollup] = useState<DemandPlanningRollupDto | null>(null);
  const [status, setStatus] = useState("Loading live planning timeline...");
  const [workbenchMode, setWorkbenchMode] = useState<WorkbenchMode>("overview");
  const [selectedFocusId, setSelectedFocusId] = useState<string | null>(null);
  const [selectedHeatmapDate, setSelectedHeatmapDate] = useState<string | null>(null);

  useEffect(() => {
    if (!token) {
      return;
    }

    Promise.all([api.getPlanningTimeline(token), api.getDemandPlanningRollup(token)])
      .then(([data, rollup]) => {
        setTimeline(data);
        setPlanningRollup(rollup);
        setStatus("Planning workbench loaded.");
      })
      .catch((error: unknown) => {
        const message = error instanceof ApiError ? error.message : "Unable to load planning timeline.";
        setStatus(message);
      });
  }, [token]);

  const tasks = timeline?.tasks ?? [];
  const links = timeline?.links ?? [];
  const summary = timeline?.summary;
  const exceptions = timeline?.exceptions ?? [];
  const focusRecords = useMemo(() => buildFocusRecords(tasks), [tasks]);
  const focusById = useMemo(() => new Map(focusRecords.map((record) => [record.id, record])), [focusRecords]);
  const selectedFocus = selectedFocusId ? focusById.get(selectedFocusId) ?? null : focusRecords[0] ?? null;
  const ganttCellHeight = 38;
  const ganttScaleHeight = 54;
  const ganttHeight = Math.max(520, tasks.length * ganttCellHeight + ganttScaleHeight);

  const heatmap = useMemo(() => {
    const start = summary ? startOfDay(new Date(summary.horizonStart)) : startOfDay(new Date());
    const cells = new Map<string, HeatmapCell>();
    for (let index = 0; index < 84; index += 1) {
      const nextDate = new Date(start.getTime() + index * DAY_MS);
      cells.set(dateKey(nextDate), { dateKey: dateKey(nextDate), count: 0, lateCount: 0, blockedCount: 0, tasks: [] });
    }

    for (const record of focusRecords) {
      if (record.kind === "PROJECT") {
        continue;
      }
      const startDate = startOfDay(new Date(record.start));
      const endDate = startOfDay(new Date(record.end));
      for (let cursor = startDate.getTime(); cursor <= endDate.getTime(); cursor += DAY_MS) {
        const key = dateKey(new Date(cursor));
        const current = cells.get(key);
        if (!current) {
          continue;
        }
        current.count += 1;
        if (record.status === "AT_RISK" || record.status === "ON_HOLD") {
          current.blockedCount += 1;
        }
        if (new Date(record.end).getTime() < Date.now() && record.status !== "COMPLETE" && record.status !== "CANCELLED") {
          current.lateCount += 1;
        }
        current.tasks.push(record);
      }
    }

    return [...cells.values()];
  }, [focusRecords, summary]);

  const selectedHeatmapCell = selectedHeatmapDate ? heatmap.find((cell) => cell.dateKey === selectedHeatmapDate) ?? null : null;
  const agendaItems = useMemo(
    () => [...focusRecords]
      .filter((record) => record.kind !== "OPERATION")
      .sort((left, right) => new Date(left.end).getTime() - new Date(right.end).getTime())
      .slice(0, 18),
    [focusRecords]
  );

  const modeOptions: Array<{ value: WorkbenchMode; label: string; detail: string }> = [
    { value: "overview", label: "Overview", detail: "Dense planner board" },
    { value: "gantt", label: "Timeline", detail: "Classic gantt lens" },
    { value: "heatmap", label: "Heatmap", detail: "Load by day" },
    { value: "agenda", label: "Agenda", detail: "Upcoming due flow" },
  ];

  return (
    <section className="space-y-4">
      <div className="rounded-[20px] border border-line/70 bg-surface/90 p-4 shadow-panel 2xl:p-5">
        <div className="flex flex-col gap-3 xl:flex-row xl:items-start xl:justify-between">
          <div>
            <p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Planning</p>
            <h3 className="mt-2 text-2xl font-bold text-text">Planning Workbench</h3>
            <p className="mt-2 max-w-4xl text-sm text-muted">A reactive planning surface for projects, work orders, operations, shortages, and schedule risk. Use it as the daily planner cockpit, not just a chart.</p>
          </div>
          <div className="rounded-[18px] border border-line/70 bg-page/60 px-3 py-3 text-sm">
            <div className="text-xs font-semibold uppercase tracking-[0.18em] text-muted">Workbench Status</div>
            <div className="mt-2 font-semibold text-text">{status}</div>
          </div>
        </div>
        <div className="mt-5 grid gap-3 xl:grid-cols-4">
          {modeOptions.map((option) => (
            <button key={option.value} type="button" onClick={() => setWorkbenchMode(option.value)} className={`rounded-[18px] border px-3 py-3 text-left transition ${workbenchMode === option.value ? "border-brand bg-brand/10" : "border-line/70 bg-page/60 hover:border-brand/40"}`}>
              <div className="text-xs font-semibold uppercase tracking-[0.18em] text-muted">{option.label}</div>
              <div className="mt-2 text-sm font-semibold text-text">{option.detail}</div>
            </button>
          ))}
        </div>
      </div>

      <section className="grid gap-3 xl:grid-cols-8">
        <MetricCard label="Active Projects" value={summary?.activeProjects ?? 0} />
        <MetricCard label="At Risk" value={summary?.atRiskProjects ?? 0} />
        <MetricCard label="Overdue Projects" value={summary?.overdueProjects ?? 0} />
        <MetricCard label="Active Work" value={summary?.activeWorkOrders ?? 0} />
        <MetricCard label="Overdue Work" value={summary?.overdueWorkOrders ?? 0} />
        <MetricCard label="Unscheduled" value={summary?.unscheduledWorkOrders ?? 0} />
        <MetricCard label="Shortage Items" value={planningRollup?.summary.uncoveredItemCount ?? 0} />
        <MetricCard label="Build / Buy" value={planningRollup ? `${planningRollup.summary.totalBuildQuantity} / ${planningRollup.summary.totalPurchaseQuantity}` : "0 / 0"} />
      </section>

      <div className="grid gap-3 xl:grid-cols-[320px_minmax(0,1fr)_360px]">
        <aside className="space-y-3">
          <section className="rounded-[20px] border border-line/70 bg-surface/90 p-4 shadow-panel">
            <div className="flex items-center justify-between gap-3">
              <div>
                <p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Exception Rail</p>
                <p className="mt-2 text-sm text-muted">Late, at-risk, and unscheduled items that require planner attention.</p>
              </div>
              <span className="rounded-full border border-line/70 px-2 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-muted">{exceptions.length}</span>
            </div>
            {exceptions.length === 0 ? (
              <div className="mt-5 rounded-[18px] border border-dashed border-line/70 bg-page/60 px-4 py-8 text-center text-sm text-muted">No planning exceptions are active.</div>
            ) : (
              <div className="mt-5 space-y-3">
                {exceptions.map((exception: PlanningExceptionDto) => (
                  <button key={exception.id} type="button" onClick={() => setSelectedFocusId(exception.id.startsWith("project-") ? exception.id : exception.id.replace("work-order-unscheduled-", "work-order-"))} className="block w-full rounded-[18px] border border-line/70 bg-page/60 p-3 text-left transition hover:bg-page/80">
                    <div className="flex items-start justify-between gap-3">
                      <div>
                        <div className="text-xs font-semibold uppercase tracking-[0.16em] text-muted">{exception.kind === "PROJECT" ? "Project" : "Work Order"}</div>
                        <div className="mt-1 font-semibold text-text">{exception.title}</div>
                        <div className="mt-2 text-xs text-muted">{exception.ownerLabel ?? "No owner context"}</div>
                      </div>
                      <span className="rounded-full border border-line/70 px-2 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-muted">{exception.status.replaceAll("_", " ")}</span>
                    </div>
                    <div className="mt-3 text-xs text-muted">Due: {formatDate(exception.dueDate)}</div>
                  </button>
                ))}
              </div>
            )}
          </section>
          <section className="rounded-[20px] border border-line/70 bg-surface/90 p-4 shadow-panel">
            <p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Planner Actions</p>
            <div className="mt-4 space-y-2 rounded-[18px] border border-line/70 bg-page/60 p-3 text-sm">
              <div className="flex items-center justify-between gap-3"><span className="text-muted">Uncovered quantity</span><span className="font-semibold text-text">{planningRollup?.summary.totalUncoveredQuantity ?? 0}</span></div>
              <div className="flex items-center justify-between gap-3"><span className="text-muted">Projects with linked demand</span><span className="font-semibold text-text">{planningRollup?.summary.projectCount ?? 0}</span></div>
            </div>
            <div className="mt-4 flex flex-wrap gap-2">
              <Link to="/projects" className="rounded-2xl border border-line/70 px-2 py-2 text-sm font-semibold text-text">Open projects</Link>
              <Link to="/manufacturing/work-orders" className="rounded-2xl border border-line/70 px-2 py-2 text-sm font-semibold text-text">Open work orders</Link>
              <Link to="/purchasing/orders" className="rounded-2xl border border-line/70 px-2 py-2 text-sm font-semibold text-text">Open purchasing</Link>
            </div>
          </section>
        </aside>

        <div className="rounded-[20px] border border-line/70 bg-surface/90 p-4 shadow-panel">
          {workbenchMode === "overview" ? <OverviewBoard focusRecords={focusRecords} onSelect={setSelectedFocusId} /> : null}
          {workbenchMode === "gantt" ? (
            <div className={`gantt-theme overflow-x-auto overflow-y-visible rounded-[18px] border border-line/70 bg-page/60 p-4 ${mode === "dark" ? "wx-willow-dark-theme" : "wx-willow-theme"}`}>
              <div className="mb-4 flex flex-wrap items-center justify-between gap-3">
                <div>
                  <p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Schedule Window</p>
                  <p className="mt-2 text-sm text-muted">{summary ? `${formatDate(summary.horizonStart)} through ${formatDate(summary.horizonEnd)}` : "Waiting for live schedule data."}</p>
                </div>
                <div className="rounded-2xl border border-line/70 bg-surface/80 px-3 py-2 text-xs font-semibold uppercase tracking-[0.18em] text-muted">{tasks.length} schedule rows</div>
              </div>
              <div style={{ height: `${ganttHeight}px`, minWidth: "100%" }}>
                <Gantt
                  tasks={tasks.map((task: GanttTaskDto) => ({
                    ...task,
                    start: new Date(task.start),
                    end: new Date(task.end),
                    parent: task.parentId ?? undefined,
                  }))}
                  links={links}
                  cellHeight={ganttCellHeight}
                  scaleHeight={ganttScaleHeight}
                />
              </div>
            </div>
          ) : null}
          {workbenchMode === "heatmap" ? <HeatmapBoard heatmap={heatmap} selectedDate={selectedHeatmapDate} onSelectDate={setSelectedHeatmapDate} /> : null}
          {workbenchMode === "agenda" ? <AgendaBoard records={agendaItems} onSelect={setSelectedFocusId} /> : null}
        </div>

        <aside className="space-y-3">
          <section className="rounded-[20px] border border-line/70 bg-surface/90 p-4 shadow-panel">
            <p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Focus Drawer</p>
            {selectedFocus ? (
              <div className="mt-4 space-y-3">
                <div className="rounded-[18px] border border-line/70 bg-page/60 p-3">
                  <div className="text-xs font-semibold uppercase tracking-[0.16em] text-muted">{selectedFocus.kind}</div>
                  <div className="mt-2 text-base font-bold text-text">{selectedFocus.title}</div>
                  <div className="mt-2 text-xs text-muted">{selectedFocus.ownerLabel ?? "No context label"}</div>
                </div>
                <div className="rounded-[18px] border border-line/70 bg-page/60 p-3 text-sm">
                  <div className="flex items-center justify-between gap-3"><span className="text-muted">Status</span><span className="font-semibold text-text">{selectedFocus.status.replaceAll("_", " ")}</span></div>
                  <div className="mt-2 flex items-center justify-between gap-3"><span className="text-muted">Window</span><span className="font-semibold text-text">{formatDate(selectedFocus.start)} - {formatDate(selectedFocus.end)}</span></div>
                  <div className="mt-2 flex items-center justify-between gap-3"><span className="text-muted">Progress</span><span className="font-semibold text-text">{selectedFocus.progress}%</span></div>
                </div>
                <div className="flex flex-wrap gap-2">
                  {selectedFocus.detailHref ? <Link to={selectedFocus.detailHref} className="rounded-2xl bg-brand px-2 py-2 text-sm font-semibold text-white">Open record</Link> : null}
                  <button type="button" onClick={() => setWorkbenchMode("gantt")} className="rounded-2xl border border-line/70 px-2 py-2 text-sm font-semibold text-text">View in timeline</button>
                  <button type="button" onClick={() => setWorkbenchMode("heatmap")} className="rounded-2xl border border-line/70 px-2 py-2 text-sm font-semibold text-text">View load</button>
                </div>
              </div>
            ) : (
              <div className="mt-5 rounded-[18px] border border-dashed border-line/70 bg-page/60 px-4 py-8 text-center text-sm text-muted">Select a project or work order to inspect it.</div>
            )}
          </section>
          <section className="rounded-[20px] border border-line/70 bg-surface/90 p-4 shadow-panel">
            <p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">{workbenchMode === "heatmap" ? "Selected Day" : "Upcoming Agenda"}</p>
            {workbenchMode === "heatmap"
              ? (selectedHeatmapCell ? <SelectedDayPanel cell={selectedHeatmapCell} onSelect={setSelectedFocusId} /> : <div className="mt-5 rounded-[18px] border border-dashed border-line/70 bg-page/60 px-4 py-8 text-center text-sm text-muted">Select a day in the heatmap to inspect its load.</div>)
              : <AgendaBoard records={agendaItems.slice(0, 8)} onSelect={setSelectedFocusId} compact />}
          </section>
        </aside>
      </div>
    </section>
  );
}

function MetricCard({ label, value }: { label: string; value: string | number }) {
  return (
    <article className="rounded-[18px] border border-line/70 bg-surface/90 px-3 py-3 shadow-panel">
      <p className="text-xs font-semibold uppercase tracking-[0.18em] text-muted">{label}</p>
      <div className="mt-2 text-xl font-extrabold text-text">{value}</div>
    </article>
  );
}

function OverviewBoard({ focusRecords, onSelect }: { focusRecords: FocusRecord[]; onSelect: (id: string) => void }) {
  const projects = focusRecords.filter((record) => record.kind === "PROJECT").slice(0, 6);
  const operations = focusRecords.filter((record) => record.kind === "OPERATION").slice(0, 10);
  const workOrders = focusRecords.filter((record) => record.kind === "WORK_ORDER").slice(0, 10);

  return (
    <div className="space-y-4">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <div>
          <p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Overview</p>
          <p className="mt-2 text-sm text-muted">Scan project rollups, active work, and operation load without leaving the planner.</p>
        </div>
      </div>
      <div className="grid gap-3 xl:grid-cols-[minmax(0,1.15fr)_minmax(0,0.85fr)]">
        <section className="rounded-[18px] border border-line/70 bg-page/60 p-3">
          <p className="text-xs font-semibold uppercase tracking-[0.18em] text-muted">Program Queue</p>
          <div className="mt-3 space-y-3">
            {projects.map((record) => (
              <button key={record.id} type="button" onClick={() => onSelect(record.id)} className="block w-full rounded-[16px] border border-line/70 bg-surface/80 p-3 text-left transition hover:bg-surface">
                <div className="flex flex-wrap items-center justify-between gap-3">
                  <div>
                    <div className="font-semibold text-text">{record.title}</div>
                    <div className="mt-1 text-xs text-muted">{record.ownerLabel ?? "No owner context"}</div>
                  </div>
                  <div className="text-right text-xs text-muted">
                    <div>{record.status.replaceAll("_", " ")}</div>
                    <div>{record.progress}% progress</div>
                  </div>
                </div>
              </button>
            ))}
          </div>
        </section>
        <section className="rounded-[18px] border border-line/70 bg-page/60 p-3">
          <p className="text-xs font-semibold uppercase tracking-[0.18em] text-muted">Operation Load</p>
          <div className="mt-3 space-y-2">
            {operations.map((record) => (
              <button key={record.id} type="button" onClick={() => onSelect(record.id)} className="flex w-full items-center justify-between gap-3 rounded-[16px] border border-line/70 bg-surface/80 px-3 py-2 text-left transition hover:bg-surface">
                <div>
                  <div className="font-semibold text-text">{record.title}</div>
                  <div className="mt-1 text-xs text-muted">{record.ownerLabel ?? "No parent work order"}</div>
                </div>
                <div className="text-xs text-muted">{formatDate(record.start)} - {formatDate(record.end)}</div>
              </button>
            ))}
          </div>
        </section>
      </div>
      <section className="rounded-[18px] border border-line/70 bg-page/60 p-3">
        <p className="text-xs font-semibold uppercase tracking-[0.18em] text-muted">Active Work Orders</p>
        <div className="mt-3 grid gap-3 xl:grid-cols-2">
          {workOrders.map((record) => (
            <button key={record.id} type="button" onClick={() => onSelect(record.id)} className="rounded-[16px] border border-line/70 bg-surface/80 p-3 text-left transition hover:bg-surface">
              <div className="font-semibold text-text">{record.title}</div>
              <div className="mt-2 flex items-center justify-between gap-3 text-xs text-muted">
                <span>{record.status.replaceAll("_", " ")}</span>
                <span>{record.progress}%</span>
              </div>
            </button>
          ))}
        </div>
      </section>
    </div>
  );
}

function HeatmapBoard({ heatmap, selectedDate, onSelectDate }: { heatmap: HeatmapCell[]; selectedDate: string | null; onSelectDate: (date: string) => void }) {
  const weeks = [];
  for (let index = 0; index < heatmap.length; index += 7) {
    weeks.push(heatmap.slice(index, index + 7));
  }

  return (
    <div className="space-y-4">
      <div>
        <p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Load Heatmap</p>
        <p className="mt-2 text-sm text-muted">Dense daily load scan for operations and work orders, with late and blocked pressure highlighted.</p>
      </div>
      <div className="overflow-x-auto rounded-[18px] border border-line/70 bg-page/60 p-4">
        <div className="flex gap-2">
          <div className="flex flex-col gap-2 pt-7">
            {["M", "T", "W", "T", "F", "S", "S"].map((label) => <div key={label} className="h-9 text-xs font-semibold text-muted">{label}</div>)}
          </div>
          {weeks.map((week, weekIndex) => (
            <div key={weekIndex} className="flex flex-col gap-2">
              <div className="h-5 text-[11px] font-semibold uppercase tracking-[0.16em] text-muted">{formatDate(week[0]?.dateKey ?? null, { month: "short" })}</div>
              {week.map((cell) => (
                <button
                  key={cell.dateKey}
                  type="button"
                  onClick={() => onSelectDate(cell.dateKey)}
                  className={`h-9 w-9 rounded-md border text-[10px] font-semibold transition hover:scale-110 ${densityTone(cell)} ${selectedDate === cell.dateKey ? "ring-2 ring-brand" : ""}`}
                  title={`${cell.dateKey}: ${cell.count} scheduled`}
                >
                  {new Date(cell.dateKey).getDate()}
                </button>
              ))}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function AgendaBoard({ records, onSelect, compact = false }: { records: FocusRecord[]; onSelect: (id: string) => void; compact?: boolean }) {
  return (
    <div className={compact ? "mt-4 space-y-3" : "space-y-4"}>
      {!compact ? (
        <div>
          <p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Agenda</p>
          <p className="mt-2 text-sm text-muted">Upcoming projects, work orders, and milestones ordered by due date.</p>
        </div>
      ) : null}
      <div className="space-y-2">
        {records.map((record) => (
          <button key={record.id} type="button" onClick={() => onSelect(record.id)} className="flex w-full items-center justify-between gap-3 rounded-[16px] border border-line/70 bg-page/60 px-3 py-3 text-left transition hover:bg-page/80">
            <div>
              <div className="font-semibold text-text">{record.title}</div>
              <div className="mt-1 text-xs text-muted">{record.kind} - {record.ownerLabel ?? "No context"}</div>
            </div>
            <div className="text-right text-xs text-muted">
              <div>{formatDate(record.end)}</div>
              <div>{record.status.replaceAll("_", " ")}</div>
            </div>
          </button>
        ))}
      </div>
    </div>
  );
}

function SelectedDayPanel({ cell, onSelect }: { cell: HeatmapCell; onSelect: (id: string) => void }) {
  return (
    <div className="mt-4 space-y-3">
      <div className="rounded-[18px] border border-line/70 bg-page/60 p-3">
        <div className="text-sm font-semibold text-text">{formatDate(cell.dateKey, { weekday: "short", month: "short", day: "numeric" })}</div>
        <div className="mt-2 flex items-center justify-between gap-3 text-xs text-muted">
          <span>{cell.count} scheduled</span>
          <span>{cell.lateCount} late</span>
        </div>
      </div>
      <div className="space-y-2">
        {cell.tasks.slice(0, 8).map((task) => (
          <button key={task.id} type="button" onClick={() => onSelect(task.id)} className="block w-full rounded-[16px] border border-line/70 bg-page/60 p-3 text-left transition hover:bg-page/80">
            <div className="font-semibold text-text">{task.title}</div>
            <div className="mt-1 text-xs text-muted">{task.status.replaceAll("_", " ")} - {task.ownerLabel ?? "No context"}</div>
          </button>
        ))}
      </div>
    </div>
  );
}
