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

describe("Switch", () => {
  const mockOnChange = vi.fn();

  const props = {
    checked: false,
    onChange: mockOnChange,
    className: "custom-class",
  };

  it("should render without errors", () => {
    const view = render(<Switch {...props} />);
    expect(view).toBeTruthy();
  });

  it("should have expected class names", () => {
    const { container } = render(<Switch {...props} />);
    expect(container.firstChild).toHaveClass("mobius mobius-switch");
    expect(container.firstChild).not.toHaveClass("mobius-switch--checked");
  });

  it("should have expected class name when checked", () => {
    const { container } = render(<Switch {...props} checked={true} />);
    expect(container.firstChild).toHaveClass("mobius-switch--checked");
  });

  it("should have expected class name and attribute when disabled", () => {
    const { container } = render(<Switch {...props} isDisabled={true} />);
    expect(container.firstChild).toHaveClass("mobius-switch--disabled");

    const input = screen.getByRole("switch");
    expect(input).toBeDisabled();
  });

  it("should receive custom class name with props", () => {
    const { container } = render(<Switch {...props} />);
    expect(container.firstChild).toHaveClass(props.className);
  });

  it("should call onChange handler when toggled", () => {
    render(<Switch {...props} data-testid="test-id" />);

    const trigger = screen.getByTestId("test-id");
    fireEvent.click(trigger);

    expect(mockOnChange).toHaveBeenCalled();
  });

  it("should call onChange handler when toggled with passed value", () => {
    let checked = false;

    render(
      <Switch
        checked={false}
        onChange={() => (checked = !checked)}
        data-testid="test-id"
      />,
    );

    const trigger = screen.getByTestId("test-id");
    fireEvent.click(trigger);
    expect(checked).toBe(true);

    fireEvent.click(trigger);
    expect(checked).toBe(false);
  });

  it("should contain input with role switch and type checkbox", () => {
    render(<Switch {...props} data-testid="test-id" />);

    const input = screen.getByRole("switch");
    expect(input).toHaveAttribute("type", "checkbox");
  });
});
