// frontend/lib/tasks/tree.ts — 트리 유틸 (무한 중첩)
import type { Folder, Project, Task } from "@/lib/types";

/* ---- 작업 트리 ---- */
export function findPath(nodes: Task[], id: string, trail: Task[] = []): Task[] | null {
  for (const n of nodes) {
    const t = [...trail, n];
    if (n.id === id) return t;
    if (n.children?.length) {
      const r = findPath(n.children, id, t);
      if (r) return r;
    }
  }
  return null;
}

export const getNode = (nodes: Task[], id: string): Task | null => {
  const p = findPath(nodes, id);
  return p ? p[p.length - 1] : null;
};

export function editTree(nodes: Task[], id: string, fn: (n: Task) => Task): Task[] {
  return nodes.map((n) =>
    n.id === id ? fn(n) : n.children?.length ? { ...n, children: editTree(n.children, id, fn) } : n,
  );
}

export function removeFromTree(nodes: Task[], id: string): Task[] {
  return nodes
    .filter((n) => n.id !== id)
    .map((n) => (n.children?.length ? { ...n, children: removeFromTree(n.children, id) } : n));
}

export const stat = (node: Task) => {
  const c = node.children ?? [];
  return { total: c.length, done: c.filter((x) => x.status === "done").length };
};

export const pct = (node: Task) => {
  const s = stat(node);
  return s.total ? Math.round((s.done / s.total) * 100) : 0;
};

/* ---- 마감 표시 (ISO date 기준) ---- */
export const dueDay = (due: string | null): number => (due ? new Date(due).getUTCDate() : 99);
export const dueLabel = (due: string | null): string => {
  if (!due) return "—";
  const d = new Date(due);
  return `${d.getUTCMonth() + 1}/${d.getUTCDate()}`; // "6/8"
};
export const TODAY = 8; // 6월 8일 — 리스크/임박 기준 (CONTRACT 고정)
export const isSoon = (t: Task) => t.status !== "done" && dueDay(t.due) <= TODAY;

/* ---- 모든 노드 평탄화 (top-level + 하위작업) ---- */
export function flattenTasks(nodes: Task[]): Task[] {
  const out: Task[] = [];
  const walk = (ns: Task[]) => {
    for (const n of ns) {
      out.push(n);
      if (n.children?.length) walk(n.children);
    }
  };
  walk(nodes);
  return out;
}

/* ---- 프로젝트 인덱스 (buildIndex 이식) ---- */
export interface ProjIndexRec {
  id: string;
  name: string;
  tone: string;
  folder: boolean;
  parentId: string | null;
  depth: number;
  hasChildren: boolean;
}

export function buildIndex(folders: Folder[]) {
  const projects: ProjIndexRec[] = [];
  const byId: Record<string, ProjIndexRec> = {};
  const walk = (nodes: (Project | Folder)[], parentId: string | null, depth: number) => {
    for (const n of nodes) {
      const children = (n as Project).children ?? (n as Folder).projects ?? [];
      const rec: ProjIndexRec = {
        id: n.id,
        name: n.name,
        tone: (n as Project).tone ?? "faint",
        folder: "is_system" in n,
        parentId,
        depth,
        hasChildren: children.length > 0,
      };
      projects.push(rec);
      byId[n.id] = rec;
      if (children.length) walk(children, n.id, depth + 1);
    }
  };
  walk(folders, null, 0);

  const isDescendant = (pid: string, ancestorId: string): boolean => {
    let cur: ProjIndexRec | undefined = byId[pid];
    while (cur) {
      if (cur.id === ancestorId) return true;
      cur = cur.parentId ? byId[cur.parentId] : undefined;
    }
    return false;
  };
  const pathOf = (id: string): ProjIndexRec[] => {
    const out: ProjIndexRec[] = [];
    let cur: ProjIndexRec | undefined = byId[id];
    while (cur) {
      out.unshift(cur);
      cur = cur.parentId ? byId[cur.parentId] : undefined;
    }
    return out;
  };
  return { projects, byId, isDescendant, pathOf };
}

/* ---- 상태 메타 (라벨/accent) ---- */
export const STATUS_META: Record<string, { label: string; c: string }> = {
  todo: { label: "할 일", c: "var(--faint)" },
  doing: { label: "진행 중", c: "var(--blue)" },
  waiting: { label: "대기 중", c: "var(--violet)" },
  review: { label: "검토", c: "var(--coral)" },
  done: { label: "완료", c: "var(--green)" },
};
export const COLUMNS = [
  { id: "todo", label: "할 일", accent: "var(--faint)" },
  { id: "doing", label: "진행 중", accent: "var(--blue)" },
  { id: "waiting", label: "대기 중", accent: "var(--violet)" },
  { id: "review", label: "검토", accent: "var(--coral)" },
  { id: "done", label: "완료", accent: "var(--green)" },
] as const;
