import React from "react";
import { useClickAway } from "use-click-away";
import { FormElement } from "../formElement";
import { Input } from "../Input";
import { Button, ButtonProps } from "../../Button";
import PropTypes from "prop-types";
import { makeParserPair } from "./formatter";
import styling from "@devcake/styling";
import colors from "../../Button/colors";
import { Dropdown } from "./dropdown";
import { Icon } from "../../Icon";

styling.link("components.dateinput.invalid", "components.form.invalid");
styling.link("components.dateinput.disabled", "components.form.disabled");
styling.link("components.dateinput.icons.calendar", "components.icons.calendar");
styling.setDefault("components.dateinput.valid", "");
styling.setDefault("components.dateinput.inset", "rounded-l-none");

export type DateInputProps = FormElement<Date> & {
  buttonType?: ButtonProps["type"];
  color?: ButtonProps["color"];
  format?: Intl.DateTimeFormatOptions;
  locale?: string;
}

export const DateInput: React.FunctionComponent<DateInputProps> = (props) => {
    const { buttonType, color, className, disabled, format, label, locale, nullable, placeholder } = props;
    const onChange = "onChange" in props ? props.onChange : () => null;
    const value = "value" in props ? props.value : null;

    const [innerValue, setInnerValue] = React.useState("");
    const [isValid, setIsValid] = React.useState(true);
    const [showPicker, setShowPicker] = React.useState(false);

    const ref = React.createRef<HTMLDivElement>();
    useClickAway(ref, () => setShowPicker(false));

    const [formatter, parser] = React.useMemo(() => makeParserPair(locale, format), [locale, format]);
    React.useEffect(() => setInnerValue(formatter(value)), [value, formatter]);
    React.useEffect(() => {
      const parsed = parser(innerValue);
      if (nullable && innerValue === "") {
        setIsValid(true);
        onChange(null);
      } else if (parsed === false) {
        setIsValid(false);
      } else {
        setIsValid(true);
        onChange(parsed);
      }
    }, [innerValue]);

    return (
      <Input
        className={[
          className,
          styling.get(`components.dateinput.${isValid ? "valid" : "invalid"}`)
        ].join(" ")}
        disabled={disabled}
        label={label}
        nullable={nullable}
        value={innerValue}
        onChange={val => setInnerValue(val || "")}
        placeholder={placeholder}
        inset={(<div ref={ref}>
          <Button
            color={color}
            type={buttonType}
            className={[
              disabled ? styling.get("components.dateinput.disabled") : "",
              styling.get("components.dateinput.inset")
            ].join(" ")}
            onClick={disabled ? null : () => setShowPicker(!showPicker)}
          >
            <Icon icon={styling.get("components.dateinput.icons.calendar")} className="w-5 h-5" />
          </Button>
          {showPicker && <Dropdown
            color={color}
            value={parser(innerValue) || new Date()}
            locale={locale}
            set={date => {
              setInnerValue(formatter(date));
              setShowPicker(false);
            }}
          />}
        </div>)}
      />
    );
  }
;

DateInput.propTypes = {
  buttonType: PropTypes.oneOf(["primary", "secondary", "tertiary"]),
  color: PropTypes.oneOf(["amber", "blue", "cyan", "emerald", "fuchsia", "gray", "green", "indigo", "lightBlue", "lime", "orange", "pink", "purple", "red", "rose", "teal", "violet", "yellow"]),
  className: PropTypes.string,
  disabled: PropTypes.bool,
  label: PropTypes.node,
  locale: PropTypes.string,
  nullable: PropTypes.bool,
  placeholder: PropTypes.string,
  onChange: PropTypes.func,
  value: PropTypes.instanceOf(Date)
};
DateInput.defaultProps = {
  buttonType: "secondary",
  color: "indigo",
  disabled: false,
  locale: "nl-NL",
  nullable: true
};