import React, { useState } from 'react';
import { cleanup } from '@testing-library/react';
import { render } from '../../../utils/theme-render-wrapper';
import type { DropDownMenuProps } from '../../dropdown-menu';
import { Select } from './select';

afterEach(cleanup);

const listItems = [{ name: 'Ini' }, { name: 'Mini' }, { name: 'Miny' }, { name: 'Mo' }];

describe('<Select />', () => {
  it(`Should render Select with single choice`, () => {
    const Wrapper = () => {
      const [selectValue, setSelectValue] = useState('');

      return (
        <Select
          value={selectValue}
          menuContentProps={{
            search: true,
            handleClick: name => () => setSelectValue(name.toString()),
            listItems
          }}
        />
      );
    };

    const { queryByTestId, queryByText } = render(<Wrapper />);

    const selectEl = queryByTestId('select');
    selectEl?.click();

    const itemEl = queryByText(listItems[0].name);
    itemEl?.click();
  });

  it(`Should render Select with multiple choice`, () => {
    const Wrapper = () => {
      const [multipleSelectValues, setMultipleSelectValues] = useState<string[]>([]);

      const handleMultipleValuesChange: NonNullable<DropDownMenuProps['handleClick']> =
        newValue => () => {
          const index = multipleSelectValues.findIndex(item => item === newValue);
          setMultipleSelectValues(
            index === -1
              ? multipleSelectValues.concat(newValue.toString())
              : multipleSelectValues
                  .slice(0, index)
                  .concat(multipleSelectValues.slice(index + 1, multipleSelectValues.length))
          );
        };

      return (
        <Select
          multiple
          value={multipleSelectValues}
          menuContentProps={{
            search: true,
            handleClick: handleMultipleValuesChange,
            listItems
          }}
        />
      );
    };

    const { queryByTestId, queryByText } = render(<Wrapper />);

    const selectEl = queryByTestId('select');
    selectEl?.click();

    const itemEl = queryByText(listItems[0].name);
    itemEl?.click();
  });

  it(`Should render Select with multiple choice and value`, () => {
    const name = 'name';
    const value = 'value';

    const { queryByText } = render(
      <Select
        multiple
        value={[value]}
        menuContentProps={{
          handleClick: jest.fn(),
          listItems: [
            {
              name,
              value
            }
          ]
        }}
      />
    );

    const el = queryByText(name);
    expect(el).toBeTruthy();
  });

  it(`Should render Select with single choice and value`, () => {
    const name = 'name';
    const value = 'value';

    const { queryByText } = render(
      <Select
        value={value}
        menuContentProps={{
          handleClick: jest.fn(),
          listItems: [
            {
              name,
              value
            }
          ]
        }}
      />
    );

    const el = queryByText(name);
    expect(el).toBeTruthy();
  });

  it(`Should render a disabled Select`, () => {
    const Wrapper = () => {
      const [selectValue, setSelectValue] = useState('');

      return (
        <Select
          disabled
          value={selectValue}
          menuContentProps={{
            search: true,
            handleClick: name => () => setSelectValue(name.toString()),
            listItems
          }}
        />
      );
    };

    render(<Wrapper />);
  });

  it(`Should activate callback function`, () => {
    const handleSelectClickCB = jest.fn();

    const { queryByTestId } = render(
      <Select
        value={'Ini'}
        handleSelectClickCB={handleSelectClickCB}
        menuContentProps={{
          handleClick: jest.fn(),
          listItems
        }}
      />
    );

    const selectEl = queryByTestId('select');
    selectEl?.click();

    expect(handleSelectClickCB).toHaveBeenCalled();
  });
});
