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

describe("ControlsPanel footer actions and settings transfer", () => {
  it("routes footer panel actions through the command bus", () => {
    renderControlsPanel();

    fireEvent.change(screen.getByDisplayValue("Initial prompt"), {
      target: { value: "Draft" },
    });
    fireEvent.blur(screen.getByDisplayValue("Draft"));
    expect(screen.getByTestId("prompt-value").textContent).toBe("Draft");

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

    expect(screen.getByTestId("prompt-value").textContent).toBe("Initial prompt");
  });

  it("routes app-specific footer panel actions through onPanelAction", () => {
    const handledActions: string[] = [];
    const schema = defineToolcraft({
      canvas: { enabled: false },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                footer: {
                  actions: [
                    {
                      icon: "download",
                      label: "Download image",
                      value: "download",
                      variant: "default",
                    },
                  ],
                  target: "panel.actions",
                  type: "panelActions",
                },
              },
              title: "Export",
            },
          ],
          title: "Generation Controls",
        },
      },
    });

    renderControlsPanelWithSchema(schema, {
      onPanelAction: ({ action, state }) => {
        handledActions.push(`${action.value}:${state.schema.panels.controls?.title}`);
      },
    });

    fireEvent.click(screen.getByRole("button", { name: "Download image" }));

    expect(handledActions).toEqual(["download:Generation Controls"]);
  });

  it("keeps runtime export mechanics out of generic product action context", () => {
    const schema = defineToolcraft({
      canvas: { enabled: true },
      panels: {
        controls: {
          sections: [
            {
              actionGroup: "secondary",
              controls: {
                footer: {
                  actions: [
                    {
                      label: "Export PNG",
                      value: "export-png",
                      variant: "default",
                    },
                  ],
                  target: "panel.actions",
                  type: "panelActions",
                },
              },
            },
          ],
          title: "Controls",
        },
      },
    });
    let actionContextKeys: string[] = [];

    renderControlsPanelWithSchema(schema, {
      onPanelAction: (context) => {
        actionContextKeys = Object.keys(context).sort();
      },
    });

    fireEvent.click(screen.getByRole("button", { name: "Export PNG" }));

    expect(actionContextKeys).not.toContain("renderModelsToCanvas");
    expect(actionContextKeys).not.toContain("renderRuntimeSceneToCanvas");
    expect(actionContextKeys).not.toContain("resolveSceneExportFrame");
  });

  it("renders runtime settings transfer as a headerless body section instead of sticky footer actions", () => {
    const schema = defineToolcraft({
      canvas: { enabled: true, size: { height: 720, unit: "px", width: 1280 } },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                prompt: {
                  defaultValue: "Initial prompt",
                  label: "Prompt",
                  target: "generation.prompt",
                  type: "text",
                },
              },
              title: "Prompt",
            },
            {
              actionGroup: "secondary",
              controls: {
                footer: {
                  actions: [
                    {
                      label: "Export PNG",
                      value: "export.png",
                      variant: "default",
                    },
                  ],
                  target: "panel.actions",
                  type: "panelActions",
                },
              },
            },
          ],
          title: "Generation Controls",
        },
      },
      settingsTransfer: true,
    });
    const { container } = renderControlsPanelWithSchema(schema);
    const scrollContent = container.querySelector(
      '[data-slot="toolcraft-panel-content"]',
    );
    const stickyFooter = container.querySelector(
      '[data-slot="toolcraft-panel-sticky-actions"]',
    );
    const firstSection = container.querySelector("section");
    const firstInlineGroup = firstSection?.querySelector(
      '[data-control-layout="inline"][data-control-layout-columns="2"]',
    );

    const transferButtons = screen
      .getAllByRole("button", { name: /Settings$/ })
      .map((button) => button.textContent);

    expect(transferButtons).toEqual(["Export Settings", "Import Settings"]);
    expect(schema.panels.controls?.sections[0]?.title).toBe("Setup");
    expect(
      [...container.querySelectorAll('[data-slot="panel-title"]')].map(
        (title) => title.textContent,
      ),
    ).not.toContain("Setup");
    expect(firstSection?.querySelector('[data-slot="panel-title"]')).toBeNull();
    expect(firstSection?.querySelector("[data-control-section-collapse-button]")).toBeNull();
    expect(firstSection?.querySelector('[data-slot="control-section-header"]')).toBeNull();
    expect(firstSection?.querySelector('[data-slot="panel-section-collapsible-body"]')).toBeNull();
    expect(firstSection?.getAttribute("data-collapsed")).toBeNull();
    expect(firstSection?.className).toContain("py-0");
    expect(firstSection?.className).toContain(
      "[&>[data-control-list]]:pt-3",
    );
    expect(firstSection?.querySelector("[data-control-list]")?.className).toContain("pt-2");
    expect(firstSection?.querySelector("[data-control-list]")?.className).toContain("pb-6");
    expect(firstInlineGroup?.textContent).toContain("Canvas width");
    expect(firstInlineGroup?.textContent).toContain("Canvas height");
    expect(firstSection?.textContent).toContain("Aspect ratio");
    expect(firstSection?.textContent).toContain("Canvas width");
    expect(firstSection?.textContent).toContain("Canvas height");
    expect(firstSection?.textContent).toContain("Export Settings");
    expect(firstSection?.textContent).toContain("Import Settings");
    expect((firstSection?.textContent ?? "").indexOf("Export Settings")).toBeLessThan(
      (firstSection?.textContent ?? "").indexOf("Import Settings"),
    );
    expect((firstSection?.textContent ?? "").indexOf("Import Settings")).toBeLessThan(
      (firstSection?.textContent ?? "").indexOf("Aspect ratio"),
    );
    expect((firstSection?.textContent ?? "").indexOf("Aspect ratio")).toBeLessThan(
      (firstSection?.textContent ?? "").indexOf("Canvas width"),
    );
    expect(scrollContent?.textContent).toContain("Import Settings");
    expect(scrollContent?.textContent).toContain("Export Settings");
    expect(stickyFooter?.textContent).toContain("Export PNG");
    expect(stickyFooter?.textContent).not.toContain("Import Settings");
  });

  it("keeps panelActions in the sticky footer even when the schema omits actionGroup", () => {
    const schema = defineToolcraft({
      canvas: { enabled: false },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                footer: {
                  actions: [
                    {
                      command: "controls.reset",
                      label: "Reset",
                      value: "reset",
                      variant: "outline",
                    },
                    {
                      command: "controls.apply",
                      label: "Apply",
                      value: "apply",
                      variant: "default",
                    },
                  ],
                  target: "panel.actions",
                  type: "panelActions",
                },
                prompt: {
                  defaultValue: "Initial prompt",
                  label: "Prompt",
                  target: "generation.prompt",
                  type: "text",
                },
              },
              title: "Export",
            },
          ],
          title: "Generation Controls",
        },
      },
    });
    const { container } = renderControlsPanelWithSchema(schema);
    const stickyFooter = container.querySelector(
      '[data-slot="toolcraft-panel-sticky-actions"]',
    );
    const scrollContent = container.querySelector(
      '[data-slot="toolcraft-panel-content"]',
    );

    expect(stickyFooter?.textContent).toContain("Reset");
    expect(stickyFooter?.textContent).toContain("Apply");
    expect(stickyFooter?.className).toContain("before:h-px");
    expect(stickyFooter?.className).toContain("var(--accent)");
    expect(stickyFooter?.className).toContain(
      "before:scale-x-[var(--sticky-footer-progress,1)]",
    );
    expect(stickyFooter?.className).toContain("before:opacity-0");
    expect(stickyFooter?.className).toContain("before:transition-[opacity,transform]");
    expect(stickyFooter?.className).toContain(
      "data-[sticky-footer-active=true]:before:opacity-100",
    );
    expect(stickyFooter?.getAttribute("data-sticky-footer-active")).toBeNull();
    expect(stickyFooter?.querySelector('[data-toolcraft-section-actions]')).toBeTruthy();
    expect(stickyFooter?.querySelector('[data-slot="panel-title"]')).toBeNull();
    expect(stickyFooter?.querySelector("[data-control-section-collapse-button]")).toBeNull();
    expect(stickyFooter?.textContent).not.toContain("Export");
    expect(scrollContent?.textContent).toContain("Prompt");
    expect(scrollContent?.textContent).not.toContain("ResetApply");
  });

  it("shows the sticky footer export indicator only while an async panel action is pending", async () => {
    const schema = defineToolcraft({
      canvas: { enabled: false },
      panels: {
        controls: {
          sections: [
            {
              actionGroup: "secondary",
              controls: {
                footer: {
                  actions: [
                    {
                      icon: "download-simple",
                      label: "Export PNG",
                      value: "export-png",
                      variant: "default",
                    },
                  ],
                  target: "panel.actions",
                  type: "panelActions",
                },
              },
            },
          ],
          title: "Generation Controls",
        },
      },
    });
    let resolveAction: (() => void) | undefined;
    const pendingAction = new Promise<void>((resolve) => {
      resolveAction = resolve;
    });
    let reportActionProgress: ((progress: number) => void) | undefined;
    const onPanelAction = vi.fn(({ reportProgress }) => {
      reportActionProgress = reportProgress;

      return pendingAction;
    });
    const { container } = renderControlsPanelWithSchema(schema, { onPanelAction });
    const stickyFooter = container.querySelector(
      '[data-slot="toolcraft-panel-sticky-actions"]',
    );
    const exportPngButton = screen.getByRole("button", { name: "Export PNG" });

    expect(stickyFooter?.getAttribute("data-sticky-footer-active")).toBeNull();
    expect(exportPngButton.querySelector('[data-icon-name="upload-simple"]')).toBeTruthy();

    fireEvent.click(exportPngButton);

    expect(onPanelAction).toHaveBeenCalledTimes(1);
    await waitFor(() => {
      expect(stickyFooter?.getAttribute("data-sticky-footer-active")).toBe("true");
    });
    expect(stickyFooter?.getAttribute("data-sticky-footer-progress")).toBeNull();

    act(() => {
      reportActionProgress?.(0.25);
    });

    await waitFor(() => {
      expect(stickyFooter?.getAttribute("data-sticky-footer-progress")).toBe("0.25");
      expect(
        (stickyFooter as HTMLElement | null)?.style.getPropertyValue(
          "--sticky-footer-progress",
        ),
      ).toBe("0.25");
    });

    act(() => {
      reportActionProgress?.(2);
    });

    await waitFor(() => {
      expect(stickyFooter?.getAttribute("data-sticky-footer-progress")).toBe("1");
    });

    await act(async () => {
      resolveAction?.();
      await pendingAction;
    });

    await waitFor(() => {
      expect(stickyFooter?.getAttribute("data-sticky-footer-active")).toBeNull();
    });
  });

  it("renders secondary footer actions as secondary buttons", () => {
    const schema = defineToolcraft({
      canvas: { enabled: false },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                footer: {
                  actions: [
                    {
                      label: "Copy PNG",
                      value: "copy",
                      variant: "secondary",
                    },
                    {
                      label: "Export PNG",
                      value: "export",
                      variant: "default",
                    },
                  ],
                  target: "panel.actions",
                  type: "panelActions",
                },
              },
            },
          ],
          title: "Generation Controls",
        },
      },
    });

    renderControlsPanelWithSchema(schema);

    expect(screen.getByRole("button", { name: "Copy PNG" }).getAttribute("data-variant")).toBe(
      "secondary",
    );
    expect(screen.getByRole("button", { name: "Export PNG" }).getAttribute("data-variant")).toBe(
      "default",
    );
  });

  it("spans the final odd footer action across the full action row", () => {
    const schema = defineToolcraft({
      canvas: { enabled: false },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                footer: {
                  actions: [
                    {
                      label: "Copy PNG",
                      value: "copy",
                      variant: "secondary",
                    },
                    {
                      label: "Export OG",
                      value: "export-og",
                      variant: "secondary",
                    },
                    {
                      label: "Export PNG",
                      value: "export",
                      variant: "default",
                    },
                  ],
                  target: "panel.actions",
                  type: "panelActions",
                },
              },
            },
          ],
          title: "Generation Controls",
        },
      },
    });

    renderControlsPanelWithSchema(schema);

    const exportPngButton = screen.getByRole("button", { name: "Export PNG" });

    expect(exportPngButton.className).toContain("col-span-2");
  });
});
