import { render, screen } from '../test-utils';
import TableRow, { TableRowType, TableRowClickableType } from './TableRow';
import { userEvent } from '@testing-library/user-event';

describe('TableRow Component', () => {
  const mockData = {
    cells: [
      {
        cell: {
          type: 'text',
          text: 'Cell content 1',
        },
      },
      {
        cell: {
          type: 'text',
          text: 'Cell content 2',
        },
      },
    ],
  } satisfies TableRowType;

  const mockDataClickable = {
    id: 1,
    cells: mockData.cells,
  } satisfies TableRowClickableType;

  const handleClick = jest.fn();

  it('renders row', () => {
    render(<TableRow />);
    expect(screen.getByTestId('np-table-row')).toBeInTheDocument();
  });

  it('renders `children` when data is not provided', () => {
    render(
      <TableRow>
        <td>Cell text</td>
      </TableRow>,
    );
    expect(screen.getByText('Cell text')).toBeInTheDocument();
  });

  it('renders cells when data is provided', () => {
    render(<TableRow rowData={mockData} />);
    expect(screen.getByText('Cell content 1')).toBeInTheDocument();
    expect(screen.getByText('Cell content 2')).toBeInTheDocument();
  });

  it('renders correct number of cells', () => {
    render(<TableRow rowData={mockData} />);
    expect(screen.getAllByRole('cell')).toHaveLength(mockData.cells.length);
  });

  it('renders correct number of cells with chevron when clickable', () => {
    render(<TableRow rowData={mockDataClickable} onRowClick={handleClick} />);
    expect(screen.getAllByRole('cell')).toHaveLength(mockDataClickable.cells.length + 1);
  });

  it('renders a separator row when `hasSeparator` is passed', () => {
    render(<TableRow rowData={mockData} hasSeparator />);
    expect(screen.getAllByTestId('np-table-row')).toHaveLength(1);
    expect(screen.getAllByTestId('np-table-row--separator')).toHaveLength(1);
  });

  it('renders correct `colSpan` for separator row', () => {
    render(<TableRow rowData={mockData} hasSeparator />);
    const separatorCell = screen.getByTestId('np-table-cell--cosmetic');
    expect(separatorCell).toHaveAttribute('colSpan', mockData.cells.length.toString());
  });

  it('renders correct `colSpan` for separator row with clickable row', () => {
    render(<TableRow rowData={mockDataClickable} hasSeparator onRowClick={handleClick} />);
    const separatorCell = screen.getByTestId('np-table-cell--cosmetic');
    expect(separatorCell).toHaveAttribute(
      'colSpan',
      (mockDataClickable.cells.length + 1).toString(),
    );
  });

  it('does not render separator row when `hasSeparator` is not provided', () => {
    render(<TableRow rowData={mockData} />);
    expect(screen.queryByTestId('np-table-row--separator')).not.toBeInTheDocument();
  });

  it('does not call `onRowClick` when row is not clickable', async () => {
    render(<TableRow rowData={mockData} />);
    await userEvent.click(screen.getByTestId('np-table-row'));
    expect(handleClick).not.toHaveBeenCalled();
  });

  it('applies the clickable class when row is clickable', () => {
    render(<TableRow rowData={mockDataClickable} onRowClick={handleClick} />);
    expect(screen.getAllByTestId('np-table-row')[0]).toHaveClass('np-table-row--clickable');
  });

  it('calls `onRowClick` when row is clicked for clickable row', async () => {
    render(<TableRow rowData={mockDataClickable} onRowClick={handleClick} />);
    await userEvent.click(screen.getByTestId('np-table-row'));
    expect(handleClick).toHaveBeenCalledWith(mockDataClickable);
  });

  it('renders a chevron icon when row is clickable', () => {
    render(<TableRow rowData={mockDataClickable} onRowClick={handleClick} />);
    expect(screen.getByTestId('chevron-up-icon')).toBeInTheDocument();
  });

  it('does not render a chevron icon when row is not clickable', () => {
    render(<TableRow rowData={mockData} />);
    expect(screen.queryByTestId('chevron-up-icon')).not.toBeInTheDocument();
  });
});
