import classNames from 'classnames';
import isEqual from 'lodash/isEqual';
import intersectionWith from 'lodash/intersectionWith';
import React from 'react';
import PropTypes from 'prop-types';

const labelOption = (theme, group, changeGroup, selecteds) => {
  return (
    group.label && group.label.length &&
    <li
      role="button"
      className={
        classNames(
          'c-options-group__group-header',
          theme['c-options-group__group-header'],
        )
      }
      onClick={(event) => {
        event.preventDefault();
        const intersection = intersectionWith(
          selecteds,
          group.options,
          (a, b) => isEqual(a.values, b.values),
        );
        if (intersection.length === group.options.length) {
          changeGroup(group, false);
        } else {
          changeGroup(group, true);
        }
      }}
    >
        {group.label}
    </li>
  );
};

export default function OptionsGroup({
  theme,
  group,
  changeOption,
  changeGroup,
  selecteds,
  activeValue,
  handleKeyDown,
  setActiveOption,
  resetActiveOption,
}) {
  return (
    <ul
      className={
        classNames(
          'c-options-group',
          theme['c-options-group'],
        )
      }
    >
      {labelOption(theme, group, changeGroup, selecteds)}
      {
        group.options.map((option, index) => (
          <li
            key={option.label + index}
            className={
              classNames(
                {
                  'c-options-group__group-option--active': (isEqual(option.values, activeValue)),
                  [theme['c-options-group__group-option--active']]: (isEqual(option.values, activeValue)),
                }
              )
            }
            onMouseEnter={() => setActiveOption(option.values)}
            onMouseLeave={resetActiveOption}
          >
            <label
              className={
                classNames(
                  'c-options-group__group-option',
                  theme['c-options-group__group-option'],
                )
              }
              htmlFor={option.label}
            >
              <input
                id={option.label}
                key={option.label}
                value={option.label}
                type="checkbox"
                autoFocus={isEqual(option.values, activeValue)}
                onKeyDown={handleKeyDown}
                onChange={(event) => {
                  const { value, checked } = event.target;
                  const opt = group.options.find(o => o.label === value);
                  changeOption(opt, checked);
                }}
                checked={!!selecteds.find(o => isEqual(o.values, option.values))}
              />
              {option.label}
            </label>
          </li>
        ))
      }
    </ul>
  );
}

OptionsGroup.propTypes = {
  theme: PropTypes.oneOfType([
    PropTypes.object,
    PropTypes.func,
  ]).isRequired,
  changeOption: PropTypes.func,
  changeGroup: PropTypes.func,
  selecteds: PropTypes.arrayOf(
    PropTypes.shape({
      value: PropTypes.string,
      label: PropTypes.label,
    }),
  ),
  group: PropTypes.shape({
    label: PropTypes.string,
    options: PropTypes.arrayOf(
      PropTypes.shape({
        value: PropTypes.string,
        label: PropTypes.string,
      }),
    ),
  }),
  optionRef: PropTypes.func,
  activeValue: PropTypes.array,
  handleKeyDown: PropTypes.func,
  setActiveOption: PropTypes.func,
  resetActiveOption: PropTypes.func,
};
