import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { ColDef, ValueFormatterParams } from 'ag-grid-community';
import { AgGridReact } from 'ag-grid-react';
import { GenericCellRenderer } from './GenericCellRenderer';
import { useSmallButton } from './useSmallButton';

describe('Text button renderer', function () {
  type TestData = {
    totalReceived: string;
  };
  const rowData: TestData[] = [{ totalReceived: '100' }, { totalReceived: '200' }];

  function TestComponent<TestData>({
    action,
    valueFormatter,
  }: {
    action: (data: TestData) => void;
    valueFormatter?: (param: ValueFormatterParams) => string;
  }) {
    const SmallButton = useSmallButton<TestData>(action);
    const colDefs: ColDef[] = [
      {
        field: 'totalReceived',
        headerName: 'Total Received',
        valueFormatter: valueFormatter,
        cellRenderer: 'genericCellRenderer',
        cellRendererParams: {
          Component: SmallButton,
        },
      },
    ];

    return (
      <AgGridReact
        columnDefs={colDefs}
        rowData={rowData}
        frameworkComponents={{
          genericCellRenderer: GenericCellRenderer,
        }}
      />
    );
  }

  it('should render button with value as its text and trigger specified action on click', async function () {
    const action = jest.fn();
    const { findByText } = render(<TestComponent action={action} />);
    const button = await findByText('100');

    userEvent.click(button);
    expect(action).toHaveBeenCalledTimes(1);
    expect(action).toHaveBeenCalledWith({ totalReceived: '100' });
  });

  it('should render button with formatted value and trigger specified action on click', async function () {
    const action = jest.fn();
    const { findByText } = render(
      <TestComponent action={action} valueFormatter={(params) => `${params.value} USD`} />
    );
    const button = await findByText('100 USD');

    userEvent.click(button);
    expect(action).toHaveBeenCalledTimes(1);
    expect(action).toHaveBeenCalledWith({ totalReceived: '100' });
  });
});