import React, { useState, useEffect, useContext } from 'react'
import { ModalContext } from '@freesewing/react/context/Modal'
import { CloseIcon } from '@freesewing/react/components/Icon'

const slideClasses = {
  left: '-translate-x-full',
  right: 'translate-x-full',
  top: '-translate-y-full',
  bottom: 'translate-y-full',
}

/**
 * This component wraps modal content, making sure the layout is ok and handling transitions
 *
 * @param {object} props - All React props
 * @param {array} children - Content to render inside the modal
 * @param {string} flex - Flexbox direction (row or col)
 * @param {string} justify - Flexbox justify value
 * @param {string} items - Flexbox items value
 * @param {string} bg - Background
 * @param {string} bgOpacity - Background opacity
 * @param {bool} bare - Set true to not handle layout
 * @param {bool} keepOpenOnClick - Set to true to prevent a click in the modal content to close the modal
 * @param {string} slideFrom - Direction to slide in from
 * @param {bool} fullWidth - Set to true to not constrain the width
 */
export const ModalWrapper = ({
  children = null,
  flex = 'row',
  justify = 'center',
  items = 'center',
  bg = 'base-100 lg:bg-base-300',
  bgOpacity = '100 lg:bg-opacity-95',
  bare = false,
  keepOpenOnClick = false,
  slideFrom = 'left',
  fullWidth = false,
}) => {
  const { clearModal } = useContext(ModalContext)
  const [animate, setAnimate] = useState('in')

  const close = (evt) => {
    // Only process the first event
    if (evt?.event) evt.event.stopPropagation()
    setAnimate('out')
    window.setTimeout(clearModal, 150)
  }

  useEffect(() => {
    // only turn off animation if it's animating in
    if (animate === 'in') setAnimate(false)
  }, [animate])

  // CSS classes for animation
  const animation = animate
    ? `lg:opacity-0 ${slideClasses[slideFrom]} lg:translate-x-0 lg:translate-y-0`
    : 'opacity-100 translate-none'

  const stopClick = (evt) => {
    /*
     * Do not keep modal open for links (with a href)
     * but do keep it open for buttons (like a new modal context)
     */
    if (!evt.target.attributes.href) evt.stopPropagation()
  }

  return (
    <div
      className={`fixed top-0 left-0 m-0 p-0 shadow w-full h-screen
        transform-all duration-150 ${animation}
        bg-${bg} bg-opacity-${bgOpacity} z-50 hover:cursor-pointer
        flex flex-${flex} justify-${justify} items-${items} lg:p-12`}
      onClick={close}
    >
      {bare ? (
        children
      ) : (
        <div
          onClick={keepOpenOnClick ? stopClick : null}
          className={`z-30 bg-base-100 p-4 lg:px-8 lg:rounded-lg lg:shadow-lg max-h-full overflow-auto hover:cursor-default ${
            fullWidth ? 'w-full' : ''
          }`}
        >
          {children}
          <button
            className="fixed bottom-2 right-2 btn btn-neutral btn-circle lg:hidden"
            onClick={close}
          >
            <CloseIcon className="w-8 h-8" />
          </button>
        </div>
      )}
    </div>
  )
}