import React from "react";
import PropTypes from "prop-types";
import { FormElement } from "../formElement";
import styling from "@devcake/styling";
import { Label } from "../Label";
import { Icon } from "../../Icon";

styling.setDefault("components.toggle.disabled.color-bg", "bg-gray-200");
styling.setDefault("components.toggle.disabled.color-text", "text-gray-400");
styling.setDefault("components.toggle.active.color-bg", "bg-green-300");
styling.setDefault("components.toggle.active.color-text", "text-green-500");
styling.link("components.toggle.active.icon", "components.icons.check");
styling.setDefault("components.toggle.active.translate", "translate-x-5");
styling.setDefault("components.toggle.inactive.color-bg", "bg-red-200");
styling.setDefault("components.toggle.inactive.color-text", "text-red-400");
styling.link("components.toggle.inactive.icon", "components.icons.cross");
styling.setDefault("components.toggle.inactive.translate", "translate-x-0");
styling.setDefault("components.toggle.classes", "relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full  transition-colors ease-in-out duration-200 focus:outline-none");
styling.setDefault("components.toggle.classes.disabled", "cursor-not-allowed");
styling.setDefault("components.toggle.classes.enabled", "cursor-pointer");
styling.setDefault("components.toggle.classes.focus", "focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500");
styling.setDefault("components.toggle.container.icon-inner", "h-3 w-3 bg-white");
styling.setDefault("components.toggle.container.icon-outer", "ease-in-out duration-200 absolute inset-0 h-full w-full flex items-center justify-center transition-opacity");
styling.setDefault("components.toggle.container.point", "pointer-events-none relative inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200");

export type ToggleProps = FormElement<boolean>;

export const Toggle: React.FunctionComponent<ToggleProps> = ({ className, disabled, label, onChange, value }) => {
  const [active, setActive] = React.useState(value);
  React.useEffect(() => setActive(value), [setActive, value]);

  return <>
    {label && <Label className="inline-block">{label}</Label>}
    <button
      className={[
        styling.get("components.toggle.classes"),
        styling.get(`components.toggle.classes.${disabled ? "disabled" : "enabled"}`),
        disabled ? "" : styling.get("components.toggle.classes.focus"),
        `${styling.get(`components.toggle.${disabled ? "disabled" : active ? "active" : "inactive"}.color-bg`)}`,
        className
      ].join(" ")}
      onClick={disabled ? null : () => {
        setActive(!active);
        onChange(!active);
      }}
    >
      <div
        className={[
          styling.get("components.toggle.container.point"),
          styling.get(`components.toggle.${active ? "active" : "inactive"}.translate`)
        ].join(" ")}
      >
        {styling.get("components.toggle.inactive.icon") && (
          <div
            className={[
              styling.get("components.toggle.container.icon-outer"),
              active ? "opacity-0" : "opacity-100"
            ].join(" ")}
          >
            <Icon
              icon={styling.get("components.toggle.inactive.icon")}
              className={[
                styling.get("components.toggle.container.icon-inner"),
                styling.get(`components.toggle.${disabled ? "disabled" : "inactive"}.color-text`)
              ].join(" ")}
            />
          </div>
        )}
        {styling.get("components.toggle.active.icon") && (
          <div
            className={[
              styling.get("components.toggle.container.icon-outer"),
              active ? "opacity-100" : "opacity-0"
            ].join(" ")}
          >
            <Icon
              icon={styling.get("components.toggle.active.icon")}
              className={[
                styling.get("components.toggle.container.icon-inner"),
                styling.get(`components.toggle.${disabled ? "disabled" : "active"}.color-text`)
              ].join(" ")}
            />
          </div>
        )}
      </div>
    </button>
  </>;
};

Toggle.propTypes = {
  className: PropTypes.string,
  disabled: PropTypes.bool,
  label: PropTypes.string,
  value: PropTypes.bool
};
Toggle.defaultProps = {
  disabled: false,
  onChange: () => null,
  value: false
};