import React from "react";
import classNames from "classnames";
import { Tooltip } from "../tooltip";
import { Icon } from "../icon";
import { StyledProps, Omit } from "../_type";
import { forwardRefWithStatics } from "../_util/forward-ref-with-statics";
import { useConfig } from "../_util/config-context";

/**
 * Button 组件支持的属性。
 *
 * 除表格中列出的属性外，支持透传原生 `<button>` 标签支持的属性。
 */
export interface ButtonProps
  extends StyledProps,
    Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "type"> {
  /**
   * 按钮类型
   *
   *   - `primary` 蓝色主要按钮
   *   - `weak` 白色按钮，默认
   *   - `pay` 橙色按钮，用于支付类操作
   *   - `error` 错误按钮，用于错误/警告类操作
   *   - `text` 文本按钮，显示为普通文本效果
   *   - `link` 连接按钮，显示为超链接效果
   *   - `icon` 图标按钮，显示为单个图标
   *
   * @default "weak"
   */
  type?: "primary" | "weak" | "pay" | "error" | "text" | "link" | "icon";

  /**
   * 原生 `<button>` 标签的 `type` 属性
   */
  htmlType?: React.ButtonHTMLAttributes<HTMLButtonElement>["type"];

  /**
   * 显示为图标按钮，传入的 `icon` 表示图标类型
   *
   * __注意__：如果已经传入 `icon`，则会忽略 `children` 属性
   */
  icon?: string;

  /**
   * 设置按钮为禁用状态
   *
   * 禁用状态下，不会响应 `onClick` 回调
   * */
  disabled?: boolean;

  /**
   * 设置按钮为加载状态
   */
  loading?: boolean;

  /**
   * 点击回调函数
   */
  onClick?: (e?: React.MouseEvent) => void;

  /**
   * 为按钮添加 Tooltip 说明，详细用法请参考 [Tooltip](/component/tooltip) 组件
   */
  tooltip?: React.ReactNode;
}

export const Button = forwardRefWithStatics(
  (props: ButtonProps, ref: React.Ref<HTMLButtonElement>) => {
    const {
      disabled,
      icon,
      loading: _loading,
      type: _type,
      className,
      style,
      onClick,
      children,
      tooltip,
      htmlType,
      ...buttonProps
    } = props;

    const { classPrefix } = useConfig();

    let [loading, type] = [_loading, _type];

    // 指定了图标的话，
    if (!type) {
      type = "weak";
    }

    if (icon) {
      type = "icon";
    }

    // 只有下面三种类型的按钮支持 loading
    if (
      ["primary", "weak", "pay", "error"].indexOf(type) === -1 &&
      typeof loading !== "undefined"
    ) {
      loading = false;
    }

    // 计算类名
    const btnClassName = `${classPrefix}-btn`;
    const classList: (string | object)[] = [`${classPrefix}-btn`];

    // 类型类名
    if (type !== "primary") {
      classList.push(`${btnClassName}--${type}`);
    }

    // 状态类名
    classList.push({
      "is-disabled": disabled,
      "is-loading": loading,
    });

    // 用户自定义类名
    if (className) {
      classList.push(className);
    }

    /* eslint-disable react/button-has-type */
    let button: JSX.Element = (
      <button
        ref={ref}
        className={classNames(...classList)}
        onClick={(!disabled && !loading && onClick) || null}
        style={style || {}}
        type={htmlType}
        disabled={disabled}
        {...buttonProps}
      >
        {loading && <Icon type="loading" />}
        {icon ? <Icon type={icon} /> : children}
      </button>
    );
    /* eslint-enable react/button-has-type */

    if (tooltip) {
      button = <Tooltip title={tooltip}>{button}</Tooltip>;
    }

    return button;
  },
  {
    defaultLabelAlign: "middle",
  }
);

Button.displayName = "Button";
