import PropTypes from 'prop-types';
import { useDelegates } from "../../../hooks/election/index.js";
import IfActive from "../../application/IfActive/index.js";
import { useMemo } from 'react';
import { useContainerBreakpointIsAtLeast } from "../../../hooks/breakpoint/index.js";
import DelegateCounter from "../DelegateCounter/index.js";
import sortBy from "../../../utils/sorting/sortBy.js";
import ModuleTitle from "../ModuleTitle/index.js";
import getHeadline from './utils/getHeadline';
import DelegateDots from './DelegateDots';
import classes from './styles.module.scss';
import sumAwarded from './utils/sumAwarded';
export default function DelegateTrackerSingle({
  party,
  reporterNote,
  eyebrow,
  headline,
  description,
  stateFips
}) {
  const delegates = useDelegates(party);
  const eventState = useMemo(() => {
    if (!delegates) return undefined;
    const deliStates = delegates.states;
    return deliStates.find(d => d.stateFips === stateFips);
  }, [delegates, stateFips]);
  const isAtLeastXS = useContainerBreakpointIsAtLeast('xs');

  // A candidates total delegates awarded to them among states in the module
  const eventCandidateTotal = useMemo(() => {
    if (!eventState) return undefined;
    const nonZeroCandidates = eventState.candidates.filter(d => d.total > 0).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'
    }]);
  }, [eventState]);
  const hasLegend = eventCandidateTotal && eventCandidateTotal.length > 0;
  if (!delegates || !eventState) return null;
  const programmaticHeadline = getHeadline({
    total: eventState.total,
    state: stateFips,
    party,
    isComplete: sumAwarded(eventState.candidates) === eventState.total
  });
  return <div className={classes.container}>
      <ModuleTitle headline={headline || programmaticHeadline} description={description} eyebrow={eyebrow} reporterNote={isAtLeastXS ? reporterNote : undefined} />
      <DelegateDots eventState={eventState} />
      <IfActive active={hasLegend}>
        <DelegateCounter delegatesByCandidate={eventCandidateTotal} />
      </IfActive>
    </div>;
}
DelegateTrackerSingle.defaultProps = {
  eyebrow: undefined,
  headline: undefined,
  description: undefined,
  reporterNote: undefined
};
DelegateTrackerSingle.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
   */
  headline: PropTypes.string,
  /**
   * State FIPS to display
   */
  stateFips: PropTypes.string.isRequired
};