import { createRef } from "react";
import { render, screen } from "@testing-library/react";
import { chevronLeft } from "@simplybusiness/icons";
import { Icon } from ".";

const CLASS_NAME = "mobius-icon";
const XS_SIZE_CLASS_NAME = "--size-xs";

describe("Test for Icon", () => {
  it("renders an icon", () => {
    const view = render(<Icon icon={chevronLeft} />);
    expect(view).toBeTruthy();
  });

  describe("uses correct class names", () => {
    it("uses Mobius class", () => {
      render(<Icon icon={chevronLeft} data-testid="test" />);
      expect(screen.getByTestId("test")).toHaveClass("mobius");
    });

    it("uses base Mobius class", () => {
      render(<Icon icon={chevronLeft} data-testid="test" />);
      expect(screen.getByTestId("test")).toHaveClass(CLASS_NAME);
    });

    it("includes custom class name", () => {
      render(
        <Icon icon={chevronLeft} data-testid="test" className="my-class" />,
      );
      expect(screen.getByTestId("test")).toHaveClass("my-class");
      expect(screen.getByTestId("test")).toHaveClass(CLASS_NAME);
    });

    it("renders with default size className", () => {
      render(<Icon icon={chevronLeft} data-testid="test" />);
      expect(screen.getByTestId("test")).toHaveClass(XS_SIZE_CLASS_NAME);
    });

    it.each(["xs", "sm", "md", "lg"] as const)(
      "applies --size-%s class",
      size => {
        render(<Icon icon={chevronLeft} size={size} data-testid="test" />);
        expect(screen.getByTestId("test")).toHaveClass(`--size-${size}`);
      },
    );

    it("applies mobius-icon-fw class when fixedWidth is true", () => {
      render(<Icon icon={chevronLeft} fixedWidth data-testid="test" />);
      expect(screen.getByTestId("test")).toHaveClass("mobius-icon-fw");
    });

    it("applies mobius-icon-spin class when spin is true", () => {
      render(<Icon icon={chevronLeft} spin data-testid="test" />);
      expect(screen.getByTestId("test")).toHaveClass("mobius-icon-spin");
    });

    it("applies mobius-icon-spin-reverse class when spinReverse is true", () => {
      render(<Icon icon={chevronLeft} spinReverse data-testid="test" />);
      expect(screen.getByTestId("test")).toHaveClass(
        "mobius-icon-spin-reverse",
      );
      expect(screen.getByTestId("test")).toHaveClass("mobius-icon-spin");
    });
  });

  describe("SVG title attribute", () => {
    it("uses iconName attribute for title as default", () => {
      render(<Icon icon={chevronLeft} />);

      const svgTitleTag = screen.getByTitle("Chevron left icon");

      expect(svgTitleTag).toBeInTheDocument();
    });

    it("uses title prop for title when provided", () => {
      const titleText = "My accessible title";

      render(<Icon icon={chevronLeft} title={titleText} />);

      const svgTitleTag = screen.getByTitle(titleText);

      expect(svgTitleTag).toBeInTheDocument();
    });
  });

  it("forwards ref", () => {
    const ref = createRef<SVGSVGElement>();
    render(<Icon ref={ref} icon={chevronLeft} />);
    expect(ref.current).toBeInstanceOf(SVGSVGElement);
  });
});
