import { cleanup, render, screen } from "@testing-library/react";
import assert from "node:assert";
import { afterEach, describe, test } from "node:test";
import { ContentPlaceholder } from "./index";

describe("ContentPlaceholder", () => {

  afterEach(() => {
    cleanup();
  });

  test("renders with default props", () => {
    render(<ContentPlaceholder />);

    const container = screen.getByRole("progressbar");
    assert.notStrictEqual(container, null);
    assert.ok(container.classList.contains("contentPlaceholder"));
  });

  test("renders correct number of lines", () => {
    const { container } = render(<ContentPlaceholder lines={5} />);

    const rects = container.querySelectorAll(".contentPlaceholder__line");
    assert.strictEqual(rects.length, 5);
  });

  test("passes extra HTML attributes", () => {
    render(
      <ContentPlaceholder
        extraAttrs={{
          "data-testid": "placeholder",
          "aria-label": "Loading content",
          id: "loader-1",
        }}
      />
    );

    const container = screen.getByTestId("placeholder");
    assert.strictEqual(container.getAttribute("aria-label"), "Loading content");
    assert.strictEqual(container.getAttribute("id"), "loader-1");
  });

  test("handles single value for line properties", () => {
    const { container } = render(
      <ContentPlaceholder
        lines={3}
        linesWidth={400}
        linesHeight={30}
        linesBorderRadius={4}
        linesMargin={10}
      />
    );

    const rects = container.querySelectorAll(".contentPlaceholder__line");

    rects.forEach((rect) => {
      assert.strictEqual(rect.getAttribute("width"), "400");
      assert.strictEqual(rect.getAttribute("height"), "30");
      assert.strictEqual(rect.getAttribute("rx"), "4");
      assert.strictEqual(rect.getAttribute("ry"), "4");
    });
  });

  test("renders custom children instead of lines", () => {
    render(
      <ContentPlaceholder>
        <circle cx={"50"} cy={"50"} r={"40"} data-testid={"custom-circle"} />
        <rect x={"100"} y={"100"} width={"200"} height={"50"} data-testid={"custom-rect"} />
      </ContentPlaceholder>
    );

    assert.notStrictEqual(screen.queryByTestId("custom-circle"), null);
    assert.notStrictEqual(screen.queryByTestId("custom-rect"), null);

    const standardRects = screen.queryAllByTestId((_, element) =>
      element?.getAttribute("data-testid")?.startsWith("line-") ?? false
    );
    assert.strictEqual(standardRects.length, 0);
  });

  test("calculates correct Y position for each line", () => {
    const { container } = render(
      <ContentPlaceholder lines={4} linesHeight={20} linesMargin={10} />
    );

    const rects = container.querySelectorAll(".contentPlaceholder__line");

    // Expected y positions: 0, 30, 60, 90
    const expectedY = [ 0, 30, 60, 90 ];
    rects.forEach((rect, index) => {
      assert.strictEqual(rect.getAttribute("y"), String(expectedY[index]));
    });
  });

  test("calculates cumulative Y position for variable line heights and margins", () => {
    const { container } = render(
      <ContentPlaceholder
        lines={3}
        linesHeight={[ 10, 20, 30 ]}
        linesMargin={[ 5, 10, 15 ]}
      />
    );

    const rects = container.querySelectorAll(".contentPlaceholder__line");
    const expectedY = [ 0, 15, 45 ];

    rects.forEach((rect, index) => {
      assert.strictEqual(rect.getAttribute("y"), String(expectedY[index]));
    });
  });

  test("handles zero lines", () => {
    const { container } = render(<ContentPlaceholder lines={0} />);

    const rects = container.querySelectorAll(".contentPlaceholder__line");
    assert.strictEqual(rects.length, 0);
  });
});
