import { useCallback, useMemo, useState } from 'react';

import { tasks } from '@/data/task-repository';
import { useBoard } from '@/data/use-board';
import { toGlideTask, type GlideTask, type TaskId } from '@/domain/glide';
import { completionHaptic } from '@/lib/haptics';

export type ActionListStatus = 'loading' | 'ready' | 'empty';

export type ActionList = {
  /** High level lifecycle of the action list. */
  status: ActionListStatus;
  /** The single task to act on right now. */
  current: GlideTask | null;
  /** Ready tasks queued behind the current one. */
  rest: GlideTask[];
  /** How many unsorted tasks are waiting in the planning deck. */
  unsorted: number;
  /** Tasks actioned this session — resets to 0 each time Plan opens. */
  done: number;
  /** Mark a ready task as actioned/done. */
  complete: (id: TaskId) => void;
};

/**
 * The actioning surface, distilled into one reusable hook. Returns the ready
 * queue (the tasks that cleared resistance during planning) and a way to action
 * them — keeping the domain logic in a single, testable place per the project's
 * deep-module principle.
 */
export function useActionList(): ActionList {
  const board = useBoard(48);

  const [completedIds, setCompletedIds] = useState<Set<TaskId>>(() => new Set());

  const readyTasks = useMemo(() => board.ready.map(toGlideTask), [board.ready]);
  const liveIds = useMemo(() => new Set(readyTasks.map((task) => task.id)), [readyTasks]);

  // Optimistic removal: hide just-completed tasks immediately, then release the
  // guard once the store board has actually dropped them. Reconciled during
  // render — the React-recommended alternative to a state-syncing effect.
  let activeCompleted = completedIds;
  if ([...completedIds].some((id) => !liveIds.has(id))) {
    activeCompleted = new Set([...completedIds].filter((id) => liveIds.has(id)));
    setCompletedIds(activeCompleted);
  }

  const visible = useMemo(
    () => readyTasks.filter((task) => !activeCompleted.has(task.id)),
    [readyTasks, activeCompleted]
  );

  const complete = useCallback((id: TaskId) => {
    completionHaptic();
    setCompletedIds((current) => new Set(current).add(id));
    tasks.complete(id);
  }, []);

  const current = visible[0] ?? null;
  const rest = useMemo(() => visible.slice(1), [visible]);
  const unsorted = board.open.length;
  const done = board.doneThisSession;
  const status: ActionListStatus = current ? 'ready' : 'empty';

  return { status, current, rest, unsorted, done, complete };
}
