/**
 * SelectWidget component.
 * @module components/manage/Widgets/SelectWidget
 */

import map from 'lodash/map';
import filter from 'lodash/filter';
import toPairs from 'lodash/toPairs';
import groupBy from 'lodash/groupBy';
import { useEffect } from 'react';
import PropTypes from 'prop-types';
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
import { compose } from 'redux';

import { FormFieldWrapper } from '@plone/volto/components/manage/Widgets';
import withQueryString from './../hocs/withQueryString';
import { defineMessages } from 'react-intl';

import {
  Option,
  DropdownIndicator,
  selectTheme,
  customSelectStyles,
} from '@plone/volto/components/manage/Widgets/SelectStyling';

const identity = (a) => a;

const messages = defineMessages({
  select: {
    id: 'Select…',
    defaultMessage: 'Select…',
  },
});

/**
 * SelectWidget component function.
 * @function SelectWidget
 * @returns {string} Markup of the component.
 */
const SelectWidget = (props) => {
  const { choices, vocabBaseUrl, getVocabulary } = props;

  useEffect(() => {
    if (!choices && vocabBaseUrl) {
      getVocabulary({ vocabNameOrURL: vocabBaseUrl });
    }
  }, [choices, vocabBaseUrl, getVocabulary]);

  const {
    id,
    value,
    onChange,
    placeholder,
    querystring,
    filterOptions = identity,
  } = props;

  const isDisabled = false;
  const { indexes = [] } = querystring;
  const Select = props.reactSelect.default;

  return (
    <FormFieldWrapper {...props}>
      <Select
        id={`field-${id}`}
        name={id}
        placeholder={placeholder ?? props.intl.formatMessage(messages.select)}
        isDisabled={isDisabled}
        className="react-select-container"
        classNamePrefix="react-select"
        options={map(
          toPairs(
            groupBy(toPairs(filterOptions(indexes)), (item) => item[1].group),
          ),
          (group) => ({
            label: group[0],
            options: map(
              filter(group[1], (item) => item[1].enabled),
              (field) => ({
                label: field[1].title,
                value: field[0],
              }),
            ),
          }),
        )}
        styles={customSelectStyles}
        theme={selectTheme}
        components={{ DropdownIndicator, Option }}
        value={{
          value: value?.value,
          label: indexes[value?.value]?.title,
        }}
        onChange={(data) => {
          let dataValue = [];
          if (Array.isArray(data)) {
            for (let obj of data) {
              dataValue.push(obj.value);
            }
            return onChange(id, dataValue);
          }
          return onChange(id, data);
        }}
      />
    </FormFieldWrapper>
  );
};

SelectWidget.propTypes = {
  id: PropTypes.string.isRequired,
  title: PropTypes.string.isRequired,
  description: PropTypes.string,
  required: PropTypes.bool,
  error: PropTypes.arrayOf(PropTypes.string),
  loading: PropTypes.bool,
  value: PropTypes.oneOfType([
    PropTypes.object,
    PropTypes.string,
    PropTypes.bool,
  ]),
  onChange: PropTypes.func.isRequired,
  onBlur: PropTypes.func,
  onClick: PropTypes.func,
  onEdit: PropTypes.func,
  onDelete: PropTypes.func,
  wrapped: PropTypes.bool,
  querystring: PropTypes.object,
};

SelectWidget.defaultProps = {
  description: null,
  required: false,
  items: {
    vocabulary: null,
  },
  widgetOptions: {
    vocabulary: null,
  },
  error: [],
  choices: [],
  loading: false,
  value: null,
  onChange: () => {},
  onBlur: () => {},
  onClick: () => {},
  onEdit: null,
  onDelete: null,
};

export default compose(
  withQueryString,
  injectLazyLibs(['reactSelect']),
)(SelectWidget);
