import { useMemo } from 'react';

import { useTaskStore, type LocalTask } from './task-store';

const MAX_BOARD_ITEMS = 64;
const DEFAULT_LIMIT = 48;

/**
 * The board, shaped exactly like the old `api.tasks.getBoard` return so the screens
 * and the widget bridge consume it unchanged: open/ready/done buckets plus the
 * action-session tally.
 */
export type Board = {
  open: LocalTask[];
  ready: LocalTask[];
  done: LocalTask[];
  doneThisSession: number;
};

/** Stable oldest→newest by creation — the deterministic planning/action order. */
const byCreatedAsc = (a: LocalTask, b: LocalTask) => a.createdAt - b.createdAt;
/** Most-recently-completed first. */
const byCompletedDesc = (a: LocalTask, b: LocalTask) => (b.completedAt ?? 0) - (a.completedAt ?? 0);

function bucket(
  tasks: LocalTask[],
  status: LocalTask['status'],
  compare: (a: LocalTask, b: LocalTask) => number,
  limit: number
): LocalTask[] {
  return tasks
    .filter((task) => task.status === status)
    .sort(compare)
    .slice(0, limit);
}

/**
 * Reactive read of the local board. Subscribes to the task store, so any mutation
 * (a swipe, a completion, a capture) re-renders consumers — the same live-update
 * feel the Convex subscription gave, but sourced entirely on-device.
 *
 * Tombstoned (`deletedAt`) rows are excluded. Open and ready are ordered by
 * `createdAt` ascending — a stable, deterministic oldest→newest that resisting never
 * reshuffles — and done by `completedAt` descending (most-recent first). The result
 * is memoised, so an unrelated store change won't churn the board reference.
 */
export function useBoard(limit: number = DEFAULT_LIMIT): Board {
  const tasks = useTaskStore((state) => state.tasks);
  const doneThisSession = useTaskStore((state) => state.session.doneThisSession);

  return useMemo(() => {
    const capped = Math.min(Math.max(limit, 1), MAX_BOARD_ITEMS);
    const live = tasks.filter((task) => task.deletedAt === undefined);
    return {
      open: bucket(live, 'open', byCreatedAsc, capped),
      ready: bucket(live, 'ready', byCreatedAsc, capped),
      done: bucket(live, 'done', byCompletedDesc, capped),
      doneThisSession,
    };
  }, [tasks, doneThisSession, limit]);
}
