import React, { useState, useCallback, useEffect } from "react"
import { Swatch } from "react-color/lib/components/common"
import PropTypes from "prop-types"
import ColorPicker from "./color-picker"
import ColorPickerInputGroup from "./color-picker-input-group"
import cx from "classnames"
import getColorInHex from "./get-color-in-hex"
import { SavedColorShape } from "./saved-colors-addon"
import { usePopper } from "react-popper"
import Portal from "../portal"
import Label from "../label"

const ColorInput = ({
  label,
  onChange,
  transparency,
  value,
  savedColors,
  children,
}) => {
  const [colorInput, setColorInput] = useState()
  const [colorPicker, setColorPicker] = useState()

  const [active, setActive] = useState(false)

  const { styles, attributes } = usePopper(colorInput, colorPicker, {
    placement: "bottom-start",
    modifiers: [
      {
        name: "flip",
        enabled: true,
      },
    ],
  })

  const buttonClasses = cx(
    "flex items-center w-full bg-white border border-gray-200 rounded text-gray-800 focus:outline-none",
    {
      uppercase: getColorInHex(value) !== "transparent",
    }
  )

  const handleClick = () => {
    if (active) {
      return
    }
    setActive(true)
  }

  const handleChange = (color) => {
    onChange && onChange(color)
  }

  const handleClose = () => {
    setActive(false)
  }

  const handleDocumentClick = useCallback(
    (event) => {
      if (!colorInput) return
      if (!colorPicker) return

      // Close if the the click is not inside the color input or color picker
      if (
        (!colorInput.contains(event.target) || colorInput === event.target) &&
        (!colorPicker.contains(event.target) || colorPicker === event.target)
      ) {
        handleClose()
      }
    },
    [colorPicker, colorInput]
  )

  useEffect(() => {
    document.addEventListener("mousedown", handleDocumentClick)

    return () => {
      document.removeEventListener("mousedown", handleDocumentClick)
    }
  }, [handleDocumentClick])

  const hex = getColorInHex(value)

  const swatchClass = hex === "#FFFFFF" ? " border border-gray-200" : ""

  return (
    <div className="relative" ref={setColorInput}>
      {label && (
        <Label as="div" className="mb-1">
          {label}
        </Label>
      )}

      <div className={buttonClasses} onClick={handleClick}>
        <div
          className={
            "rounded overflow-hidden ml-2 flex-none h-6 w-6" + swatchClass
          }
        >
          <Swatch color={hex} />
        </div>
        <ColorPickerInputGroup color={hex} onChange={handleChange} />
      </div>
      <Portal>
        {active && (
          <div
            ref={setColorPicker}
            style={styles.popper}
            {...attributes.popper}
          >
            <ColorPicker
              onChange={handleChange}
              onClose={handleClose}
              active={active}
              color={hex}
              hexInput={false}
              className="mt-1"
              position="relative"
              transparency={transparency}
              standalone={false}
              savedColors={savedColors}
            >
              {children}
            </ColorPicker>
          </div>
        )}
      </Portal>
    </div>
  )
}

ColorInput.propTypes = {
  label: PropTypes.string,
  onChange: PropTypes.func,
  value: PropTypes.string,
  transparency: PropTypes.bool,
  savedColors: PropTypes.shape(SavedColorShape),
  children: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.node),
    PropTypes.node,
  ]),
}

export default ColorInput
