import PropTypes from 'prop-types';
import classnames from 'classnames';
import getColor from "../../../utils/colors/getColor.js";
import { IconArrowLeft, IconArrowRight, IconArrowUp, IconArrowDown, IconCaretRight, IconFlag, IconHourglassHigh, IconHourglassLow, IconList, IconMagnifyingGlass, IconSpiral, IconX } from "../../icons/index.js";
import CandidateSwatch from './CandidateSwatch';
import WinnerCheck from './WinnerCheck';
import OutcomeRunoff from './OutcomeRunoff';
import LinkCaret from './LinkCaret';
import classes from './styles.module.scss';

/**
 * This is a mapping of icon types onto components that render those icons
 * along with additional props that should be passed to the component to render
 * the icon correctly. In most cases the components should be icons from
 * Phosphor.
 */
export const icons = {
  ArrowDown: {
    icon: IconArrowDown,
    props: {
      weight: 'bold'
    }
  },
  ArrowLeft: {
    icon: IconArrowLeft,
    props: {
      weight: 'bold'
    }
  },
  ArrowRight: {
    icon: IconArrowRight,
    props: {
      weight: 'bold'
    }
  },
  ArrowUp: {
    icon: IconArrowUp,
    props: {
      weight: 'bold'
    }
  },
  CandidateSwatch: {
    icon: CandidateSwatch,
    props: {
      alt: 'Candidate'
    }
  },
  FavoritedContest: {
    icon: IconFlag,
    props: {
      weight: 'duotone'
    }
  },
  OutcomeFlipToDem: {
    icon: IconSpiral,
    props: {
      alt: 'Flip icon'
    }
  },
  OutcomeFlipToGop: {
    icon: IconSpiral,
    className: classes.flipToGop,
    props: {
      alt: 'Flip icon'
    }
  },
  OutcomeRecountActive: {
    icon: IconHourglassHigh,
    props: {
      weight: 'fill',
      alt: 'Recount'
    }
  },
  OutcomeRecountComplete: {
    icon: IconHourglassLow,
    props: {
      weight: 'fill',
      alt: 'Recount completed'
    }
  },
  OutcomeRunoff: {
    icon: OutcomeRunoff,
    props: {
      alt: 'Runoff'
    }
  },
  OutcomeWin: {
    icon: WinnerCheck,
    props: {
      alt: 'Winner'
    }
  },
  LinkCaret: {
    icon: LinkCaret
  },
  Expand: {
    icon: IconCaretRight,
    className: classes.rotate90,
    props: {
      weight: 'bold',
      alt: 'Expand'
    }
  },
  Collapse: {
    icon: IconCaretRight,
    className: classes.rotate270,
    props: {
      weight: 'bold',
      alt: 'Collapse'
    }
  },
  Hamburger: {
    icon: IconList,
    props: {
      weight: 'bold',
      alt: 'Menu'
    }
  },
  Close: {
    icon: IconX,
    props: {
      weight: 'bold',
      alt: 'Close'
    }
  },
  Search: {
    icon: IconMagnifyingGlass,
    props: {
      weight: 'bold',
      alt: 'Search'
    }
  }
};

/**
 * This is a mapping of standard sizing levels onto actual widths to ensure
 * consistency in icon sizes throughout their uses.
 */
export const sizes = {
  2: '8px',
  3: '12px',
  4: '16px',
  5: '20px',
  6: '24px',
  8: '32px'
};

/**
 * Election-specific icons for use in results displays and election-related
 * UIs. This component collects a few specific icons from our icon set as the
 * canonical representations of specific election results.
 */
const ElectionIcon = function ElectionIcon(props) {
  const {
    type,
    size,
    color
  } = props;
  const config = icons[type];
  if (!config) return null;
  const {
    icon: Icon,
    props: iconProps = {},
    className
  } = config;
  const iconSize = sizes[size] || sizes['5'];
  return <span className={classnames(classes.icon, className)}>
      <Icon color={getColor(color)} size={iconSize} {...iconProps} />
    </span>;
};
ElectionIcon.defaultProps = {
  color: 'currentColor',
  size: '5'
};
ElectionIcon.propTypes = {
  /**
   * The specific election icon to render.
   */
  type: PropTypes.oneOf(Object.keys(icons)).isRequired,
  /**
   * The color of the icon.
   */
  color: PropTypes.string,
  /**
   * The size of the icon.
   */
  size: PropTypes.oneOf(Object.keys(sizes))
};
export default ElectionIcon;