import { render, screen, userEvent, mockMatchMedia } from '../test-utils';
import { Position } from '../common';

import Drawer from './Drawer';

jest.mock('../common/DOMOperations');
mockMatchMedia();

describe('Drawer', () => {
  const renderedComponent = (props: React.ComponentProps<typeof Drawer>) =>
    render(<Drawer {...props} />);

  const props = {
    open: true,
    onClose: jest.fn(),
    headerTitle: 'Drawer Title',
    footerContent: <div>Footer Content</div>,
    children: <p>Drawer Content</p>,
    className: 'drawer-class',
  };

  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('renders the Drawer component', () => {
    renderedComponent(props);
    expect(screen.getByRole('dialog')).toBeInTheDocument();
  });

  it('renders the header title', () => {
    renderedComponent(props);
    expect(screen.getByText('Drawer Title')).toBeInTheDocument();
  });

  it('renders the footer content', () => {
    renderedComponent(props);
    expect(screen.getByText('Footer Content')).toBeInTheDocument();
  });

  it('renders the children content', () => {
    renderedComponent(props);
    expect(screen.getByText('Drawer Content')).toBeInTheDocument();
  });

  it('passes through the className prop', () => {
    renderedComponent({ ...props, className: 'drawer-class' });
    expect(screen.getByRole('dialog')).toHaveClass('drawer-class');
  });

  it('calls onClose when the close button is clicked', async () => {
    renderedComponent(props);
    await userEvent.click(screen.getByLabelText('Close'));
    expect(props.onClose).toHaveBeenCalled();
  });

  it('calls onClose if the dimmer is clicked', async () => {
    render(<Drawer {...props} />);
    await userEvent.click(screen.getByRole('button'));
    expect(props.onClose).toHaveBeenCalledTimes(1);
  });

  it('does not call onClose if the drawer content is clicked', async () => {
    render(<Drawer {...props}>Drawer Content</Drawer>);
    await userEvent.click(screen.getByText('Drawer Content'));
    expect(props.onClose).not.toHaveBeenCalled();
  });

  it('does not render the Drawer when open is false', () => {
    renderedComponent({ ...props, open: false });
    expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
  });

  it('renders the Drawer with the correct aria-labelledby attribute', () => {
    renderedComponent(props);
    expect(screen.getByRole('dialog')).toHaveAttribute('aria-labelledby');
  });

  it('renders the Drawer with the correct position', () => {
    renderedComponent({ ...props, position: Position.LEFT });
    expect(screen.getByRole('dialog').parentElement).toHaveClass('sliding-panel--open-left');
  });

  it('renders the Drawer with the correct role attribute', () => {
    renderedComponent(props);
    expect(screen.getByRole('dialog')).toHaveAttribute('role', 'dialog');
  });

  it('renders the Drawer with the correct aria-modal attribute', () => {
    renderedComponent(props);
    expect(screen.getByRole('dialog')).toHaveAttribute('aria-modal', 'true');
  });
});
