import React from "react";
import { RowRenderContext, TableAddon, TableProps } from "../TableProps";
import { Button } from "../../button";
import { injectPropsIfTargetNotExisted } from "../util/inject-props-if-target-not-existed";

/**
 * `removeable` 插件用于支持表格可删除行的样式及操作。
 */
export interface RemoveableOptions<Record = any> {
  /**
   * 删除操作回调
   */
  onRemove?: (
    rowKey: string,
    context: { event: React.SyntheticEvent; record: Record }
  ) => void;

  /**
   * 列宽度，可以指定 CSS 属性或数字 (单位：px)
   * @default 46
   */
  width?: string | number;

  /**
   * 提供一个列的 `key`，将选择组件插入到一个目标列
   *
   * 默认在最前新建一列插入
   *
   * @since 2.6.9
   */
  targetColumnKey?: string;

  /**
   * 参考 Icon 组件[图标类型](/component/icon)
   *
   * @default "dismiss"
   */
  icon?: string;

  /**
   * 更改该插件的在每行的渲染内容，`element` 为默认渲染内容，`context` 中包含该行数据相关信息
   * @default x => x
   *
   * @since 2.6.9
   */
  render?: (
    element: JSX.Element,
    context: RowRenderContext<Record>
  ) => React.ReactNode;
}

const fallbackColumnKey = "__removeable_addon__";

let rowDisabled: TableProps["rowDisabled"] = null;

export function removeable({
  onRemove = () => null,
  width = 46,
  targetColumnKey,
  icon = "dismiss",
  render = x => x,
}: RemoveableOptions): TableAddon {
  return {
    getInfo: () => ({ name: "removeable" }),
    onInjectProps: props => {
      let { columns } = props;

      rowDisabled = props.rowDisabled || (() => false);

      columns = injectPropsIfTargetNotExisted(
        columns,
        targetColumnKey,
        {
          key: fallbackColumnKey,
          width,
          header: null,
          render: () => null,
        },
        true
      );
      return { ...props, columns };
    },
    onInjectColumn: previous => (
      record,
      rowKey,
      recordIndex,
      column,
      columnIndex
    ) => {
      // 不是目标列
      if (column.key !== fallbackColumnKey) {
        return previous(record, rowKey, recordIndex, column, columnIndex);
      }

      const { children: preChildren, props, ...result } = previous(
        record,
        rowKey,
        recordIndex,
        column,
        columnIndex
      );

      let children = preChildren;

      // 非表头
      if (recordIndex !== -1 && !rowDisabled(record)) {
        const element = <Button type="icon" icon={icon} htmlType="button" />;

        children = (
          <div onClick={event => onRemove(rowKey, { event, record })}>
            {render(element, {
              children: preChildren,
              record,
              rowKey,
              recordIndex,
              disabled: rowDisabled(record),
            })}
          </div>
        );
      }

      return { ...result, props, children };
    },
  };
}
