import { useMemo } from 'react';
import { getStateName, formatNumber, getPartyName } from "../../../utils/election/index.js";
import { ordinal } from 'journalize';

/**
 * Constructs auto text to label the state importance chart.
 * @param {string} stateFips         - The FIPS code of the state that's highlighted
 * @param {string} party             - The party ("dem or "gop")
 * @param {array}  statesByDelegates - States sorted by total number of delegates for the relevant party
 * @returns {string}
 */

// Find the previous two, or following two states in the sorted dels array
const getNeighboringStates = ({
  statesByDelegates,
  thisStateIdx,
  type
}) => {
  if (type === 'prev') {
    return [{
      name: getStateName(statesByDelegates[thisStateIdx - 1].stateFips, {
        format: 'sentence'
      }),
      total: statesByDelegates[thisStateIdx - 1].total
    }, {
      name: getStateName(statesByDelegates[thisStateIdx - 2].stateFips, {
        format: 'sentence'
      }),
      total: statesByDelegates[thisStateIdx - 2].total
    }];
  }
  return [{
    name: getStateName(statesByDelegates[thisStateIdx + 1].stateFips, {
      format: 'sentence'
    }),
    total: statesByDelegates[thisStateIdx + 1].total
  }, {
    name: getStateName(statesByDelegates[thisStateIdx + 2].stateFips, {
      format: 'sentence'
    }),
    total: statesByDelegates[thisStateIdx + 2].total
  }];
};
const getComparisonStatement = ({
  statesByDelegates,
  type
}) => {
  // By default compare to the max states
  let firstComparison = statesByDelegates[0];
  let secondComparison = statesByDelegates[1];
  let comparator = 'highest';
  if (type === 'lowest') {
    firstComparison = statesByDelegates[statesByDelegates.length - 1];
    secondComparison = statesByDelegates[statesByDelegates.length - 2];
    comparator = 'lowest';
  }
  const firstComparisonName = getStateName(firstComparison.stateFips, {
    format: 'sentence'
  });
  const secondComparisonName = getStateName(secondComparison.stateFips, {
    format: 'sentence'
  });
  return `Comparatively, some of the ${comparator} counts belong to 
  ${firstComparisonName} (${firstComparison.total})
   and ${secondComparisonName} (${secondComparison.total}).`;
};
const getRelativeStatesStatement = ({
  stateFips,
  thisStateIdx,
  statesByDelegates,
  hasOrHave
}) => {
  const stateName = getStateName(stateFips, {
    format: 'sentence'
  });
  if (thisStateIdx === statesByDelegates.length - 1) {
    const prevStates = getNeighboringStates({
      statesByDelegates,
      thisStateIdx,
      type: 'prev'
    });

    // If lowest count
    return `In raw delegates, ${stateName} ${hasOrHave} the lowest count, behind 
      ${prevStates[0].name} (${prevStates[0].total}) and 
      ${prevStates[1].name} (${prevStates[1].total}).`;
  }
  if (thisStateIdx >= statesByDelegates.length - 6) {
    const prevStates = getNeighboringStates({
      statesByDelegates,
      thisStateIdx,
      type: 'prev'
    });

    // If in bottom five
    return `In raw delegates, ${stateName} ${hasOrHave} one of the lowest counts, along with 
    ${prevStates[0].name} (${prevStates[0].total}) and 
    ${prevStates[1].name} (${prevStates[1].total}).`;
  }
  if (thisStateIdx === 0) {
    const nextStates = getNeighboringStates({
      statesByDelegates,
      thisStateIdx,
      type: 'next'
    });

    // If highest count
    return `In raw delegates, ${stateName} ${hasOrHave} the highest count, followed by
    ${nextStates[0].name} (${nextStates[0].total}) and 
    ${nextStates[1].name} (${nextStates[1].total}).`;
  }

  // If in the middle
  const nextStates = getNeighboringStates({
    statesByDelegates,
    thisStateIdx,
    type: 'next'
  });
  return `In raw delegates, ${stateName} ${hasOrHave} the ${ordinal(thisStateIdx)} highest count followed by 
  ${nextStates[0].name} (${nextStates[0].total}) and 
  ${nextStates[1].name} (${nextStates[1].total}).`;
};
const chartLabelFormatter = opts => {
  const {
    stateFips,
    party,
    statesByDelegates,
    totalDelegates
  } = opts;
  if (!statesByDelegates) {
    return '';
  }
  const totalStates = statesByDelegates.length;
  const thisState = statesByDelegates.find(d => d.stateFips === stateFips);
  if (!thisState) return '';
  const thisStateIdx = statesByDelegates.indexOf(thisState);
  const stateDelegates = thisState.total;
  const stateName = getStateName(stateFips, {
    format: 'sentence',
    capitalized: true
  });
  const hasOrHave = stateFips === '69' || stateFips === '78' ? 'have' : 'has';
  const partyName = getPartyName(party, {
    format: 'name',
    fullPartyName: party === 'dem' ? 'Democratic' : undefined // to do: add adjective format
  });

  const relativeStates = getRelativeStatesStatement({
    stateFips,
    thisStateIdx,
    statesByDelegates,
    hasOrHave
  });
  const comparisonType = thisStateIdx >= totalStates / 2 ? 'highest' : 'lowest';
  const comparisonStatement = getComparisonStatement({
    statesByDelegates,
    type: comparisonType
  });
  return `${stateName} ${hasOrHave} ${stateDelegates} of the 
  ${formatNumber(totalDelegates)} pledged delegates 
  up for grabs in 2024 to ${partyName} candidates. 
  ${relativeStates}
  ${comparisonStatement}`;
};
const useChartLabel = ({
  stateFips,
  party,
  statesByDelegates,
  totalDelegates
}) => useMemo(() => chartLabelFormatter({
  stateFips,
  party,
  statesByDelegates,
  totalDelegates
}), [stateFips, party, statesByDelegates, totalDelegates]);
export default useChartLabel;