import type { MdtodoTaskRecord } from "@/api";

export type TreeKeyAction =
  | "previous"
  | "next"
  | "expand"
  | "collapse"
  | "parent"
  | "none";

export function taskParentRefs(
  task: MdtodoTaskRecord,
  tasks: MdtodoTaskRecord[],
): string[] {
  const byRef = new Map(tasks.map((item) => [item.taskRef, item]));
  const parents: string[] = [];
  const visited = new Set<string>();
  let parentRef = task.parentTaskRef || null;
  while (parentRef && !visited.has(parentRef)) {
    visited.add(parentRef);
    parents.unshift(parentRef);
    parentRef = byRef.get(parentRef)?.parentTaskRef || null;
  }
  return parents;
}

export function visibleTasks(
  tasks: MdtodoTaskRecord[],
  collapsed: Set<string>,
  selectedTaskRef: string | null,
): MdtodoTaskRecord[] {
  const selected = tasks.find((task) => task.taskRef === selectedTaskRef);
  const selectedPath = new Set(
    selected ? [...taskParentRefs(selected, tasks), selected.taskRef] : [],
  );
  return tasks.filter((task) => {
    const hiddenByCollapsedParent = taskParentRefs(task, tasks).some(
      (parentRef) => collapsed.has(parentRef),
    );
    return !hiddenByCollapsedParent || selectedPath.has(task.taskRef);
  });
}

export function treeKeyAction(
  key: string,
  expanded: boolean,
  hasChildren: boolean,
): TreeKeyAction {
  if (key === "ArrowUp") return "previous";
  if (key === "ArrowDown") return "next";
  if (key === "ArrowRight" && hasChildren && !expanded) return "expand";
  if (key === "ArrowLeft" && hasChildren && expanded) return "collapse";
  if (key === "ArrowLeft") return "parent";
  return "none";
}
