import { describe, expect, it } from "vitest";
import {
  buildStarChange,
  groupPortfoliosForHome,
  planFolderDeletion,
  planFolderReorder,
} from "./portfolioUserConfig";

describe("planFolderReorder", () => {
  it("renumbers every folder to its index in the requested order", () => {
    const plan = planFolderReorder({
      currentIds: [1n, 2n, 3n],
      orderedIds: [3n, 1n, 2n],
    });

    expect(plan).toEqual({
      updates: [
        { id: 3n, position: 0 },
        { id: 1n, position: 1 },
        { id: 2n, position: 2 },
      ],
    });
  });

  it("rejects an order naming a folder the user does not have", () => {
    const plan = planFolderReorder({
      currentIds: [1n, 2n],
      orderedIds: [2n, 99n],
    });

    expect(plan).toEqual({
      error: "Folder order does not match your folders",
    });
  });

  it("rejects an order that lists the same folder twice", () => {
    const plan = planFolderReorder({
      currentIds: [1n, 2n],
      orderedIds: [1n, 1n, 2n],
    });

    expect(plan).toEqual({
      error: "Folder order does not match your folders",
    });
  });
});

describe("groupPortfoliosForHome", () => {
  it("groups portfolios into folders ordered by position, with the rest unfiled", () => {
    const grouped = groupPortfoliosForHome({
      portfolios: [{ id: 1n }, { id: 2n }, { id: 3n }],
      configs: [
        { portfolioId: 1n, folderId: 10n, starredAt: null },
        { portfolioId: 2n, folderId: 11n, starredAt: null },
      ],
      folders: [
        { id: 10n, name: "SHDF Wave 3", position: 1 },
        { id: 11n, name: "Demos", position: 0 },
      ],
    });

    expect(grouped.folders).toEqual([
      { id: 11n, name: "Demos", portfolios: [{ id: 2n }] },
      { id: 10n, name: "SHDF Wave 3", portfolios: [{ id: 1n }] },
    ]);
    expect(grouped.unfiled).toEqual([{ id: 3n }]);
  });

  it("floats starred portfolios to the top of their group and lists them most-recently-starred first", () => {
    const grouped = groupPortfoliosForHome({
      portfolios: [{ id: 1n }, { id: 2n }, { id: 3n }, { id: 4n }],
      configs: [
        { portfolioId: 1n, folderId: 10n, starredAt: null },
        { portfolioId: 2n, folderId: 10n, starredAt: new Date("2026-07-01") },
        { portfolioId: 4n, folderId: null, starredAt: new Date("2026-07-05") },
      ],
      folders: [{ id: 10n, name: "SHDF Wave 3", position: 0 }],
    });

    expect(grouped.folders[0].portfolios).toEqual([{ id: 2n }, { id: 1n }]);
    expect(grouped.unfiled).toEqual([{ id: 4n }, { id: 3n }]);
    expect(grouped.starred).toEqual([{ id: 4n }, { id: 2n }]);
  });
});

describe("planFolderDeletion", () => {
  it("unfiles exactly the configs in the folder, then deletes the folder", () => {
    const plan = planFolderDeletion({
      folderId: 10n,
      configs: [
        { id: 1n, folderId: 10n },
        { id: 2n, folderId: 11n },
        { id: 3n, folderId: 10n },
        { id: 4n, folderId: null },
      ],
    });

    expect(plan).toEqual({
      unfileConfigIds: [1n, 3n],
      deleteFolderId: 10n,
    });
  });
});

describe("buildStarChange", () => {
  it("starring stamps the moment, unstarring clears it", () => {
    const now = new Date("2026-07-07T12:00:00Z");

    expect(buildStarChange({ starred: true, now })).toEqual({ starredAt: now });
    expect(buildStarChange({ starred: false, now })).toEqual({
      starredAt: null,
    });
  });
});
