import React from "react"
import cx from "classnames"
import PropTypes from "prop-types"
import Stack from "../stack"
import Label from "../label"
import CKIcon from "../ck-icon"
import Text from "../text"

const STATES = {
  default: {
    inputClasses:
      "border border-gray-200 focus:outline-none focus:border-blue-500 focus:ring-0 hover:border-gray-300",
  },
  error: {
    inputClasses: "border-red-600 outline-red",
    icon: "alert-circle",
    iconColor: "text-red-600",
  },
  success: {
    inputClasses: "border-green-600 outline-green",
    icon: "check-circle",
    iconColor: "text-green-600",
  },
}

const Textarea = React.forwardRef(
  (
    {
      state = "default",
      className,
      disabled = false,
      style,
      resize = "none",
      info,
      message,
      label,
      ...props
    },
    ref
  ) => {
    const stateName =
      typeof state === "string" ? state : state?.name || "default"
    const stateMessage = state?.message

    className = cx(
      {
        "bg-gray-50, select-none": disabled,
      },
      className,
      getResize(resize),
      "text-sm leading-5 px-3 py-2 w-full rounded",
      STATES[stateName].inputClasses
    )

    return (
      <Stack spacing={2}>
        {label && (
          <div className="flex justify-between">
            <Label htmlFor={props.id}>{label}</Label>
            {info && (
              <Text size="sm" className="text-gray-700 leading-5">
                {info}
              </Text>
            )}
          </div>
        )}
        <textarea
          {...props}
          id={props.id}
          ref={ref}
          style={{
            ...style,
            transition: "border-color 0.3s",
            resize: resize,
          }}
          className={className}
          disabled={disabled}
        />
        {stateMessage && (
          <div className="flex items-center gap-1">
            {STATES[stateName].icon && (
              <CKIcon
                name={STATES[stateName].icon}
                className={STATES[stateName].iconColor}
              />
            )}
            <Text size="sm" className="text-black">
              {stateMessage}
            </Text>
          </div>
        )}
        {message && (
          <Text size="sm" className="text-gray-700 leading-5">
            {message}
          </Text>
        )}
      </Stack>
    )
  }
)

function getResize(resize) {
  switch (resize) {
    case "none":
      return "resize-none"
    case "both":
      return "resize"
    case "vertical":
      return "resize-y"
    case "horizontal":
      return "resize-x"
    default:
      return "resize-none"
  }
}

Textarea.propTypes = {
  /**
   * State for the Textarea can be one of the following: "default", "error", or "success". It can also be an object with the following properties: `name` and `message`.
   */
  state: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
  className: PropTypes.string,
  id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  style: PropTypes.object,
  disabled: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
  resize: PropTypes.string,
  rows: PropTypes.number,
  placeholder: PropTypes.string,
  onChange: PropTypes.func,
  value: PropTypes.string,
  /**
   * Text (or an element) placed below the textarea box on the left.
   */
  message: PropTypes.string,
  label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
  /**
   * Text (or an element) placed on the right side of the label.
   */
  info: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
}

export default Textarea
