import { describe, expect, it } from "vitest";
import {
  defineToolcraft,
  fireEvent,
  renderControlsPanelWithSchema,
  screen
} from "../testing/controls-panel-test-utils";

describe("ControlsPanel gradient control", () => {
  it.each([
    ["linear", "Linear"],
    ["radial", "Radial"],
    ["angular", "Angular"],
    ["diamond", "Diamond"],
  ] as const)("preserves %s gradient type in the gradient select", (gradientType, label) => {
    const schema = defineToolcraft({
      canvas: { enabled: true },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                gradient: {
                  defaultValue: {
                    angle: 138,
                    gradientType,
                    stops: [
                      { color: "#111111", position: "0%" },
                      { color: "#14B8FF", position: "45%" },
                      { color: "#F472B6", position: "76%" },
                    ],
                  },
                  label: "Gradient",
                  target: "style.gradient",
                  type: "gradient",
                },
              },
              title: "Gradient",
            },
          ],
          title: "Generation Controls",
        },
      },
    });

    const { container } = renderControlsPanelWithSchema(schema);
    const gradientSelect = container.querySelector('[data-slot="select-trigger"]');

    expect(gradientSelect?.textContent).toContain(label);
  });

  it("commits gradient stop position inputs on blur or Enter with a separated percent suffix", () => {
    const schema = defineToolcraft({
      canvas: { enabled: true },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                gradient: {
                  defaultValue: {
                    angle: 90,
                    gradientType: "linear",
                    stops: [
                      { color: "#111111", position: "0%" },
                      { color: "#FFFFFF", position: "100%" },
                    ],
                  },
                  label: "Gradient",
                  target: "style.gradient",
                  type: "gradient",
                },
              },
              title: "Gradient",
            },
          ],
          title: "Generation Controls",
        },
      },
    });

    renderControlsPanelWithSchema(schema);

    const firstPositionInput = screen.getByLabelText(
      "Stop 1 position",
    ) as HTMLInputElement;
    const secondPositionInput = screen.getByLabelText(
      "Stop 2 position",
    ) as HTMLInputElement;
    const firstPositionGroup = firstPositionInput.closest('[data-slot="input-group"]');
    const firstOpacityInput = screen.getByLabelText("Stop 1 opacity");
    const stopsList = firstPositionInput.closest('[data-slot="gradient-stops-list"]');
    const gradientControlItem = stopsList?.closest(
      "[data-control-item-compound-context]",
    );
    const firstStopGrid = firstPositionInput.closest('[data-slot="field"]')
      ?.querySelector('[data-slot="gradient-stop-row-grid"]');

    expect(firstPositionInput.value).toBe("0");
    expect(firstPositionGroup?.textContent).toContain("%");
    expect(stopsList?.className).not.toContain("border-y");
    expect(gradientControlItem).toBeNull();
    expect(firstPositionInput.className.split(/\s+/)).toContain("pl-[5px]");
    expect(firstOpacityInput.className.split(/\s+/)).toContain("pl-[5px]");
    expect(firstStopGrid?.className).toContain("grid-cols-[3.5rem_minmax(0,1fr)_1.5rem]");

    fireEvent.change(firstPositionInput, { target: { value: "25" } });
    expect(JSON.parse(screen.getByTestId("gradient-value").textContent ?? "{}")).toMatchObject({
      stops: [
        { position: "0%" },
        { position: "100%" },
      ],
    });

    fireEvent.blur(firstPositionInput);
    expect(JSON.parse(screen.getByTestId("gradient-value").textContent ?? "{}")).toMatchObject({
      stops: [
        { position: "25%" },
        { position: "100%" },
      ],
    });

    fireEvent.change(secondPositionInput, { target: { value: "75" } });
    expect(JSON.parse(screen.getByTestId("gradient-value").textContent ?? "{}")).toMatchObject({
      stops: [
        { position: "25%" },
        { position: "100%" },
      ],
    });

    fireEvent.keyDown(secondPositionInput, { code: "Enter", key: "Enter" });
    expect(JSON.parse(screen.getByTestId("gradient-value").textContent ?? "{}")).toMatchObject({
      stops: [
        { position: "25%" },
        { position: "75%" },
      ],
    });
  });
});
