import React, {
  useState,
  useCallback,
  useEffect,
  forwardRef,
  useImperativeHandle
} from 'react'
import { makeStyles } from '@material-ui/styles'
import { useTheme } from '@material-ui/core/styles'
import clsx from 'clsx'
import PropTypes from 'prop-types'
import Paper from '@material-ui/core/Paper'
import DropUp from '@material-ui/icons/ArrowDropUp'
import DropDown from '@material-ui/icons/ArrowDropDown'
import IconButton from '@material-ui/core/IconButton'
import useMediaQuery from '@material-ui/core/useMediaQuery'

import Styles from './styles'

const TRANSITION_DURATION = 250
const MIN_HEIGHT_TO_COLLAPSE = 450

const useRootStyles = makeStyles({
  root: {
    position: 'fixed',
    display: 'flex',
    flexDirection: 'column',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    backgroundColor: (props) => props.color,
    borderRight: (props) => `2px solid ${props.color}`,
    borderLeft: (props) => `2px solid ${props.color}`
  }
})

const useStyles = makeStyles((theme) => Styles(theme, TRANSITION_DURATION))

const Backdrop = forwardRef(
  (
    {
      frontLayer,
      backLayer,
      layerHeightUp,
      classes: extraClasses,
      className,
      headerText,
      backgroundColor,
      isStaticPage,
      layerHeightDown
    },
    ref
  ) => {
    const theme = useTheme()
    const classes = useStyles()
    const rootClasses = useRootStyles({ color: backgroundColor })
    const isMobile = useMediaQuery(theme.breakpoints.down('xs'))
    const isLandscape = useMediaQuery('(orientation: landscape)')
    const [frontLayerHeight, setFrontLayerHeight] = useState(layerHeightUp)
    const [transaction, setTransaction] = useState(false)
    const [isArrowUp, setIsArrowUp] = useState(false)
    const [showHeader, setShowHeader] = useState(false)

    const handleOnClick = () => {
      const height = window.innerHeight
      const contentHeight = isArrowUp
        ? height - layerHeightDown
        : height - (height - layerHeightUp)

      setIsArrowUp(!isArrowUp)
      setNewHeight(contentHeight)
    }

    useImperativeHandle(ref, () => ({
      toggleOnClickMobile: () => {
        if (isMobile) {
          handleOnClick()
        }
      }
    }))

    const setNewHeight = useCallback(async (value) => {
      setTransaction(true)
      setFrontLayerHeight(value)
      setTimeout(() => {
        setTransaction(false)
      }, TRANSITION_DURATION)
    }, [])

    useEffect(() => {
      const height = window.innerHeight

      setShowHeader(
        (height < MIN_HEIGHT_TO_COLLAPSE && isLandscape) ||
          (isMobile && !isStaticPage)
      )

      if (isStaticPage) {
        setNewHeight(height - (height - layerHeightUp))

        return
      }

      if (isMobile) {
        setNewHeight(height - layerHeightDown)

        return
      }

      if (!isMobile) {
        setNewHeight(
          isLandscape && height < MIN_HEIGHT_TO_COLLAPSE
            ? height - layerHeightDown
            : height - (height - layerHeightUp)
        )
      }
    }, [
      isMobile,
      layerHeightDown,
      layerHeightUp,
      setNewHeight,
      isStaticPage,
      isLandscape
    ])

    return (
      <div className={clsx(className, rootClasses.root, extraClasses.root)}>
        <div
          className={clsx(
            classes.backLayer,
            transaction ? classes.backlayerTransition : null,
            extraClasses.backLayer
          )}
          style={{
            height: frontLayerHeight
          }}
        >
          {backLayer}
        </div>
        <Paper className={clsx(classes.frontLayer, extraClasses.frontLayer)}>
          <div className={clsx(classes.headerBox, extraClasses.headerBox)}>
            {headerText}
            {showHeader && (
              <IconButton
                aria-label=""
                classes={{ root: classes.iconDrop }}
                onClick={handleOnClick}
              >
                {isArrowUp ? <DropDown /> : <DropUp />}
              </IconButton>
            )}
          </div>
          <div className={classes.contentWrapper}>
            <div className={classes.frontLayerContent}>{frontLayer}</div>
          </div>
        </Paper>
      </div>
    )
  }
)

Backdrop.defaultProps = {
  layerHeightUp: 200,
  layerHeightDown: 51,
  frontLayer: null,
  backLayer: null,
  className: null,
  classes: {},
  headerText: <span>Settings</span>,
  backgroundColor: '#00bace',
  isStaticPage: false
}

Backdrop.propTypes = {
  layerHeightUp: PropTypes.number,
  layerHeightDown: PropTypes.number,
  frontLayer: PropTypes.node,
  backLayer: PropTypes.node,
  className: PropTypes.string,
  classes: PropTypes.objectOf(PropTypes.any),
  headerText: PropTypes.node,
  backgroundColor: PropTypes.string,
  isStaticPage: PropTypes.bool
}

export default Backdrop