import PropTypes from 'prop-types';
import { always, path, omit, keys } from 'ramda';
import React, { Component } from 'react';
import { Form, Loader } from 'semantic-ui-react';

import Collection from '.';

/* Interface */
const propTypes = {
  /**
   * Predicate to restrict which items show up.
   * @param {Object} item - Item to test.
   * @returns {boolean} Whether to include the item when rendering.
   */
  filterPredicate: PropTypes.func,

  /**
   * Called when the user tries to select a value
   * `onChange(event: SyntheticEvent, data: Object, item)`
   * @param {SyntheticEvent} event - React's original SyntheticEvent.
   * @param {Object} data - All props and proposed value.
   * @param {Object} item - Selected item.
   */
  onChange: PropTypes.func,

  /** Additional parameters to include in the API request. */
  params: PropTypes.object,

  /** Content to display while awaiting data. */
  placeholder: PropTypes.element,

  /** Slug for post type or taxonomy from which posts or terms are drawn. */
  typeSlug: PropTypes.string.isRequired,

  /** ID of the selected item. */
  value: PropTypes.number,
};

/* Defaults */
const defaultProps = {
  filterPredicate: always(true),
  params: { },
  placeholder: <Loader active inline />,
};

/**
 * Radio buttons for choosing items from a collection
 * The following props are supported.
 * Additional props will be passed through to SUI's <Form.Radio> components.
 * @returns {Object} component
 */
export class CollectionRadios extends Component {
  state = {
    total: null, // count of items loaded from StoryShare
  };

  /**
   * Receives updates from the `<Collection>` when items are loaded.
   * @param {Object} pagination - Counts of items and pages.
   * @returns {void}
   */
  handleUpdate = ({ total }) => this.setState({ total });

  /**
   * Handle selection change of Select
   * @param {SyntheticEvent} event - React's synthetic event.
   * @param {Object} data - All props and proposed value.
   * @param {Object} item - The selected item.
   * @returns {void}
   */
  handleChange = (event, data, item) => {
    const { onChange } = this.props;
    if (onChange) {
      onChange(event, data, item);
    }
  };

  render = () => {
    const {
      filterPredicate,
      params,
      placeholder,
      typeSlug,
      value,
    } = this.props;
    const { total } = this.state;

    return (
      <>
        <Collection
          onUpdate={ this.handleUpdate }
          params={ { per_page: 100, ...params } }
          typeSlug={ typeSlug }
        >
          { (item) => filterPredicate(item) && (
            <Form.Radio
              checked={ item.id === value }
              key={ item.id }
              label={ path(['title', 'rendered'], item) || item.name }
              onChange={ (e, data) => this.handleChange(e, data, item) }
              value={ item.id }
              { ...omit(keys(propTypes), this.props) }
            />
          ) }
        </Collection>
        { !total && placeholder }
      </>
    );
  };
}

CollectionRadios.propTypes = propTypes;
CollectionRadios.defaultProps = defaultProps;

export default CollectionRadios;
