import { act, cleanup, fireEvent } from '@testing-library/react';
import { render } from '../../../utils/theme-render-wrapper';
import noop from 'lodash/noop';

import type { DropdownMenuItem } from '../../dropdown-menu';
import { mockData, mockTableConfig } from '../__mocks__';

import { DataGrid, GridFeatureModes, GridSpecialColumnFields } from '../index';
import type { DataGridProps } from '../index';

beforeEach(() => jest.useFakeTimers());

afterEach(() => {
  jest.useRealTimers();
  cleanup();
});

const title1 = 'title1';
const title2 = 'title2';
const defaultNumOfRowsOptions: DropdownMenuItem[] = [
  { name: 25, selected: false },
  { name: 50, selected: false },
  { name: 100, selected: true },
  { name: 250, selected: false }
];

const Wrapper = (props: Partial<DataGridProps>) => (
  <DataGrid
    tableConfig={mockTableConfig as DataGridProps['tableConfig']}
    tableData={mockData}
    numOfRowsOptions={defaultNumOfRowsOptions}
    filtersProps={{
      filters: [],
      values: {},
      onValuesChange: noop,
      handleFieldSaveFilters: noop
    }}
    toolbarProps={{
      title1,
      title2,
      tableSettingsListItems: mockTableConfig.slice(1).map(item => ({
        checkboxProps: { disabled: item.field === 'actions' },
        hidden: item.field === 'actions',
        name: item.title || item.headerName || '',
        selected: true,
        value: item.field
      })),
      handleSearchChangeCallback: noop,
      handleTableSettingsMenuItemClick: () => noop,
      onChangeNumOfRows: () => noop,
      tableSettingsButtonHandler: noop,
      exportButtonProps: {
        onClick: noop
      }
    }}
    paginationProps={{
      page: 0,
      count: mockData.data.length,
      rowsPerPage: defaultNumOfRowsOptions[0].name as number,
      onChangePage: noop
    }}
    {...props}
  />
);

describe('<DataGrid />', () => {
  it(`should render successfully and check column hover`, () => {
    const { queryAllByRole } = render(<Wrapper headerHeight={96} paginationProps={undefined} />);

    const headerEl = queryAllByRole('columnheader');
    fireEvent.mouseOver(headerEl[1]);
    fireEvent.mouseOut(headerEl[1]);
  });

  it(`should render with treeData and all toolbar buttons`, () => {
    const { getByTestId } = render(
      <Wrapper
        treeDataField="companyName"
        initialState={{
          pinnedColumns: {
            left: [GridSpecialColumnFields.TREE_DATA_GROUPING, 'companyName'],
            right: ['actions']
          }
        }}
        // disable DeferredGridCell
        components={{ Cell: undefined }}
      />
    );
    act(() => {
      getByTestId('childCollapseButton').click();
      getByTestId('exportButton').click();
      getByTestId('rowSelectionButton').click();
      getByTestId('tableSettingsButton').click();
    });
  });

  it(`should render with checkboxes, pinnedColumns and treeData`, () => {
    const { getByTestId } = render(
      <Wrapper
        checkboxSelection
        selected={['60c56c5520d2d56612ce60ae']}
        treeDataField="companyName"
        initialState={{
          pinnedColumns: {
            left: [
              GridSpecialColumnFields.CHECKBOX_SELECTION,
              GridSpecialColumnFields.TREE_DATA_GROUPING,
              'companyName'
            ],
            right: ['actions']
          }
        }}
        // disable DeferredGridCell
        components={{ Cell: undefined }}
      />
    );
    const buttonEl = getByTestId('childCollapseButton');
    fireEvent.keyDown(buttonEl, { key: 'Enter' });
    buttonEl.click();
  });

  it(`should render/scroll in server-side mode with autoHeight`, () => {
    render(
      <Wrapper
        autoHeight
        filterMode={GridFeatureModes.SERVER}
        paginationMode={GridFeatureModes.SERVER}
        rowCount={3}
      />
    );
    act(() => {
      fireEvent.scroll(window, { target: { scrollY: 1024 } });
    });
  });

  it(`should render loader skeleton with pinned columns`, () => {
    render(
      <Wrapper
        loading
        initialState={{
          pinnedColumns: {
            left: ['companyName'],
            right: ['actions']
          }
        }}
      />
    );
    jest.runAllTimers();
  });

  it(`should render with autoHeight and lazyLoading`, () => {
    const setTimeoutSpy = jest.spyOn(global, 'setTimeout');
    render(<Wrapper autoHeight lazyLoading />);

    act(() => {
      // trigger an event for LazyLoadingGridRow
      fireEvent.scroll(window, { target: { scrollY: 1024 } });
      jest.runAllTimers();
    });

    expect(setTimeoutSpy).toHaveBeenCalled();
    setTimeoutSpy.mockClear();
  });
});
