import * as React from 'react';
import {
  cleanup,
  render,
  screen,
} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import {
  vi,
  expect,
  describe,
  it,
  afterEach,
} from 'vitest';
import matchers from '@testing-library/jest-dom/matchers';
import { PluginAPI } from 'tailwindcss/types/config';
import {
  RadioTickBox,
  RadioTickBoxDerivedElement,
  radioTickBoxPlugin,
} from '.';

expect.extend(matchers);

describe('radioTickBoxPlugin', () => {
  it('adds component styles', () => {
    const pluginApi = {
      addComponents: vi.fn(),
    } as unknown as PluginAPI;

    radioTickBoxPlugin(pluginApi);
    expect(pluginApi.addComponents).toBeCalledTimes(1);
  });
});

describe('RadioTickBox', () => {
  afterEach(() => {
    cleanup();
  });

  it('renders a radio button', () => {
    render(
      <RadioTickBox />,
    );
    const checkbox = screen.getByRole('radio');
    expect(checkbox).toBeInTheDocument();
  });

  it('renders a block tick box', () => {
    render(
      <RadioTickBox
        block
      />,
    );

    const base = screen.getByTestId('base');
    expect(base).toHaveClass('flex');
  });

  it('renders a subtext', () => {
    render(
      <RadioTickBox
        subtext="subtext"
      />,
    );
    const subtext = screen.getByTestId('subtext');
    expect(subtext).toBeInTheDocument();
  });

  it('handles click events', async () => {
    const onClick = vi.fn().mockImplementationOnce(
      (e: React.MouseEvent<RadioTickBoxDerivedElement>) => {
        e.preventDefault();
      },
    );

    render(
      <RadioTickBox
        onClick={onClick}
      />,
    );
    const radio = screen.getByRole('radio');
    await userEvent.click(radio);
    expect(onClick).toBeCalled();
  });

  it('handles change events', async () => {
    const onChange = vi.fn().mockImplementationOnce(
      (e: React.ChangeEvent<RadioTickBoxDerivedElement>) => {
        e.preventDefault();
      },
    );

    render(
      <RadioTickBox
        onChange={onChange}
      />,
    );
    const radio = screen.getByRole('radio');
    await userEvent.click(radio);
    expect(onChange).toBeCalled();
  });
});
