// @flow
import type { Styles } from '../types/style'
import PolishedError from '../internalHelpers/_errors'

/**
 * Helper for targeting rules in a style block generated by polished modules that need !important-level specificity. Can optionally specify a rule (or rules) to target specific rules.
 *
 * @example
 * // Styles as object usage
 * const styles = {
 *   ...important(cover())
 * }
 *
 * // styled-components usage
 * const div = styled.div`
 *   ${important(cover())}
 * `
 *
 * // CSS as JS Output
 *
 * div: {
 *   'position': 'absolute !important',
 *   'top': '0 !important',
 *   'right: '0 !important',
 *   'bottom': '0 !important',
 *   'left: '0 !important'
 * }
 */
export default function important(styleBlock: Styles, rules?: Array<string> | string): Styles {
  if (typeof styleBlock !== 'object' || styleBlock === null) {
    throw new PolishedError(75, typeof styleBlock)
  }

  const newStyleBlock = {}

  Object.keys(styleBlock).forEach(key => {
    if (typeof styleBlock[key] === 'object' && styleBlock[key] !== null) {
      newStyleBlock[key] = important(styleBlock[key], rules)
    } else if (!rules || (rules && (rules === key || rules.indexOf(key) >= 0))) {
      newStyleBlock[key] = `${styleBlock[key]} !important`
    } else {
      newStyleBlock[key] = styleBlock[key]
    }
  })

  return newStyleBlock
}
