import React, { ReactNode } from "react";

import "./Button.css";
import { getCN, isDevaice, getClassName } from "../utils";

import ButtonTouch, { IButtonTouch } from "../ButtonTouch/ButtonTouch";

import { IconRightArrow } from "../../svg_icons/IconRightArrow";
import { IconSpinner } from "../../svg_icons/IconSpinner";

export interface IButton extends React.HTMLAttributes<HTMLDivElement> {
  before?: React.ReactNode;
  after?: React.ReactNode;
  stretched?: boolean;
  border?: `default` | `primary` | string;
  wide?: boolean;
  size?: `s` | `m` | `l` | `low` | string;
  mode?: `primary` | `secondary` | `outline` | `tertiary`;
  disabled?: boolean;
  appearance?: "warning" | "primary" | "accent" | "positive" | "negative" | "neutral";
  align?: "left" | "center" | "right";
  selected?: boolean | null;
  expandable?: boolean;

  touchMode?: IButtonTouch["mode"];
  stopPropagation?: IButtonTouch["stopPropagation"];
  preventDefault?: IButtonTouch["preventDefault"];
  onClick?: IButtonTouch["onClick"];
  href?: IButtonTouch["href"];
  target?: IButtonTouch["target"];
  loading?: boolean;
  loadingIcon?: React.ReactNode;
  rootRef?: React.LegacyRef<HTMLDivElement> | undefined;
  className?: string | undefined
}

function Button({
  children,
  before,
  after,
  stretched = false,
  border = "auto",
  wide = false,
  size = "s",
  mode = "primary",
  disabled = false,
  appearance = `primary`,
  align = "center",
  selected = null,
  expandable = false,
  touchMode,
  stopPropagation = true,
  preventDefault = false,
  onClick,
  href,
  target,
  loading = false,
  loadingIcon,
  rootRef,
  className,
  ...props
}: IButton) {
  if (selected) {
    appearance = `positive`;
    mode = "secondary";
  }
  if (selected == false) {
    appearance = `neutral`;
    mode = "tertiary";
  }

  if (border == `auto`) border = isDevaice(`mobile`) ? `default` : `primary`;

  const _onClick = (e: any) => {
    if (loading) return;
    if (onClick) onClick(e);
  };

  return (
    <div
      ref={rootRef}
      className={getClassName(`Button`)}
      {...props}
      /* data-* */
      data-stretched={stretched}
      data-selected={selected}
    >
      <ButtonTouch
        preventDefault={preventDefault}
        stopPropagation={stopPropagation}
        mode={touchMode}
        onClick={_onClick}
        stretched={stretched}
        disabled={disabled}
        href={href}
        target={target}
      >
        <div
          className={getClassName(`Button__in`, className)}
          /* data-* */
          data-appearance={appearance}
          data-mode={mode}
          data-border={border}
          data-wide={wide}
          data-size={size}
        >
          <div data-align={align} className={getClassName(`Button--align`)}>
            {!loading && before && (
              <div className={getClassName(`Button__before`)}>{before}</div>
            )}
            {!loading && children && (
              <div className={getClassName(`Button__children`)}>{children}</div>
            )}
            {!loading && after && (
              <div className={getClassName(`Button__after`)}>{after}</div>
            )}
            {loading && (
              <div className={getClassName(`Button__loading`)}>
                {!loadingIcon ? <IconSpinner
                  width={
                    size == `s` ? 20 : size == `m` ? 24 : size == `l` ? 28 : 20
                  }
                  height={
                    size == `s` ? 20 : size == `m` ? 24 : size == `l` ? 28 : 20
                  }
                /> : loadingIcon}
              </div>
            )}
          </div>
          {expandable && (
            <span className={getClassName(`Button__expandable`)}>
              <IconRightArrow
                width={
                  size == `s` ? 20 : size == `m` ? 24 : size == `l` ? 28 : 20
                }
                height={
                  size == `s` ? 20 : size == `m` ? 24 : size == `l` ? 28 : 20
                }
              />
            </span>
          )}
        </div>
      </ButtonTouch>
    </div>
  );
}
export default Button;
