import React from "react";
import { TableAddon } from "../TableProps";
import { StatusTip, StatusTipProps } from "../../tips";
import { useTranslation } from "../../i18n";
import { FetcherState, QueryState, Omit } from "../../_type";

/**
 * `autotip` 插件用于给定表格数据的状态，自动提供合适的 `topTip` 来显示该状态。
 */
export interface AutoTipOptions extends Omit<StatusTipProps, "status"> {
  /**
   * 数据是否在加载中
   */
  isLoading?: boolean;

  /**
   * 数据加载是否异常
   */
  isError?: boolean;

  /**
   * 数据是否被筛选
   */
  isFound?: boolean;

  /**
   * 用于没有传入 `foundText` 时，默认筛选文案的生成
   *
   * 如果提供了 `foundKeyword`，默认筛选文案将会使用
   */
  foundKeyword?: string;

  /**
   * `foundKeyword` 最长展示长度，超出部分将用 '...' 代替
   *
   * @default 20
   */
  foundKeywordMaxLength?: number;

  /**
   * 用于没有传入 `foundText` 时，默认筛选文案的生成
   *
   * 如果提供了 `foundCount`，默认筛选文案将会使用，不提供时将使用当前传入的记录条数
   *
   * `foundCount` 为 0 时将使用空数据提示文案
   */
  foundCount?: number;

  /**
   * 隐藏图标
   */
  hideIcon?: boolean;
}

/**
 * 给定表格数据的状态，自动提供合适的 topTip 来显示该状态
 */
export function autotip(options: AutoTipOptions): TableAddon {
  const {
    isFound,
    isLoading,
    isError,
    foundText,
    emptyText,
    foundKeyword,
    foundCount,
    foundKeywordMaxLength = 20,
    ...tipProps
  } = options;

  return {
    getInfo: () => ({ name: "autotip" }),
    onInjectProps(props) {
      // 根据数据情况、加载情况、关键字情况使用不同的 Tips 渲染
      let topTip: React.ReactNode = null;
      let tipStatus: StatusTipProps["status"] = null;

      const records = props.records || [];
      const recordCount =
        typeof foundCount === "undefined" ? records.length : foundCount;

      if (isLoading) {
        tipStatus = "loading";
      } else if (isError) {
        tipStatus = "error";
      } else if (isFound) {
        tipStatus = "found";
      } else if (recordCount === 0) {
        tipStatus = "empty";
      }

      if (tipStatus) {
        topTip = (
          <DefaultFoundTextProvider
            foundText={foundText}
            foundKeyword={foundKeyword}
            recordCount={recordCount}
            foundKeywordMaxLength={foundKeywordMaxLength}
          >
            {tableFoundText => (
              <StatusTip
                status={tipStatus}
                foundText={tableFoundText}
                emptyText={emptyText}
                {...tipProps}
              />
            )}
          </DefaultFoundTextProvider>
        );
      }

      return {
        ...props,
        topTip,
      };
    },
  };
}

function DefaultFoundTextProvider({
  foundText,
  foundKeyword,
  recordCount,
  foundKeywordMaxLength,
  children,
}: {
  foundText: React.ReactNode;
  foundKeyword: string;
  recordCount: number;
  foundKeywordMaxLength: number;
  children?: (text: React.ReactNode) => any;
}) {
  const t = useTranslation();

  if (foundText) {
    return children(foundText);
  }
  if (foundKeyword) {
    if (recordCount === 0) {
      return children(t.foundNothingWithKeyword(foundKeyword));
    }
    // eslint-disable-next-line no-param-reassign
    foundKeyword =
      foundKeyword.slice(0, foundKeywordMaxLength) +
      (foundKeyword.length > foundKeywordMaxLength ? "..." : "");
    return children(t.foundManyTextWithKeyword(foundKeyword, recordCount));
  }
  return children(t.foundManyText(recordCount));
}

export interface LegacySmartTipState {
  fetcher: FetcherState<any>;
  query?: QueryState<any>;
  onClearSearch?: () => void;
  onRetry?: () => void;
  emptyTips?: React.ReactNode;
  enableLoading?: boolean;
}

/**
 * 从 Tea v1 的 SmartTips.render() 参数构造成新的 autotip 插件
 */
autotip.fromLegacyState = ({
  enableLoading,
  fetcher,
  query,
  onClearSearch,
  onRetry,
  emptyTips,
}: LegacySmartTipState) => {
  const search = query && query.search;
  return autotip({
    isLoading: (enableLoading !== false || search) && fetcher.loading,
    isError: fetcher.fetchState === "Failed",
    foundKeyword: search,
    onClear: onClearSearch,
    onRetry,
    emptyText: emptyTips,
  });
};
