// frontend/tests/tasks/tree.test.ts
import { describe, expect, it } from "vitest";
import {
  buildIndex,
  dueLabel,
  editTree,
  findPath,
  isSoon,
  pct,
  stat,
} from "@/lib/tasks/tree";
import type { Folder, Task } from "@/lib/types";

function t(id: string, status: Task["status"], children: Task[] = [], due: string | null = null): Task {
  return {
    id,
    project_id: "biz-report",
    parent_id: null,
    title: id,
    status,
    assignee_id: "jiwoo",
    due,
    prio: "보통",
    notes: "",
    est: "",
    delegated: false,
    sort_order: 0,
    created_at: "",
    updated_at: "",
    comments: [],
    children,
  };
}

describe("tree utils", () => {
  it("findPath 무한 중첩 경로", () => {
    const tree = [t("k1", "doing", [t("kx7", "doing", [t("kx9", "todo")])])];
    const p = findPath(tree, "kx9");
    expect(p?.map((n) => n.id)).toEqual(["k1", "kx7", "kx9"]);
  });

  it("editTree 깊은 노드 갱신 (형제 불변)", () => {
    const tree = [t("k1", "doing", [t("a", "todo"), t("b", "todo")])];
    const next = editTree(tree, "b", (n) => ({ ...n, status: "done" }));
    expect(next[0].children[0].status).toBe("todo"); // a 불변
    expect(next[0].children[1].status).toBe("done"); // b 변경
  });

  it("stat/pct 진행률", () => {
    const node = t("k", "doing", [t("a", "done"), t("b", "done"), t("c", "todo")]);
    expect(stat(node)).toEqual({ total: 3, done: 2 });
    expect(pct(node)).toBe(67);
  });

  it("dueLabel ISO → 6/8", () => {
    expect(dueLabel("2026-06-08")).toBe("6/8");
    expect(dueLabel(null)).toBe("—");
  });

  it("isSoon: due<=8 && !done", () => {
    expect(isSoon(t("a", "todo", [], "2026-06-08"))).toBe(true);
    expect(isSoon(t("a", "done", [], "2026-06-08"))).toBe(false);
    expect(isSoon(t("a", "todo", [], "2026-06-20"))).toBe(false);
  });

  it("buildIndex isDescendant 필터", () => {
    const folders: Folder[] = [
      {
        id: "work",
        name: "업무",
        tone: "ink",
        icon: "folder",
        sort_order: 0,
        is_system: true,
        projects: [
          {
            id: "biz",
            folder_id: "work",
            parent_id: null,
            name: "경영",
            tone: "coral",
            sort_order: 0,
            pinned: false,
            task_count: 0,
            children: [
              {
                id: "biz-report",
                folder_id: "work",
                parent_id: "biz",
                name: "리포트",
                tone: "coral",
                sort_order: 0,
                pinned: false,
                task_count: 0,
                children: [],
              },
            ],
          },
        ],
      },
    ];
    const ix = buildIndex(folders);
    expect(ix.isDescendant("biz-report", "work")).toBe(true);
    expect(ix.isDescendant("biz-report", "biz")).toBe(true);
    expect(ix.isDescendant("biz", "biz-report")).toBe(false);
    expect(ix.pathOf("biz-report").map((r) => r.id)).toEqual(["work", "biz", "biz-report"]);
  });
});
