import PropTypes from 'prop-types';
import { useDelegates } from "../../../hooks/election/index.js";
import { useMemo, useState } from 'react';
import sortBy from "../../../utils/sorting/sortBy.js";
import IfActive from "../../application/IfActive/index.js";
import DelegateCounter from "../DelegateCounter/index.js";
import ModuleTitle from "../ModuleTitle/index.js";
import getHeadline from './utils/getHeadline';
import StatesStack from './StatesStack';
import classes from './styles.module.scss';
export default function DelegateTrackerMulti({
  party,
  reporterNote,
  eyebrow,
  headline,
  description,
  states
}) {
  const delegates = useDelegates(party);
  const [activeCand, setActiveCand] = useState();
  const eventStates = useMemo(() => {
    if (!delegates) return undefined;
    const deliStates = delegates.states;
    const filtered = deliStates.filter(d => states.includes(d.stateFips));
    return sortBy(filtered, [{
      comparison: 'total',
      direction: 'desc'
    }, {
      comparison: 'stateFips',
      direction: 'desc'
    }]);
  }, [delegates, states]);

  // A candidates total delegates awarded to them among states in the module
  const eventCandidateTotal = useMemo(() => {
    if (!eventStates) return undefined;
    const filterTotal = d => d.candidates.filter(({
      total
    }) => total > 0);
    const nonZeroCandidates = eventStates.map(filterTotal).flat();
    const groupedById = nonZeroCandidates.reduce((map, obj) => {
      const {
        id,
        total
      } = obj;
      if (map.has(id)) {
        map.set(id, map.get(id) + total);
      } else {
        map.set(id, total);
      }
      return map;
    }, new Map());
    return sortBy(groupedById, [{
      comparison: ([, total]) => total,
      direction: 'desc'
    }, {
      comparison: ([id]) => id,
      direction: 'desc'
    }]);
  }, [eventStates]);
  const hasLegend = eventCandidateTotal && eventCandidateTotal.length > 0;
  if (!delegates) return null;
  return <div className={classes.container}>
      <ModuleTitle headline={getHeadline({
      headline,
      party,
      delegates,
      states
    })} description={description} eyebrow={eyebrow} reporterNote={reporterNote} />
      <StatesStack eventStates={eventStates} eventCandidateTotal={eventCandidateTotal} activeCand={activeCand} setActiveCand={setActiveCand} />
      <IfActive active={hasLegend}>
        <DelegateCounter delegatesByCandidate={eventCandidateTotal} activeCand={activeCand} />
      </IfActive>
    </div>;
}
DelegateTrackerMulti.defaultProps = {
  eyebrow: undefined,
  headline: undefined,
  description: undefined,
  reporterNote: undefined
};
DelegateTrackerMulti.propTypes = {
  /**
   * The ID of the party to show delegate counts for
   */
  party: PropTypes.oneOf(['dem', 'gop']).isRequired,
  /**
   * Reporter note for module title
   */
  reporterNote: PropTypes.shape({}),
  /**
   * Configuration for the title eyebrow
   */
  eyebrow: PropTypes.shape({}),
  /**
   * Module description
   */
  description: PropTypes.string,
  /**
   * Module headline that overrides the default autogenerated headline. You can
   * use the special template strings `{delegates}`, `{party}`, and `{states}`
   * to automatically fill in the number of delegates at stake, the abbreviated
   * name of the party, and the number of states in play, respectively. For
   * example, setting the headline prop as
   *
   * ```
   * {delegates} {party} delegates will be at stake in {states} states
   * ```
   *
   * would produce a headline like
   *
   * ```
   * 1,237 GOP delegates will be a stake in 14 states
   * ```
   */
  headline: PropTypes.string,
  /**
   * Array of state FIPS to display
   */
  states: PropTypes.arrayOf(PropTypes.string).isRequired
};