import type { Board } from '@/data/use-board';

/** Most next-up titles we ship — only the large widget renders a list. */
const MAX_NEXT = 4;

/**
 * The serialisable contract handed to the home-screen widget. Deliberately flat
 * and string-only so it crosses the JS → native boundary cleanly and stays
 * trivially diffable for the push-on-change bridge.
 */
export type GlideWidgetPayload = {
  /**
   * The single task to act on now, or `''` when nothing is ready. Kept a plain
   * string (never `null`) so it survives the JS → native bridge — the widget's
   * native `updateSnapshot` host function can't convert a `null` prop value and
   * throws if handed one. The widget treats `''` as the empty state.
   */
  current: string;
  /** Titles queued behind the current one (capped at {@link MAX_NEXT}). */
  next: string[];
  /** Total ready tasks, including the current one. */
  readyCount: number;
  /** Open tasks still waiting to be planned. */
  unsorted: number;
  /** Tasks actioned this session — resets to 0 each Plan session. */
  done: number;
};

/**
 * Derive the widget payload from the local board. Mirrors the actioning surface
 * exactly — `board.ready` is already sorted ascending, so the first ready task is
 * "now" and the rest line up behind it — but straight from the store's truth, with
 * none of the UI's optimistic-completion state. Pure so it's easy to test and safe
 * to run anywhere.
 */
export function toWidgetPayload(board: Board): GlideWidgetPayload {
  const { ready, open } = board;
  return {
    current: ready[0]?.title ?? '',
    next: ready.slice(1, 1 + MAX_NEXT).map((task) => task.title),
    readyCount: ready.length,
    unsorted: open.length,
    done: board.doneThisSession,
  };
}
