import { selectorFamily } from 'recoil';
import contestCallEventsAtom from '../atoms/contestCallEvents';
import multiSourceData from './multiSourceData';

/**
 * Helper to reformat contest calls into the structure required for contest
 * summaries. Exported for testing purposes.
 */
export const formattedContestCallEventsFromCalls = (contestId, callList) => {
  const callsByParty = new Map();
  const callsByCandidate = new Map();
  const calls = callList.filter(call => {
    if (call.contestId !== contestId) return false;
    if (call.subjectType === 'candidate') {
      callsByCandidate.set(call.subjectId, [...(callsByCandidate.get(call.subjectId) || []), call]);
    }
    if (call.subjectType === 'party') {
      callsByParty.set(call.subjectId, [...(callsByParty.get(call.subjectId) || []), call]);
    }
    return true;
  });
  return {
    calls,
    callsByParty: Object.fromEntries(callsByParty),
    callsByCandidate: Object.fromEntries(callsByCandidate)
  };
};

/**
 * Contest call events can be hydrated by a calls file.
 */
const contestCallEvents = selectorFamily({
  key: 'election.selectors.contestCallEvents',
  get: key => ({
    get
  }) => {
    const atom = contestCallEventsAtom(key);
    const source = get(multiSourceData(atom.key));
    const callList = source ? source.data : [];
    return {
      data: formattedContestCallEventsFromCalls(key, callList),
      source
    };
  }
});
export default contestCallEvents;