import React from "react";
import { List } from "./index";
import { ListItem } from "./list-item";

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

import "@testing-library/jest-dom";

describe("List", () => {
  describe("Rendering", () => {
    it("renders as ul by default", () => {
      const { container } = render(<List />);
      expect(container.querySelector("ul")).toBeInTheDocument();
    });

    it("renders as ol when type='ol'", () => {
      const { container } = render(<List type="ol" />);
      expect(container.querySelector("ol")).toBeInTheDocument();
    });

    it("has correct displayName", () => {
      expect(List.displayName).toBe("List");
    });

    it("renders children content", () => {
      render(
        <List>
          <li>Item 1</li>
        </List>
      );
      expect(screen.getByText("Item 1")).toBeInTheDocument();
    });

    it("renders items from items prop", () => {
      const items = [
        { id: 1, content: "First" },
        { id: 2, content: "Second" },
      ];
      render(<List items={items} />);
      expect(screen.getByText("First")).toBeInTheDocument();
      expect(screen.getByText("Second")).toBeInTheDocument();
    });

    it("renders nothing when items is empty", () => {
      const { container } = render(<List items={[]} />);
      expect(container.querySelector("ul")?.children).toHaveLength(0);
    });

    it("uses renderItem when provided", () => {
      const items = [
        { id: 1, content: "First" },
        { id: 2, content: "Second" },
      ];
      const renderItem = (item: any, index: number) => (
        <li key={index} data-testid={`custom-${index}`}>
          Custom: {item.content}
        </li>
      );
      render(<List items={items} renderItem={renderItem} />);
      expect(screen.getByText("Custom: First")).toBeInTheDocument();
      expect(screen.getByTestId("custom-0")).toBeInTheDocument();
    });
  });

  describe("Variants", () => {
    it("applies unstyled variant with no extra classes", () => {
      const { container } = render(<List variant="unstyled" />);
      const el = container.querySelector("ul");
      expect(el?.className).toContain("list--unstyled");
    });

    it("applies default variant classes for ul", () => {
      const { container } = render(<List variant="default" />);
      const el = container.querySelector("ul");
      expect(el?.className).toContain("list--default");
      expect(el?.className).toContain("list-disc");
    });

    it("applies default variant classes for ol", () => {
      const { container } = render(<List type="ol" variant="default" />);
      const el = container.querySelector("ol");
      expect(el?.className).toContain("list-decimal");
    });
  });

  describe("Props", () => {
    it("applies custom className", () => {
      const { container } = render(<List className="my-list" />);
      expect(container.querySelector("ul")?.className).toContain("my-list");
    });

    it("applies inline style", () => {
      const { container } = render(<List style={{ color: "blue" }} />);
      expect(container.querySelector("ul")?.style.color).toBe("blue");
    });

    it("forwards ref to ul element", () => {
      const ref = React.createRef<HTMLUListElement>();
      render(<List ref={ref} />);
      expect(ref.current).toBeInstanceOf(HTMLUListElement);
    });

    it("forwards ref to ol element", () => {
      const ref = React.createRef<HTMLOListElement>();
      render(<List ref={ref} type="ol" />);
      expect(ref.current).toBeInstanceOf(HTMLOListElement);
    });

    it("passes item className to ListItem", () => {
      const items = [{ id: 1, content: "Item", className: "item-class" }];
      render(<List items={items} />);
      const li = screen.getByText("Item");
      expect(li.className).toContain("item-class");
    });
  });
});

describe("ListItem", () => {
  it("renders children content", () => {
    render(<ListItem>Hello</ListItem>);
    expect(screen.getByText("Hello")).toBeInTheDocument();
  });

  it("has correct displayName", () => {
    expect(ListItem.displayName).toBe("ListItem");
  });

  it("renders as li element", () => {
    render(<ListItem>Item</ListItem>);
    expect(screen.getByText("Item").tagName).toBe("LI");
  });

  it("applies custom className", () => {
    render(<ListItem className="custom">Item</ListItem>);
    expect(screen.getByText("Item").className).toContain("custom");
  });

  it("applies unstyled variant", () => {
    render(<ListItem variant="unstyled">Item</ListItem>);
    const el = screen.getByText("Item");
    expect(el.className).toContain("list-item--unstyled");
  });

  it("applies default variant classes", () => {
    render(<ListItem variant="default">Item</ListItem>);
    const el = screen.getByText("Item");
    expect(el.className).toContain("list-item--default");
    expect(el.className).toContain("mb-1");
  });

  it("applies inline style", () => {
    render(<ListItem style={{ color: "green" }}>Item</ListItem>);
    expect(screen.getByText("Item").style.color).toBe("green");
  });

  it("forwards ref to li element", () => {
    const ref = React.createRef<HTMLLIElement>();
    render(<ListItem ref={ref}>Item</ListItem>);
    expect(ref.current).toBeInstanceOf(HTMLLIElement);
  });

  it("passes additional HTML attributes", () => {
    render(<ListItem data-testid="li-item">Item</ListItem>);
    expect(screen.getByTestId("li-item")).toBeInTheDocument();
  });
});
