import { useMemo } from 'react';
import { useContestCollectionContests } from "../index.js";
import getContestStatusIsUnclear from "../../../utils/election/getContestStatusIsUnclear/index.js";

/**
 * Function to create a palette object for electoral maps.
 *
 * @param {String} collectionId  Contest collection id
 * @param {String} mapGeography  Which type of map geography you're using, one of "districts", "states" or "electoral"
 * @returns
 */

const useMapColors = function useMapColors({
  collectionId,
  mapGeography = 'districts'
}) {
  const contests = useContestCollectionContests(collectionId);
  const contestIds = contests ? Object.keys(contests) : [];
  return useMemo(() => {
    const getBaseCode = opts => {
      const {
        stateFips,
        districtNumber
      } = opts;
      const district = [stateFips, districtNumber].filter(Boolean).join('');
      if (mapGeography === 'electoral') return district;
      if (mapGeography === 'districts') return district;
      return stateFips;
    };
    const getCode = opts => {
      const {
        isSpecial
      } = opts;
      const code = getBaseCode(opts);
      if (!isSpecial) return code;
      return `${code}-special`;
    };
    const statuses = contestIds.reduce((status, contestId) => {
      const contest = contests[contestId];
      const {
        combinedMetadata: meta,
        contestStatus,
        candidateColors
      } = contest;
      const {
        leadingCandidate,
        winningCandidate
      } = contestStatus;
      const candidateId = winningCandidate || leadingCandidate;
      const palette = candidateColors && candidateColors[candidateId];
      const code = getCode(meta.contest);
      const statusIsUnclear = getContestStatusIsUnclear(contestStatus);
      status.fipsToPalette.set(code, {
        code,
        status: contestStatus,
        statusIsUnclear,
        candidateId,
        contestId,
        palette
      });
      if (palette) {
        status.palettes.set(contestId, palette);
      }
      return {
        ...status,
        includeNoClearLeader: status.includeNoClearLeader || statusIsUnclear,
        includeRunoff: status.includeRunoff || contestStatus.outcome === 'runoff',
        includeFlip: status.includeFlip || contestStatus.outcomeBalanceType === 'flip'
      };
    }, {
      fipsToPalette: new Map(),
      palettes: new Map(),
      includeNoClearLeader: false,
      includeRunoff: false
    });
    return {
      ...statuses,
      palettes: [...statuses.palettes].map(([contestId, palette]) => ({
        contestId,
        palette
      }))
    };
  }, [contests]);
};
export default useMapColors;