import { cleanup, fireEvent, render, screen } from "@testing-library/react";
import { FileDrop, type FileDropPresentation } from "@repo/ui";
import { afterEach, describe, expect, it, vi } from "vitest";

afterEach(() => {
  cleanup();
});

const emptyModelPresentation = {
  accept: ".glb",
  allowsFileBatch: true,
  allowsFolderSelection: true,
  emptyDescription: "or drop its local dependencies",
  emptyTitle: "Upload model",
  items: [],
  presenter: "model-item",
  secondaryActions: [],
} satisfies FileDropPresentation<"model", never, never>;

describe("FileDrop model folder selection", () => {
  it("offers distinct file and folder package inputs", () => {
    const onFilesSelect = vi.fn();
    const onFolderSelect = vi.fn();
    const folderFiles = [
      new File([new Uint8Array([1])], "scene.gltf"),
      new File([new Uint8Array([2])], "mesh.bin"),
    ];
    Object.defineProperty(folderFiles[0], "webkitRelativePath", {
      value: "model/scene.gltf",
    });
    Object.defineProperty(folderFiles[1], "webkitRelativePath", {
      value: "model/mesh.bin",
    });

    render(
      <FileDrop
        onFilesSelect={onFilesSelect}
        onFolderSelect={onFolderSelect}
        presentation={emptyModelPresentation}
      />,
    );

    const fileInput = screen.getByLabelText("Upload model") as HTMLInputElement;
    const folderInput = screen.getByLabelText(
      "Upload model folder",
    ) as HTMLInputElement;
    const fileClick = vi.spyOn(fileInput, "click");
    const folderClick = vi.spyOn(folderInput, "click");

    fireEvent.click(screen.getByRole("button", { name: "Choose files" }));
    fireEvent.click(screen.getByRole("button", { name: "Choose folder" }));
    expect(fileClick).toHaveBeenCalledTimes(1);
    expect(folderClick).toHaveBeenCalledTimes(1);
    expect(folderInput.hasAttribute("webkitdirectory")).toBe(true);
    expect(folderInput.hasAttribute("directory")).toBe(true);

    fireEvent.change(folderInput, { target: { files: folderFiles } });

    expect(onFolderSelect).toHaveBeenCalledWith(folderFiles);
    expect(onFilesSelect).not.toHaveBeenCalled();
  });
});
