import React, { useEffect, useRef } from "react"
import PropTypes from "prop-types"
import { CustomPicker } from "react-color"
import { Hue, Saturation, Swatch } from "react-color/lib/components/common"
import cx from "classnames"
import ColorPickerInputGroup from "./color-picker-input-group"
import getColorInHex from "./get-color-in-hex"
import ColorsUpdaterToolbar, { SavedColorShape } from "./saved-colors-addon"

const TrianglePointer = () => {
  return (
    <div
      className="inline-flex w-full items-center justify-between absolute"
      style={{ top: "-6px" }}
    >
      <div
        className="w-0 h-0"
        style={{
          borderWidth: 6,
          borderTopColor: "transparent",
          borderLeftColor: "white",
          borderRightColor: "transparent",
          borderBottomColor: "transparent",
        }}
      ></div>
      <div
        className="w-0 h-0"
        style={{
          borderWidth: 6,
          borderTopColor: "transparent",
          borderLeftColor: "transparent",
          borderRightColor: "white",
          borderBottomColor: "transparent",
        }}
      ></div>
    </div>
  )
}

const formatColor = (color) =>
  getColorInHex(color) === "transparent" ? color : color.toUpperCase()

const renderSavedColors = (onChange, savedColors) => {
  const { colors, handleColorSelect, handleColorsEdit } = savedColors
  const handleSelect = (color) => {
    if (handleColorSelect) handleColorSelect(color)
    if (onChange) onChange(color)
  }

  return (
    <div className="flex w-full">
      <ColorsUpdaterToolbar
        colors={colors}
        handleColorSelect={handleSelect}
        handleColorsEdit={handleColorsEdit}
      />
    </div>
  )
}

const ColorPicker = ({
  active,
  anchor,
  hex,
  hsl,
  variant,
  onChange,
  onClose,
  position = "absolute",
  savedColors,
  hexInput = true,
  transparency = false,
  standalone = true,
  children,
  oldHue,
  ...props
}) => {
  const colorPicker = useRef()

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

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

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

  const handleClose = () => {
    onClose && onClose()
  }

  // This will never get called unless standalone is true
  const handleDocumentClick = (event) => {
    if (!colorPicker.current) return
    if (!colorPicker.current.contains(event.target)) {
      handleClose()
    }
  }

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

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

  const savedColorsToolbar = savedColors
    ? renderSavedColors(onChange, savedColors)
    : null

  return (
    <div
      className={`${position} z-10`}
      ref={colorPicker}
      style={{ width: "200px" }}
      {...props}
    >
      {active ? (
        <div
          data-active={active}
          className={cx(
            "rounded absolute shadow w-full p-3 border border-gray-200 mt-2 z-10",
            {
              "bg-white": variant !== "dark",
              "": variant == "dark",
              block: active,
              hidden: !active,
            }
          )}
          style={{
            width: "200px",
            ...(variant === "dark" ? { background: "rgb(64, 78, 92)" } : {}),
          }}
        >
          {hexInput && (
            <div className={hexInputClasses}>
              <div
                className={
                  "rounded-sm overflow-hidden ml-2 flex-none h-6 w-6" +
                  swatchClass
                }
              >
                <Swatch color={hex} />
              </div>
              <ColorPickerInputGroup
                variant={variant}
                color={formatColor(hex)}
                onChange={handleChange}
              />
            </div>
          )}
          <div className="flex w-full">
            <div
              className="rounded overflow-hidden flex-auto relative mr-2"
              style={{ height: "160px" }}
            >
              <Saturation
                {...props}
                oldHue={oldHue}
                hsl={hsl}
                onChange={handleChange}
              />
            </div>
            <div className="grid grid-rows-6 w-6">
              {transparency && (
                <div
                  className="rounded overflow-hidden flex-auto row-span-1"
                  style={{ width: "24px", height: "24px" }}
                >
                  <button
                    style={{
                      width: "24px",
                      height: "24px",
                      backgroundColor: "#EEE",
                      backgroundImage: `url('data:image/svg+xml, <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" fill-opacity=".25"><rect x="50" width="50" height="50" /><rect y="50" width="50" height="50" /></svg>')`,
                      backgroundSize: "8px 8px",
                    }}
                    onClick={() => handleChange({ hex: "rgba(0, 0, 0, 0.0)" })}
                  >
                    &nbsp;
                  </button>
                </div>
              )}

              <div
                className={`rounded overflow-hidden relative row-span-${
                  transparency ? "5" : "6"
                }`}
              >
                <Hue
                  direction="vertical"
                  hsl={hsl}
                  onChange={handleChange}
                  pointer={TrianglePointer}
                />
              </div>
            </div>
          </div>
          {children && <div className="flex w-full">{children}</div>}
          {!children && savedColorsToolbar}
        </div>
      ) : null}
    </div>
  )
}

ColorPicker.propTypes = {
  active: PropTypes.bool,
  hex: PropTypes.string,
  hsl: PropTypes.object,
  oldHue: PropTypes.number,
  onChange: PropTypes.func,
  onClose: PropTypes.func,
  anchor: PropTypes.oneOf(["left", "right"]),
  variant: PropTypes.oneOf(["dark"]),
  position: PropTypes.oneOf(["absolute", "relative"]),
  standalone: PropTypes.bool,
  hexInput: PropTypes.bool,
  transparency: PropTypes.bool,
  savedColors: PropTypes.shape(SavedColorShape),
  children: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.node),
    PropTypes.node,
  ]),
}

export default CustomPicker(ColorPicker)
