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

describe("ControlsPanel slider rendering and layout", () => {
  it("renders schema discrete sliders with Toolcraft variant and markers", () => {
    const schema = defineToolcraft({
      canvas: { enabled: true },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                grain: {
                  defaultValue: 3,
                  label: "Grain",
                  max: 5,
                  min: 0,
                  step: 1,
                  target: "shader.grain",
                  type: "slider",
                  variant: "discrete",
                },
              },
              title: "Texture",
            },
          ],
          title: "Generation Controls",
        },
      },
    });

    const { container } = renderControlsPanelWithSchema(schema);
    const slider = container.querySelector<HTMLElement>(
      '[data-slot="slider"][data-variant="discrete"]',
    );
    const markers = Array.from(
      container.querySelectorAll<HTMLElement>('[data-slot="slider-marker"]'),
    );

    expect(slider).toBeTruthy();
    expect(markers).toHaveLength(4);

    for (const marker of markers) {
      expect(marker.className).toContain("group-hover/slider-control:opacity-100");
      expect(marker.className.split(/\s+/)).not.toContain("opacity-100");
    }

    fireEvent.pointerDown(slider as HTMLElement, { button: 0 });

    for (const marker of markers) {
      expect(marker.className.split(/\s+/)).toContain("opacity-100");
    }
  });

  it("renders one discrete slider marker for each fractional step", () => {
    const schema = defineToolcraft({
      canvas: { enabled: true },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                duration: {
                  defaultValue: 0.3,
                  label: "Duration",
                  markerCount: 3,
                  max: 0.5,
                  min: 0,
                  step: 0.1,
                  target: "animation.duration",
                  type: "slider",
                  variant: "discrete",
                },
              },
              title: "Timing",
            },
          ],
          title: "Generation Controls",
        },
      },
    });

    const { container } = renderControlsPanelWithSchema(schema);
    const slider = container.querySelector<HTMLElement>(
      '[data-slot="slider"][data-variant="discrete"]',
    );
    const markers = Array.from(
      container.querySelectorAll<HTMLElement>('[data-slot="slider-marker"]'),
    );

    expect(slider).toBeTruthy();
    expect(markers).toHaveLength(4);
  });

  it("keeps stepped continuous sliders free of discrete markers", () => {
    const schema = defineToolcraft({
      canvas: { enabled: true },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                speed: {
                  defaultValue: 118,
                  label: "Reveal speed",
                  max: 150,
                  min: 0,
                  step: 1,
                  target: "animation.speed",
                  type: "slider",
                  unit: " cols/s",
                },
              },
              title: "Reveal",
            },
          ],
          title: "Generation Controls",
        },
      },
    });

    const { container } = renderControlsPanelWithSchema(schema);

    expect(
      container.querySelector('[data-slot="slider"][data-variant="discrete"]'),
    ).toBeNull();
    expect(container.querySelectorAll('[data-slot="slider-marker"]')).toHaveLength(0);
    expect(container.textContent).toContain("118 cols/s");
  });

  it("keeps textual slider value labels non-editable", () => {
    const schema = defineToolcraft({
      canvas: { enabled: true },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                letterSpacing: {
                  defaultValue: 2,
                  label: "Letter spacing",
                  max: 4,
                  min: 0,
                  step: 1,
                  target: "text.letterSpacing",
                  type: "slider",
                  valueLabel: "Normal",
                },
              },
              title: "Text",
            },
          ],
          title: "Generation Controls",
        },
      },
    });

    renderControlsPanelWithSchema(schema);

    const valueLabel = screen
      .getAllByText("Normal")
      .find((node) => node.getAttribute("aria-hidden") !== "true");

    expect(screen.queryByRole("button", { name: "Edit Letter spacing value" })).toBeNull();
    expect(valueLabel).toBeTruthy();
    expect(valueLabel?.className).toContain("cursor-default");
    expect(valueLabel?.className).not.toContain("cursor-text");
  });

  it("keeps schema sliders stacked even when a layout group asks for an inline row", () => {
    const schema = defineToolcraft({
      canvas: { enabled: true },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                fps: {
                  defaultValue: 17,
                  label: "FPS",
                  max: 30,
                  min: 1,
                  step: 1,
                  target: "animation.fps",
                  type: "slider",
                  unit: "fps",
                  variant: "discrete",
                },
                speed: {
                  defaultValue: 3.7,
                  label: "Speed",
                  max: 4,
                  min: 0.1,
                  step: 0.1,
                  target: "animation.speed",
                  type: "slider",
                },
              },
              layoutGroups: [
                {
                  columns: 2,
                  controls: ["fps", "speed"],
                  layout: "inline",
                },
              ],
              title: "Pattern Animation",
            },
          ],
          title: "Generation Controls",
        },
      },
    });

    const { container } = renderControlsPanelWithSchema(schema);
    const fpsSlider = container.querySelector<HTMLElement>(
      '[data-slot="slider"][data-variant="discrete"]',
    );

    expect(container.querySelector('[data-control-layout="inline"]')).toBeNull();
    expect(fpsSlider).toBeTruthy();
    expect(container.querySelectorAll('[data-slot="slider-marker"]').length).toBeGreaterThan(0);
    expect(container.textContent).toContain("17 fps");
    expect(container.textContent).toContain("3.7");
  });

  it("passes schema disabled state into slider controls", () => {
    const schema = defineToolcraft({
      canvas: { enabled: true },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                opacity: {
                  defaultValue: 70,
                  disabled: true,
                  label: "Opacity",
                  max: 100,
                  min: 0,
                  step: 1,
                  target: "shader.opacity",
                  type: "slider",
                },
              },
              title: "Output",
            },
          ],
          title: "Generation Controls",
        },
      },
    });

    const { container } = renderControlsPanelWithSchema(schema);
    const field = screen.getByText("Opacity").closest('[data-slot="field"]');
    const slider = container.querySelector<HTMLElement>('[data-slot="slider"]');

    expect(field?.getAttribute("data-disabled")).toBe("true");
    expect(slider).toBeTruthy();
    expect(slider?.hasAttribute("data-disabled")).toBe(true);
  });

  it("does not place any schema slider in inline layout rows", () => {
    const schema = defineToolcraft({
      canvas: { enabled: true },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                range: {
                  defaultValue: [20, 80],
                  label: "Range",
                  max: 100,
                  min: 0,
                  step: 1,
                  target: "shape.range",
                  type: "rangeSlider",
                  unit: "%",
                },
                strength: {
                  defaultValue: 50,
                  label: "Strength",
                  max: 100,
                  min: 0,
                  step: 1,
                  target: "shape.strength",
                  type: "slider",
                  unit: "%",
                },
              },
              layoutGroups: [
                {
                  columns: 2,
                  controls: ["range", "strength"],
                  layout: "inline",
                },
              ],
              title: "Shape",
            },
          ],
          title: "Controls",
        },
      },
    });

    const { container } = renderControlsPanelWithSchema(schema);

    expect(container.querySelector('[data-control-layout="inline"]')).toBeNull();
    expect(screen.getByText("Range")).toBeTruthy();
    expect(screen.getByText("Strength")).toBeTruthy();
  });
});
