import { cleanup, fireEvent } from '@testing-library/react';
import { render } from '../../../utils/theme-render-wrapper';
import { ASSETS_URL } from '../../../consts/common';
import GlobalSearch from './global-search';
import GlobalSearchGroup from './components/GlobalSearchGroup';
import { groupBy, makeOptionsArray } from './helpers';
import { BaseOptionProps } from './types';

afterEach(cleanup);

const handleClick = jest.fn();

const groupedOptions = {
  users: [
    {
      label: 'Hello',
      email: 'hello@gmail.com'
    }
  ],
  tenant: [{ label: 'company', subtitle: 'subtitle' }],
  'Some Group': [{ label: 'item' }]
};

describe('Check GlobalSearch helpers', () => {
  it('should convert object with group keys to array of options with group field', () => {
    expect(makeOptionsArray(groupedOptions)).toMatchInlineSnapshot(`
      Array [
        Object {
          "email": "hello@gmail.com",
          "group": "users",
          "id": "1",
          "label": "Hello",
        },
        Object {
          "group": "tenant",
          "id": "2",
          "label": "company",
          "subtitle": "subtitle",
        },
        Object {
          "group": "Some Group",
          "id": "3",
          "label": "item",
        },
      ]
    `);
  });

  it('should return group name', () => {
    let expected = 'users';
    const option: BaseOptionProps = {
      group: 'users',
      componentType: 'User',
      label: 'Hello'
    };

    expect(groupBy(option)).toEqual(expected);
    expected = 'User';
    delete option.group;
    expect(groupBy(option)).toEqual(expected);
    expected = 'other';
    delete option.componentType;
    expect(groupBy(option)).toEqual(expected);
  });
});

describe('<GlobalSearch />', () => {
  it('should render successfully', () => {
    const { baseElement } = render(<GlobalSearch />);
    expect(baseElement).toBeTruthy();
  });

  it('should render with value and onEndAdornmentClick', () => {
    const { container, queryByTestId } = render(
      <GlobalSearch
        disableGrouping
        options={[{ id: 'foobar', label: 'foobar' }]}
        endAdornmentIconSrc={`${ASSETS_URL}/icons2/icon_arrow.svg`}
        onEndAdornmentClick={handleClick}
        value={{ label: 'foobar' }}
      />
    );

    // Test button events
    queryByTestId('endAdornment')?.click();
    expect(handleClick).toBeCalledTimes(1);

    // Test input events
    const inputEl = container.querySelector('input');
    inputEl &&
      fireEvent.keyDown(inputEl, { key: 'Space' }) &&
      fireEvent.keyDown(inputEl, { key: 'Enter' });
  });

  it('should render groupedOptions with minInputLength', () => {
    const { container } = render(
      <GlobalSearch groupedOptions={groupedOptions} minInputLength={2} />
    );

    // Test change events
    const inputEl = container.querySelector('input');
    inputEl && fireEvent.change(inputEl, { target: { value: 'Hello' } });
  });
});

describe('<GlobalSearchGroup />', () => {
  it('should render and show right number of children', () => {
    const children = Array(10);

    const groupName = 'Group';
    const { getByTestId } = render(
      <GlobalSearchGroup
        expanded={true}
        params={{ key: 'key', group: groupName, children: children.map(_ => <div>child</div>) }}
      />
    );
    const renderedCount = parseInt(
      getByTestId('group-items-count').textContent?.toString().replace(/[()]/g, '') || ''
    );
    expect(renderedCount).toBe(children.length);
  });
});
