'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var React = require('react');
var options = require('../../utilities/options.js');
var arrays = require('../../utilities/arrays.js');
var useDeepEffect = require('../../utilities/use-deep-effect.js');
var Option = require('./components/Option/Option.js');
var hooks = require('../../utilities/unique-id/hooks.js');
var Box = require('../Box/Box.js');
var Bleed = require('../Bleed/Bleed.js');
var Text = require('../Text/Text.js');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var React__default = /*#__PURE__*/_interopDefaultLegacy(React);

function OptionList({
  options,
  sections,
  title,
  selected,
  allowMultiple,
  role,
  optionRole,
  verticalAlign,
  onChange,
  id: idProp,
  onPointerEnterOption,
  onFocusOption
}) {
  const [normalizedOptions, setNormalizedOptions] = React.useState(createNormalizedOptions(options, sections, title));
  const id = hooks.useUniqueId('OptionList', idProp);
  useDeepEffect.useDeepEffect(() => {
    setNormalizedOptions(createNormalizedOptions(options || [], sections || [], title));
  }, [options, sections, title], optionArraysAreEqual);
  const handleClick = React.useCallback((sectionIndex, optionIndex) => {
    const selectedValue = normalizedOptions[sectionIndex].options[optionIndex].value;
    const foundIndex = selected.indexOf(selectedValue);

    if (allowMultiple) {
      const newSelection = foundIndex === -1 ? [selectedValue, ...selected] : [...selected.slice(0, foundIndex), ...selected.slice(foundIndex + 1, selected.length)];
      onChange(newSelection);
      return;
    }

    onChange([selectedValue]);
  }, [normalizedOptions, selected, allowMultiple, onChange]);
  const handlePointerEnter = React.useCallback((sectionIndex, optionIndex) => {
    if (!onPointerEnterOption) return;
    const selectedValue = normalizedOptions[sectionIndex].options[optionIndex].value;
    onPointerEnterOption(selectedValue);
  }, [normalizedOptions, onPointerEnterOption]);
  const handleFocus = React.useCallback((sectionIndex, optionIndex) => {
    if (!onFocusOption) return;
    const selectedValue = normalizedOptions[sectionIndex].options[optionIndex].value;
    onFocusOption(selectedValue);
  }, [normalizedOptions, onFocusOption]);
  const optionsExist = normalizedOptions.length > 0;
  const optionsMarkup = optionsExist ? normalizedOptions.map(({
    title,
    options
  }, sectionIndex) => {
    const isFirstOption = sectionIndex === 0;
    const titleMarkup = title ? /*#__PURE__*/React__default["default"].createElement(Box.Box, {
      paddingBlockStart: isFirstOption ? '2' : '4',
      paddingInlineStart: "2",
      paddingBlockEnd: "2",
      paddingInlineEnd: "2",
      borderColor: "border-subdued",
      borderBlockStartWidth: !isFirstOption ? '1' : undefined
    }, /*#__PURE__*/React__default["default"].createElement(Text.Text, {
      as: "p",
      variant: "headingXs"
    }, title)) : null;
    const optionsMarkup = options && options.map((option, optionIndex) => {
      const isSelected = selected.includes(option.value);
      const optionId = option.id || `${id}-${sectionIndex}-${optionIndex}`;
      return /*#__PURE__*/React__default["default"].createElement(Option.Option, Object.assign({
        key: optionId
      }, option, {
        id: optionId,
        section: sectionIndex,
        index: optionIndex,
        onClick: handleClick,
        select: isSelected,
        allowMultiple: allowMultiple,
        verticalAlign: verticalAlign,
        role: optionRole,
        onPointerEnter: handlePointerEnter,
        onFocus: handleFocus
      }));
    });
    return /*#__PURE__*/React__default["default"].createElement(Box.Box, {
      key: title || `noTitle-${sectionIndex}`,
      as: "li",
      paddingBlockStart: isFirstOption ? undefined : '2'
    }, titleMarkup, /*#__PURE__*/React__default["default"].createElement(Bleed.Bleed, {
      marginBlockStart: title ? undefined : '05'
    }, /*#__PURE__*/React__default["default"].createElement(Box.Box, {
      as: "ul",
      id: `${id}-${sectionIndex}`,
      role: role
    }, optionsMarkup)));
  }) : null;
  return /*#__PURE__*/React__default["default"].createElement(Box.Box, {
    as: "ul",
    role: role,
    padding: "2"
  }, optionsMarkup);
}

function createNormalizedOptions(options, sections, title) {
  if (options == null) {
    const section = {
      options: [],
      title
    };
    return sections == null ? [] : [section, ...sections];
  }

  if (sections == null) {
    return [{
      title,
      options
    }];
  }

  return [{
    title,
    options
  }, ...sections];
}

function optionArraysAreEqual(firstArray, secondArray) {
  if (options.isSection(firstArray) && options.isSection(secondArray)) {
    return arrays.arraysAreEqual(firstArray, secondArray, testSectionsPropEquality);
  }

  return arrays.arraysAreEqual(firstArray, secondArray);
}

function testSectionsPropEquality(previousSection, currentSection) {
  const {
    options: previousOptions
  } = previousSection;
  const {
    options: currentOptions
  } = currentSection;
  const optionsAreEqual = arrays.arraysAreEqual(previousOptions, currentOptions);
  const titlesAreEqual = previousSection.title === currentSection.title;
  return optionsAreEqual && titlesAreEqual;
}

exports.OptionList = OptionList;
