import { render, screen, within } from "@testing-library/react";

import {
  MapPanelSkeleton,
  MapTimelineSkeleton,
} from "./MapComponentSkeletons";
import {
  MAP_SKELETON_CONFIGS,
  MAP_SKELETON_VARIANTS,
  type MapSkeletonVariant,
} from "./mapComponentSkeletonConfig";

describe("map component skeletons", () => {
  it("keeps the loading state inside the analysis panel geometry", () => {
    render(<MapPanelSkeleton variant="burst-simulation" />);

    const panel = screen.getByRole("status", {
      name: "正在加载爆管分析",
    });

    expect(panel).toHaveAttribute("data-component-skeleton", "map-panel");
    expect(panel).toHaveAttribute("data-panel-side", "right");
    expect(panel).toHaveAttribute("data-panel-width", "520");
    expect(panel).toHaveStyle({
      position: "absolute",
      pointerEvents: "none",
    });
    expect(screen.getByTestId("burst-simulation-content")).toBeInTheDocument();
  });

  it("keeps an explicit panel configuration for every heavy map component", () => {
    expect(Object.keys(MAP_SKELETON_CONFIGS).sort()).toEqual(
      [...MAP_SKELETON_VARIANTS].sort(),
    );
  });

  it("keeps known panel chrome out of the skeleton layer", () => {
    render(<MapPanelSkeleton variant="burst-simulation" />);

    const header = screen.getByTestId("map-panel-header");
    const tabs = screen.getByTestId("map-panel-tabs");

    expect(header.querySelector(".MuiSkeleton-root")).not.toBeInTheDocument();
    expect(tabs.querySelector(".MuiSkeleton-root")).not.toBeInTheDocument();
    expect(screen.queryByText("正在加载组件")).not.toBeInTheDocument();
    expect(
      within(tabs).getByText("分析要件"),
    ).toBeInTheDocument();
  });

  it.each(MAP_SKELETON_VARIANTS)(
    "renders the component-specific panel for %s",
    (variant: MapSkeletonVariant) => {
      const config = MAP_SKELETON_CONFIGS[variant];

      render(<MapPanelSkeleton variant={variant} />);

      const panel = screen.getByRole("status", {
        name: `正在加载${config.title}`,
      });
      expect(panel).toHaveAttribute("data-component-skeleton", "map-panel");
      expect(panel).toHaveAttribute("data-panel-side", config.side);
      expect(panel).toHaveAttribute(
        "data-panel-width",
        String(config.panelWidth),
      );
      expect(screen.getByText(config.panelTitle)).toBeInTheDocument();
      expect(screen.queryAllByTestId("map-panel-tab-label")).toHaveLength(
        config.tabLabels.length,
      );
    },
  );

  it("distinguishes cleaning controls from the simulation device list", () => {
    const { rerender } = render(
      <MapPanelSkeleton variant="network-simulation" />,
    );

    expect(screen.getByTestId("network-device-content")).toBeInTheDocument();

    rerender(<MapPanelSkeleton variant="scada-data-cleaning" />);

    expect(screen.getByTestId("cleaning-device-content")).toBeInTheDocument();
    expect(screen.getByTestId("cleaning-action-skeleton")).toBeInTheDocument();
  });

  it("matches the DMA parameter panel's vertical control distribution", () => {
    render(<MapPanelSkeleton variant="dma-leak-detection" />);

    const fields = screen.getByTestId("dma-primary-fields");

    expect(screen.getByTestId("dma-notice-skeleton")).toBeInTheDocument();
    expect(fields).toHaveAttribute("data-layout", "vertical");
    expect(fields.children).toHaveLength(5);
    expect(screen.getByTestId("dma-advanced-skeleton")).toBeInTheDocument();
    expect(screen.getByTestId("dma-primary-action-skeleton")).toHaveStyle({
      width: "100%",
    });
  });

  it.each([
    ["burst-detection", "burst-detection-primary-fields", "vertical", 3],
    ["burst-location", "burst-location-primary-fields", "vertical", 2],
    ["burst-simulation", "burst-simulation-primary-fields", "vertical", 3],
    [
      "contaminant-simulation",
      "contaminant-simulation-primary-fields",
      "vertical",
      4,
    ],
    [
      "flushing-analysis",
      "flushing-primary-fields",
      "vertical-vertical-two-columns",
      3,
    ],
    [
      "monitoring-place-optimization",
      "monitoring-primary-fields",
      "vertical",
      5,
    ],
  ] as const)(
    "matches the primary control distribution for %s",
    (variant, testId, layout, childCount) => {
      render(<MapPanelSkeleton variant={variant} />);

      const fields = screen.getByTestId(testId);

      expect(fields).toHaveAttribute("data-layout", layout);
      expect(fields.children).toHaveLength(childCount);
    },
  );

  it("keeps the two flushing selection regions separate", () => {
    render(<MapPanelSkeleton variant="flushing-analysis" />);

    expect(screen.getByTestId("flushing-valve-selection")).toBeInTheDocument();
    expect(screen.getByTestId("flushing-node-selection")).toBeInTheDocument();
  });

  it("renders the timeline as an independent loading boundary", () => {
    render(<MapTimelineSkeleton />);

    expect(
      screen.getByRole("status", { name: "正在加载时间轴" }),
    ).toHaveAttribute("data-component-skeleton", "map-timeline");
  });
});
