import { describe, it, expect, vi } from "vitest";
import "@testing-library/jest-dom/vitest";
import {
  fireEvent,
  renderWithProviders as render,
  screen,
} from "../utils/test-utils";
import { CustomMethodCardWizardBlocksList } from "../../app/(app)/create/components/CustomMethodCardWizard/CustomMethodCardWizardBlocksList.container";
import type { CustomMethodCardFieldBlock } from "../../lib/create/customMethodCardFieldBlocks";

function createDataTransfer() {
  const store: Record<string, string> = {};
  return {
    effectAllowed: "all",
    dropEffect: "move",
    setData(type: string, value: string) {
      store[type] = value;
    },
    getData(type: string) {
      return store[type] ?? "";
    },
  };
}

const fieldTypeLabels = {
  text: "Text",
  badges: "Badges",
  upload: "Upload",
  proportion: "Proportion",
};

const blocks: CustomMethodCardFieldBlock[] = [
  {
    kind: "text",
    id: "facet-meaning",
    blockTitle: "Meaning",
    placeholderText: "a",
  },
  {
    kind: "text",
    id: "facet-signals",
    blockTitle: "Signals",
    placeholderText: "b",
  },
];

describe("CustomMethodCardWizardBlocksList", () => {
  it("reorders when a row is dropped after dragging from the handle", () => {
    const onBlocksReorder = vi.fn();
    render(
      <CustomMethodCardWizardBlocksList
        blocks={blocks}
        fieldTypeLabels={fieldTypeLabels}
        dragHandleAriaLabel="Drag to reorder this field"
        listLabel="Fields"
        onBlocksReorder={onBlocksReorder}
        onEditBlock={() => {}}
      />,
    );

    const handle = screen.getAllByRole("button", {
      name: "Drag to reorder this field",
    })[0];
    const rows = screen.getAllByRole("listitem");
    const dataTransfer = createDataTransfer();

    fireEvent.pointerDown(handle);
    fireEvent.dragStart(rows[0], { dataTransfer });
    fireEvent.dragOver(rows[1], { dataTransfer });
    fireEvent.drop(rows[1], { dataTransfer });

    expect(onBlocksReorder).toHaveBeenCalledWith([blocks[1], blocks[0]]);
  });

  it("edits a block when its title is clicked", () => {
    const onEditBlock = vi.fn();
    render(
      <CustomMethodCardWizardBlocksList
        blocks={blocks}
        fieldTypeLabels={fieldTypeLabels}
        dragHandleAriaLabel="Drag to reorder this field"
        listLabel="Fields"
        onBlocksReorder={() => {}}
        onEditBlock={onEditBlock}
      />,
    );

    fireEvent.click(screen.getByRole("button", { name: "Meaning" }));
    expect(onEditBlock).toHaveBeenCalledWith(blocks[0]);
  });

  it("does not reorder when the drag did not start from the handle", () => {
    const onBlocksReorder = vi.fn();
    render(
      <CustomMethodCardWizardBlocksList
        blocks={blocks}
        fieldTypeLabels={fieldTypeLabels}
        dragHandleAriaLabel="Drag to reorder this field"
        listLabel="Fields"
        onBlocksReorder={onBlocksReorder}
        onEditBlock={() => {}}
      />,
    );

    const rows = screen.getAllByRole("listitem");
    const dataTransfer = createDataTransfer();

    fireEvent.dragStart(rows[0], { dataTransfer });
    fireEvent.drop(rows[1], { dataTransfer });

    expect(onBlocksReorder).not.toHaveBeenCalled();
  });
});
