import React, { useState, useEffect, useRef, createRef } from "react";

import { getClassName, randomId, renderProps } from "../utils";
import "./ButtonTouch.css";

export type IButtonTouch = {
  children?: React.ReactNode,
  componentName?: string,
  modeButtonTouch?: string,
  mode?: string,
  modeActive?: string,
  href?: string,
  target?: string,
  disabled?: boolean,
  hover?: boolean,
  ref?: any,
  ripple?: boolean,
  stopPropagation?: boolean,
  preventDefault?: boolean,
  stretched?: boolean,
  clickable?: boolean,
  onClick?: React.MouseEventHandler | undefined;
  [x: string]: any;
};

function ButtonTouch({
  children,
  componentName,
  mode = `default`,
  modeActive = `default`,
  ripple,
  href,
  target,
  onClick,
  disabled = false,
  hover = true,
  stretched = false,
  ref = createRef(),
  stopPropagation = false,
  preventDefault = false,
  clickable = false,
  ...props
}: IButtonTouch) {
  const Component = href ? `a` : `button`;
  const childrenRed = useRef<HTMLInputElement | null>(null);
  const [button_id, setbutton_id] = useState(
    randomId(props.id, `button_touch`)
  );
  const [rippleElements, setRippleElements] = useState<JSX.Element[]>([]);

  const [is_mobile_hover, setMobileHover] = useState(false);
  const [is_hover, setHover] = useState(false);
  const [is_active, setActive] = useState(false);
  const [time_is_active, setTime_is_active] = useState(0);

  if (href) clickable = true;
  if (onClick) clickable = true;
  if (!clickable) {
    stopPropagation = false;
    preventDefault = false;
  }


  /* Ripple эффект */
  function onRippleClick(
    event: React.MouseEvent<HTMLButtonElement, MouseEvent>
  ) {
    var rect = event.currentTarget.getBoundingClientRect();

    const d = Math.max(
      event.currentTarget.clientWidth,
      event.currentTarget.clientHeight
    );
    const left = event.clientX - rect.left - d / 2 + "px";
    const top = event.clientY - rect.top - d / 2 + "px";
    const rippleElement = newRippleElement(d, left, top);

    setRippleElements([...rippleElements, rippleElement]);
  }

  const newRippleElement = (d: number, left: string, top: string) => {
    var key_id = Math.random();
    return (
      <div
        id="ripplik"
        key={key_id}
        className={`MYUI-ripple_in`}
        style={{ width: d, height: d, left, top }}
        onAnimationEnd={() => onAnimationEnd(key_id.toString())}
      ></div>
    );
  }

  function onAnimationEnd(key: string) {
    setRippleElements((rippleElements: any) =>
      rippleElements.filter((element: any) => element.key !== key)
    );
  }



  const _onClick = (e: any) => {
    stopPropagation && e.stopPropagation();
    preventDefault && e.preventDefault();
    if (clickable) {
      if (ripple) onRippleClick(e);
    }
    if (onClick) onClick(e);
  };

  const onMouseUp_Event = (e: any) => {
    if (clickable) {
      if (Date.now() - time_is_active < 400) {
        setTimeout(() => setActive(false), 200);
      } else setActive(false);
      if (props.onMouseUp) props.onMouseUp(e);
    }
  };

  const onMouseDown_Event = (e: any) => {
    stopPropagation && e.stopPropagation();
    if (clickable) {
      setActive(true);
      setTime_is_active(Date.now());
      if (props.onMouseDown) props.onMouseDown(e);
    }
  };

  const onTouchEnd = (e: any) => {
    setActive(false);
    if (props.onTouchEnd) props.onTouchEnd(e);
  };

  const onMouseMove = (e: any) => {
    setActive(false);

    if (props.onMouseMove) props.onMouseMove(e);
  };

  const onTouchStart = (e: any) => {
    setMobileHover(true);
    if (props.onTouchStart) props.onTouchStart(e);
  };

  const onMouseHover = (e: any) => {
    stopPropagation && e.stopPropagation();
    if (!is_mobile_hover && clickable) {
      if (e.type == "mouseover") {
        setHover(true);
      } else if (e.type == "mouseout") {
        setHover(false);
      }
    }
  };

  useEffect(() => {
    if (ripple) {
      if (childrenRed.current) {
        if (childrenRed.current.children[0]) {
          const borderRadius = getComputedStyle(
            childrenRed.current.children[0]
          ).borderRadius;
          childrenRed.current.style.borderRadius = borderRadius;
        }
      }
    }
  }, [ripple]);

  return (
    <Component
      ref={ref}
      disabled={disabled}
      className={getClassName(`ButtonTouch`, componentName)}
      onMouseOver={onMouseHover}
      onMouseOut={onMouseHover}
      onMouseDown={onMouseDown_Event}
      onMouseUp={onMouseUp_Event}
      onTouchEnd={onTouchEnd}
      onMouseMove={onMouseMove}
      onTouchStart={onTouchStart}
      onClick={(e: any) => _onClick(e)}
      href={href}
      target={target}
      {...renderProps(props, `button`)}
      /* data-* */
      data-disabled={disabled}
      data-stretched={stretched}
      data-hover_mode={mode}
      data-hover_enabled={is_hover}
      data-active_mode={!ripple && is_active && modeActive}
      data-clickable={clickable}
    >
      <div
        id={button_id}
        ref={childrenRed}
        className="MYUI-ButtonTouch--schildren"
      >
        {children}
        {ripple && (
          <span
            id="ripple_button"
            data-ripple={onClick ? ripple : `null`}
            className={getClassName(`MYUI-ripple`)}
          >
            {rippleElements}
          </span>
        )}
      </div>
    </Component>
  );
}

/*
ripple
className={getClassName([
              onClick && ripple
                ? `MYUI-ripple`
                : ripple && mode == `background`
                ? `MYUI-ripple--background`
                : `MYUI-ripple`,
            ])}
*/
export default ButtonTouch;
