import { describe, expect, it } from "vitest";
import {
  cleanup,
  createSchema,
  FileDrop,
  fireEvent,
  Panel,
  render,
  renderControlsPanelWithSchema,
  screen,
  waitFor,
} from "../testing/controls-panel-test-utils";

describe("ControlsPanel collapsible section shell", () => {
  it("exposes stable schema target ownership without changing control layout", () => {
    const { container } = renderControlsPanelWithSchema(createSchema());
    const opacityBoundary = container.querySelector(
      '[data-toolcraft-control-target="selectedLayer.opacity"]',
    );
    const colorGroupBoundary = container.querySelector(
      '[data-toolcraft-control-targets]',
    );

    expect(opacityBoundary?.className).toContain("contents");
    expect(opacityBoundary?.querySelector('[data-slot="field"]')).toBeTruthy();
    expect(
      JSON.parse(colorGroupBoundary?.getAttribute("data-toolcraft-control-targets") ?? "[]"),
    ).toEqual(["style.fill", "style.stroke"]);
    expect(colorGroupBoundary?.querySelectorAll('[data-slot="field"]')).toHaveLength(2);
  });

  it("renders titled body sections as 36px collapsible header rows", () => {
    const schema = createSchema();
    const { container } = renderControlsPanelWithSchema(schema);
    const basicTitle = screen.getByText("Basic");
    const header = basicTitle.closest('[data-slot="control-section-header"]');
    const section = basicTitle.closest("section");
    const controlList = section?.querySelector("[data-control-list]");
    const body = section?.querySelector('[data-slot="panel-section-collapsible-body"]');

    expect(header?.className).toContain("h-9");
    expect(header?.getAttribute("data-collapsible")).toBe("");
    expect(header?.getAttribute("aria-expanded")).toBe("true");
    expect(header?.getAttribute("role")).toBe("button");
    expect(body?.className).toContain("transition-[grid-template-rows,opacity]");
    expect(body?.className).toContain("grid-rows-[1fr]");
    expect(controlList?.className).toContain("pt-2");
    expect(controlList?.className).toContain("pb-6");
    expect(section?.textContent).toContain("Prompt");
    expect(section?.textContent).toContain("Opacity");

    fireEvent.click(header!);

    expect(section?.getAttribute("data-collapsed")).toBe("true");
    expect(header?.getAttribute("aria-expanded")).toBe("false");
    expect(body?.getAttribute("aria-hidden")).toBe("true");
    expect(body?.className).toContain("grid-rows-[0fr]");
    expect(section?.textContent).toContain("Basic");
    expect(section?.textContent).toContain("Prompt");

    fireEvent.transitionEnd(body!);

    expect(section?.textContent).not.toContain("Prompt");
    expect(section?.textContent).not.toContain("Opacity");

    fireEvent.keyDown(header!, { key: "Enter" });

    expect(section?.getAttribute("data-collapsed")).toBe("false");
    expect(header?.getAttribute("aria-expanded")).toBe("true");
    expect(section?.querySelector('[data-slot="panel-section-collapsible-body"]')).toBeTruthy();
    expect(container.querySelector('[data-slot="control-section-header"]')).toBeTruthy();
  });

  it("suppresses child control transitions when a section re-expands", () => {
    const schema = createSchema();
    renderControlsPanelWithSchema(schema);
    const basicTitle = screen.getByText("Basic");
    const header = basicTitle.closest<HTMLElement>('[data-slot="control-section-header"]');
    const section = basicTitle.closest("section");
    const initialBody = section?.querySelector<HTMLElement>(
      '[data-slot="panel-section-collapsible-body"]',
    );

    fireEvent.click(header!);
    fireEvent.transitionEnd(initialBody!);
    fireEvent.click(header!);

    const expandedBody = section?.querySelector<HTMLElement>(
      '[data-slot="panel-section-collapsible-body"]',
    );
    const innerControls = expandedBody?.firstElementChild as HTMLElement | null;

    expect(expandedBody?.className).toContain("transition-[grid-template-rows,opacity]");
    expect(expandedBody?.className).toContain("grid-rows-[1fr]");
    expect(innerControls?.getAttribute("data-toolcraft-controls-mounting")).toBe("true");
  });

  it("persists ordinary section collapse state as a UI preference across remounts", async () => {
    const schema = createSchema();
    const { unmount } = renderControlsPanelWithSchema(schema);
    const basicHeader = screen
      .getByText("Basic")
      .closest<HTMLElement>('[data-slot="control-section-header"]');

    fireEvent.click(basicHeader!);

    expect(basicHeader?.closest("section")?.getAttribute("data-collapsed")).toBe("true");

    if (schema.persistence.storage !== "localStorage") {
      throw new Error("Expected default local persistence");
    }

    const persistenceKey = schema.persistence.key;

    const basicSectionId = schema.panels.controls?.sections.find(
      (section) => section.title === "Basic",
    )?.id;

    await waitFor(() => {
      const persisted = JSON.parse(
        window.localStorage.getItem(persistenceKey) ?? "{}",
      );

      expect(persisted.state.panels.controls.collapsedSections).toEqual({
        [basicSectionId!]: true,
      });
    });

    unmount();
    cleanup();

    renderControlsPanelWithSchema(schema);

    const restoredSection = screen.getByText("Basic").closest("section");

    expect(restoredSection?.getAttribute("data-collapsed")).toBe("true");

    fireEvent.click(screen.getByRole("button", { name: "Reset controls" }));

    expect(screen.getByText("Basic").closest("section")?.getAttribute("data-collapsed")).toBe(
      "true",
    );

  });

  it("puts ordinary implicit panel section spacing on the control list layer", () => {
    const { container } = render(
      <Panel title="Master Controls">
        <FileDrop accept="PNG, JPEG" />
      </Panel>,
    );
    const section = container.querySelector("section");
    const controlList = section?.querySelector("[data-control-list]");

    expect(section?.className).toContain("py-0");
    expect(controlList?.className).toContain("pt-2");
    expect(controlList?.className).toContain("pb-6");
    expect(controlList?.textContent).toContain("Click to upload an image");
  });
});
