/* eslint-disable react/forbid-prop-types */
import React, { useMemo, useState } from 'react';
import PropTypes from 'prop-types';

import { capitalize, toString } from 'lodash';
import { useSelector } from 'react-redux';

import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import {
  Collapsible, Form, Icon, Spinner,
} from '@edx/paragon';
import { Tune } from '@edx/paragon/icons';

import {
  PostsStatusFilter, RequestStatus,
  ThreadOrdering, ThreadType,
} from '../data/constants';
import { selectCourseCohorts } from '../discussions/cohorts/data/selectors';
import messages from '../discussions/posts/post-filter-bar/messages';
import { ActionItem } from '../discussions/posts/post-filter-bar/PostFilterBar';

function FilterBar({
  intl,
  filters,
  selectedFilters,
  onFilterChange,
  showCohortsFilter,
}) {
  const [isOpen, setOpen] = useState(false);
  const cohorts = useSelector(selectCourseCohorts);
  const { status } = useSelector(state => state.cohorts);
  const selectedCohort = useMemo(() => cohorts.find(cohort => (
    toString(cohort.id) === selectedFilters.cohort)),
  [selectedFilters.cohort]);

  const allFilters = [
    {
      id: 'type-all',
      label: intl.formatMessage(messages.allPosts),
      value: ThreadType.ALL,
    },
    {
      id: 'type-discussions',
      label: intl.formatMessage(messages.filterDiscussions),
      value: ThreadType.DISCUSSION,
    },
    {
      id: 'type-questions',
      label: intl.formatMessage(messages.filterQuestions),
      value: ThreadType.QUESTION,
    },
    {
      id: 'status-any',
      label: intl.formatMessage(messages.filterAnyStatus),
      value: PostsStatusFilter.ALL,
    },
    {
      id: 'status-unread',
      label: intl.formatMessage(messages.filterUnread),
      value: PostsStatusFilter.UNREAD,
    },
    {
      id: 'status-reported',
      label: intl.formatMessage(messages.filterReported),
      value: PostsStatusFilter.REPORTED,
    },
    {
      id: 'status-unanswered',
      label: intl.formatMessage(messages.filterUnanswered),
      value: PostsStatusFilter.UNANSWERED,
    },
    {
      id: 'status-unresponded',
      label: intl.formatMessage(messages.filterUnresponded),
      value: PostsStatusFilter.UNRESPONDED,
    },
    {
      id: 'sort-activity',
      label: intl.formatMessage(messages.lastActivityAt),
      value: ThreadOrdering.BY_LAST_ACTIVITY,
    },
    {
      id: 'sort-comments',
      label: intl.formatMessage(messages.commentCount),
      value: ThreadOrdering.BY_COMMENT_COUNT,
    },
    {
      id: 'sort-votes',
      label: intl.formatMessage(messages.voteCount),
      value: ThreadOrdering.BY_VOTE_COUNT,
    },
  ];

  return (
    <Collapsible.Advanced
      open={isOpen}
      onToggle={() => setOpen(!isOpen)}
      className="filter-bar collapsible-card-lg border-0"
    >
      <Collapsible.Trigger className="collapsible-trigger border-0">
        <span className="text-primary-700 pr-4">
          {intl.formatMessage(messages.sortFilterStatus, {
            own: false,
            type: selectedFilters.postType,
            sort: selectedFilters.orderBy,
            status: selectedFilters.status,
            cohortType: selectedCohort?.name ? 'group' : 'all',
            cohort: capitalize(selectedCohort?.name),
          })}
        </span>
        <Collapsible.Visible whenClosed>
          <Icon src={Tune} />
        </Collapsible.Visible>
        <Collapsible.Visible whenOpen>
          <Icon src={Tune} />
        </Collapsible.Visible>
      </Collapsible.Trigger>
      <Collapsible.Body className="collapsible-body px-4 pb-3 pt-0">
        <Form>
          <div className="d-flex flex-row py-2 justify-content-between">
            {filters.map((value) => (
              <Form.RadioSet
                key={value.name}
                name={value.name}
                className="d-flex flex-column list-group list-group-flush"
                value={selectedFilters[value.name]}
                onChange={onFilterChange}
              >
                {value.filters.map(filterName => {
                  const element = allFilters.find(obj => obj.id === filterName);
                  if (element) {
                    return (
                      <ActionItem
                        key={element.id}
                        id={element.id}
                        label={element.label}
                        value={element.value}
                        selected={selectedFilters[value.name]}
                      />
                    );
                  }
                  return false;
                })}
              </Form.RadioSet>
            ))}
          </div>
          {showCohortsFilter && (
            <>
              <div className="border-bottom my-2" />
              {status === RequestStatus.IN_PROGRESS ? (
                <div className="d-flex justify-content-center p-4">
                  <Spinner animation="border" variant="primary" size="lg" />
                </div>
              ) : (
                <div className="d-flex flex-row pt-2">
                  <Form.RadioSet
                    name="cohort"
                    className="d-flex flex-column list-group list-group-flush w-100"
                    value={selectedFilters.cohort}
                    onChange={onFilterChange}
                  >
                    <ActionItem
                      id="all-groups"
                      label="All groups"
                      value=""
                      selected={selectedFilters.cohort}
                    />
                    {cohorts.map(cohort => (
                      <ActionItem
                        key={toString(cohort.id)}
                        id={toString(cohort.id)}
                        label={capitalize(cohort.name)}
                        value={toString(cohort.id)}
                        selected={selectedFilters.cohort}
                      />
                    ))}
                  </Form.RadioSet>
                </div>
              )}
            </>
          )}
        </Form>
      </Collapsible.Body>
    </Collapsible.Advanced>
  );
}

FilterBar.propTypes = {
  intl: intlShape.isRequired,
  filters: PropTypes.array.isRequired,
  selectedFilters: PropTypes.object.isRequired,
  onFilterChange: PropTypes.func.isRequired,
  showCohortsFilter: PropTypes.bool,
};

FilterBar.defaultProps = {
  showCohortsFilter: false,
};

export default injectIntl(FilterBar);
