import { describe, expect, it } from "vitest";
import {
  CanvasShell,
  ControlsPanel,
  defineToolcraft,
  fireEvent,
  render,
  renderControlsPanelWithSchema,
  screen,
  StateProbe,
  ToolcraftRoot,
  waitFor,
} from "../testing/controls-panel-test-utils";

describe("ControlsPanel media upload image attachments", () => {
  it("renders single-layer file uploads as a removable preview", () => {
    const schema = defineToolcraft({
      canvas: { enabled: true, upload: true },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                source: {
                  accept: "PNG, SVG",
                  label: "Image",
                  target: "input.source",
                  type: "fileDrop",
                },
              },
              layout: "standalone",
              title: "Input",
            },
          ],
          title: "Generation Controls",
        },
      },
    });

    const { container } = renderControlsPanelWithSchema(schema, undefined, {
      layers: [
        {
          id: "layer-1",
          kind: "layer",
          name: "material",
          visible: true,
        },
      ],
      mediaAssets: [
        {
          dataUrl:
            "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='64' viewBox='0 0 96 64'%3E%3Crect width='96' height='64' fill='%23777'/%3E%3C/svg%3E",
          fileName: "material.svg",
          id: "media-1",
          layerId: "layer-1",
          mimeType: "image/svg+xml",
          position: { x: 0, y: 0 },
          size: { height: 64, unit: "px", width: 96 },
        },
      ],
      selectedLayerId: "layer-1",
    });

    expect(screen.getByRole("img", { name: "material.svg" })).toBeTruthy();
    const transformActions = container.querySelector(
      '[data-slot="actions-control"][aria-label="Image transforms"]',
    );
    const transformActionButtons = transformActions?.querySelector(
      '[data-slot="actions-control-buttons"]',
    );

    expect(transformActions).toBeTruthy();
    expect(transformActions?.parentElement?.style.gap).toBe("6px");
    expect(transformActionButtons?.className).toContain("grid-cols-3");
    expect(transformActionButtons?.getAttribute("data-actions-columns")).toBe("3");
    expect(screen.queryByRole("button", { name: "90° Left" })).toBeNull();

    for (const [name, visibleLabel] of [
      ["90° Right", "90°"],
      ["Flip horizontal", "Flip H"],
      ["Flip vertical", "Flip V"],
    ] as const) {
      const button = screen.getByRole("button", { name });

      expect(button).toBeTruthy();
      expect(button.textContent).toContain(visibleLabel);
    }
    expect(
      screen.queryByText("Click to upload an image"),
    ).toBeNull();
    const initialPreviewFrameStyle = container
      .querySelector('[data-slot="file-upload-preview-frame"]')
      ?.getAttribute("style");

    expect(initialPreviewFrameStyle).toBe(
      "aspect-ratio: 96 / 64; max-height: 196px; width: 100%;",
    );
    expect(screen.getByRole("img", { name: "material.svg" }).getAttribute("style")).toBe(
      "transform: translate(-50%, -50%);",
    );

    fireEvent.click(screen.getByRole("button", { name: "90° Right" }));
    expect(screen.getByTestId("media-transforms").textContent).toBe(
      '[{"rotationDeg":90}]',
    );
    expect(
      container.querySelector('[data-slot="file-upload-preview-frame"]')?.getAttribute("style"),
    ).toBe(initialPreviewFrameStyle);
    expect(screen.getByRole("img", { name: "material.svg" }).getAttribute("style")).toBe(
      "transform: translate(-50%, -50%) rotate(90deg); width: 66.6667%;",
    );

    fireEvent.click(screen.getByRole("button", { name: "Flip horizontal" }));
    expect(screen.getByTestId("media-transforms").textContent).toBe(
      '[{"rotationDeg":90,"flipHorizontal":true}]',
    );
    expect(screen.getByRole("img", { name: "material.svg" }).getAttribute("style")).toBe(
      "transform: translate(-50%, -50%) rotate(90deg) scale(-1, 1); width: 66.6667%;",
    );

    fireEvent.click(screen.getByRole("button", { name: "Flip vertical" }));
    expect(screen.getByTestId("media-transforms").textContent).toBe(
      '[{"rotationDeg":90,"flipHorizontal":true,"flipVertical":true}]',
    );

    fireEvent.click(screen.getByRole("button", { name: "Remove material.svg" }));

    expect(screen.getByTestId("media-count").textContent).toBe("0");
    expect(screen.queryByRole("img", { name: "material.svg" })).toBeNull();
    expect(screen.getByText("Click to upload an image")).toBeTruthy();
  });

  it("renders schema default media as a removable fileDrop attachment", () => {
    const schema = defineToolcraft({
      canvas: { enabled: true, upload: true },
      media: {
        defaultAssets: [
          {
            dataUrl:
              "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='64' viewBox='0 0 96 64'%3E%3Crect width='96' height='64' fill='%23777'/%3E%3C/svg%3E",
            fileName: "default-background.svg",
            id: "default-background",
            layerId: "default-background-layer",
            mimeType: "image/svg+xml",
            size: { height: 64, unit: "px", width: 96 },
            sourceTarget: "input.source",
          },
        ],
      },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                source: {
                  accept: "PNG, SVG",
                  label: "Image",
                  target: "input.source",
                  type: "fileDrop",
                },
              },
              layout: "standalone",
              title: "Input",
            },
          ],
          title: "Generation Controls",
        },
      },
    });

    renderControlsPanelWithSchema(schema);

    expect(screen.getByRole("img", { name: "default-background.svg" })).toBeTruthy();
    expect(screen.getByTestId("media-ids").textContent).toBe("default-background");

    fireEvent.click(
      screen.getByRole("button", { name: "Remove default-background.svg" }),
    );

    expect(screen.getByTestId("media-count").textContent).toBe("0");
    expect(screen.queryByRole("img", { name: "default-background.svg" })).toBeNull();
    expect(screen.getByText("Click to upload an image")).toBeTruthy();

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

    expect(screen.getByRole("img", { name: "default-background.svg" })).toBeTruthy();
    expect(screen.getByTestId("media-count").textContent).toBe("1");

    fireEvent.click(
      screen.getByRole("button", { name: "Remove default-background.svg" }),
    );
    fireEvent.click(screen.getByRole("button", { name: "Reset controls" }));

    expect(screen.getByRole("img", { name: "default-background.svg" })).toBeTruthy();
    expect(screen.getByTestId("media-count").textContent).toBe("1");
  });

  it("keeps the current editable canvas size when uploading an image through fileDrop", async () => {
    const schema = defineToolcraft({
      canvas: {
        enabled: true,
        size: { height: 720, unit: "px", width: 1280 },
        upload: true,
      },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                source: {
                  label: "Image",
                  target: "input.source",
                  type: "fileDrop",
                },
              },
              layout: "standalone",
              title: "Input",
            },
          ],
          title: "Generation Controls",
        },
      },
    });
    const { container } = renderControlsPanelWithSchema(schema);
    const input = container.querySelector<HTMLInputElement>('input[type="file"]');

    expect(input).toBeTruthy();
    expect(screen.getByTestId("canvas-size").textContent).toBe("1280,720");

    fireEvent.change(input as HTMLInputElement, {
      target: {
        files: [new File(["image"], "wide.png", { type: "image/png" })],
      },
    });

    await waitFor(() => {
      expect(screen.getByTestId("media-count").textContent).toBe("1");
    });

    expect(screen.getByTestId("canvas-size").textContent).toBe("1280,720");
    expect(screen.getByTestId("media-sizes").textContent).toBe("1280x720");
  });

  it("removes single-layer file uploads from the canvas and returns the file control to empty", () => {
    const schema = defineToolcraft({
      canvas: { enabled: true, upload: true },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                source: {
                  accept: "PNG, SVG",
                  label: "Image",
                  target: "input.source",
                  type: "fileDrop",
                },
              },
              layout: "standalone",
              title: "Input",
            },
          ],
          title: "Generation Controls",
        },
      },
    });

    render(
      <ToolcraftRoot
        initialState={{
          layers: [
            {
              id: "layer-1",
              kind: "layer",
              name: "material",
              visible: true,
            },
          ],
          mediaAssets: [
            {
              dataUrl:
                "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='64' viewBox='0 0 96 64'%3E%3Crect width='96' height='64' fill='%23777'/%3E%3C/svg%3E",
              fileName: "material.svg",
              id: "media-1",
              layerId: "layer-1",
              mimeType: "image/svg+xml",
              position: { x: 0, y: 0 },
              size: { height: 64, unit: "px", width: 96 },
            },
          ],
          selectedLayerId: "layer-1",
        }}
        schema={schema}
      >
        <div style={{ height: 320, position: "relative", width: 320 }}>
          <CanvasShell />
        </div>
        <ControlsPanel framed={false} />
        <StateProbe />
      </ToolcraftRoot>,
    );

    expect(screen.getByRole("button", { name: "Select material.svg" })).toBeTruthy();
    expect(screen.getAllByRole("img", { name: "material.svg" })).toHaveLength(2);

    fireEvent.click(screen.getByRole("button", { name: "Remove material.svg" }));

    expect(screen.queryByRole("button", { name: "Select material.svg" })).toBeNull();
    expect(screen.queryAllByRole("img", { name: "material.svg" })).toHaveLength(0);
    expect(screen.getByText("Click to upload an image")).toBeTruthy();
    expect(screen.getByTestId("media-count").textContent).toBe("0");
  });

  it("keeps file upload deletion in the layers panel for multi-layer apps", () => {
    const schema = defineToolcraft({
      canvas: { enabled: true, upload: true },
      panels: {
        controls: {
          sections: [
            {
              controls: {
                source: {
                  accept: "PNG, SVG",
                  label: "Image",
                  target: "input.source",
                  type: "fileDrop",
                },
              },
              layout: "standalone",
              title: "Input",
            },
          ],
          title: "Generation Controls",
        },
        layers: true,
      },
    });

    renderControlsPanelWithSchema(schema, undefined, {
      layers: [
        {
          id: "layer-1",
          kind: "layer",
          name: "material",
          visible: true,
        },
      ],
      mediaAssets: [
        {
          dataUrl:
            "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='64' viewBox='0 0 96 64'%3E%3Crect width='96' height='64' fill='%23777'/%3E%3C/svg%3E",
          fileName: "material.svg",
          id: "media-1",
          layerId: "layer-1",
          mimeType: "image/svg+xml",
          position: { x: 0, y: 0 },
          size: { height: 64, unit: "px", width: 96 },
        },
      ],
      selectedLayerId: "layer-1",
    });

    expect(screen.queryByRole("img", { name: "material.svg" })).toBeNull();
    expect(
      screen.queryByRole("button", { name: "Remove material.svg" }),
    ).toBeNull();
    expect(screen.getByText("Click to upload an image")).toBeTruthy();
  });
});
