import foundations from '../../theme/foundations'
import { isObject } from '../../utils'
import { createGlobalStyle, css } from '../styled'
import { bounce, fadeDown, fadeIn, fadeLeft, fadeOut, fadeRight, fadeUp, pulse, spin } from './animations'
import { noScrollClass } from './consts'
import fontFaces from './fontFaces'

type GlobalStyleProps = {
  globalStyle?: boolean
}

/**
 * Provides global styles, such as:
 * - font face definitions
 * - font base styles (color, size, family)
 * - animation keyframes
 * - CSS variables for each theme value
 */
export default createGlobalStyle<GlobalStyleProps>`
  ${fontFaces}
  :root {
    ${generateCSSVariables}
  }

  * {
    --x-ring-color: var(--vui-colors-focusColor);
    // Fixes a box-shadow issue between some parent and child components
    --x-shadow: 0 0 0 0 transparent;
  }

  button,
  .vui-avatar,
  .vui-tag,
  .vui-sidemenu-item,
  .vui-switchTrack {
    --x-ring-color: transparent;
  }

  button:focus-visible,
  li:focus-visible,
  .vui-avatar:focus-visible,
  .vui-tag:focus-visible,
  .vui-sidemenu-item:focus-visible,
  .vui-switchTrack:focus-visible {
    --x-ring-color: var(--vui-colors-focusColor);
    outline: var(--vui-colors-focusColor) solid 3px;
    z-index: 1;
  }

  body.${noScrollClass} {
    overflow: hidden !important;
    overscroll-behavior: contain;
  }

  //@formatter:off
  ${p =>
    p.globalStyle &&
    css`
      body {
        color: sandstone.10;
        font-family: avenir;
        font-size: md;
      }

      h1,
      h2,
      h3,
      h4,
      h5 {
        color: darkBlue.18;
      }
    `}

  //@formatter:on
  @keyframes vui-bounce {
  ${bounce}
  }

  @keyframes vui-fadeDown {
  ${fadeDown(20)}
  }

  @keyframes vui-fadeIn {
  ${fadeIn}
  }

  @keyframes vui-fadeLeft {
  ${fadeLeft(20)}
  }

  @keyframes vui-fadeLeftLong {
  ${fadeLeft(600)}
  }

  @keyframes vui-fadeOut {
  ${fadeOut}
  }


  @keyframes vui-fadeRight {
  ${fadeRight(20)}
  }

  @keyframes vui-fadeRightLong {
  ${fadeRight(600)}
  }

  @keyframes vui-fadeUp {
  ${fadeUp(20)}
  }

  @keyframes vui-pulse {
  ${pulse}
  }

  @keyframes vui-spin {
  ${spin}
  }
`

/** Recursively maps through all theme styles and generates a set of CSS properties. */
function generateCSSVariables() {
  function computeStyle(name: string, value: any): string {
    if (!isObject(value)) return `${name}: ${typeof value === 'string' ? value : `${value}px`};\n`

    return Object.entries(value).reduce((str, [key, value]) => {
      return (str += computeStyle(`${name}-${key}`, value))
    }, '')
  }

  const { animations, transformers, ...styles } = foundations

  return computeStyle('--vui', styles)
}
