import { ProColumns, ProTableProps } from '@ant-design/pro-table';
import { TableProps as AntTableProps } from 'antd/es/table';
import { TableRowSelection } from 'antd/es/table/interface';
import { BaseEntity } from 'nsn-entity';
import { NConnectProps, NDispatchType, NLoading } from 'nsn-model-type';
import { Component, CSSProperties, Key, ReactNode } from 'react';
import { OptionColumnMenu } from './OptionColumnMenu';
import { TableState } from './State';
import { TableOptionColumnProps } from './TableOptionColumnProps';
import { TableStatusColumnProps } from './TableStatusColumnProps';
import { TableTreeProps } from './TableTreeProps';
import { ToolbarProps } from './ToolbarProps';

type MountedFunction<T extends BaseEntity, DT extends string, S = {}> = (comp: Component<TableProps<T, DT, S>, TableState<T, S>>) => void;

//
type TableEditFormProps<T extends BaseEntity, DT extends string, S = {}> = {

  /** 
   * 在编辑数据之前，先处理数据内容（应对后端返回数据，与前端渲染数据显示，不一致而导致的bug）
   * 例如：后端返回 true/false，
   * 而前端需要显示：1/0，
   * 如果直接回填编辑表单，会导致 BUG：Received `false` for a non-boolean attribute `text`.
   * */
  postRecord?: (record: T) => any,

  /** 编辑表单提交之前执行，返回修改过的 params */
  beforeSubmit?: (params: T, comp: Component<TableProps<T, DT, S>, TableState<T, S>>) => any;

  /** 当表单字段没有填写，提交的默认值 */
  defaultValues?: Partial<T>,
}
  & Pick<TableTreeProps<DT>, 'dtype'>

/**
 * 没有自定义 DispatchType 的表格属性
 */
export type TablePropsPure<T extends BaseEntity, S = {}> = {
} & TableProps<T, '_', S>;

/**
 * 带有自定义 DispatchType 的表格属性
 */
export type TableProps<T extends BaseEntity, DT extends string, S = {}> = {

  loading: NLoading;

  /** 页面中的其他内容 */
  children?: ReactNode | ((comp: Component<TableProps<T, DT, S>, TableState<T, S>>) => ReactNode);

  /** 组件加载完成之后执行的回调 */
  mounted?: MountedFunction<T, DT, S> | Array<MountedFunction<T, DT, S>>;

  /** 表格配置 */
  table: {

    /** 
     * 是否表格树（表格树不会显示分页条，并以 999999 分页大小来查询分页数据）
     * @type NDispatchType | 更新状态数据的同步动作
     * @type DT | 自定义更新状态数据的同步动作
     * @type Array | 当前展开的行
     * @type object | NDispatchType + Array
    */
    tree?: NDispatchType<DT> | Array<Key> | TableTreeProps<DT>;

    /** ProTable 样式 */
    style?: CSSProperties;

    /** ProTable 样式 */
    className?: string;

    /** 分页查询 */
    page: NDispatchType<DT> | {
      /** 查询之前回调，获取查询参数 */
      before?: () => { [K: string]: any };

      /** 查询分页数据的异步操作 */
      dtype: NDispatchType<DT>;

      /** 查询之后回调 */
      after?: (data: Array<T>) => void;

      /** 在数据渲染之前，进行数据变形 */
      transform?: (data: Array<T>) => Array<any>;
    };

    /** 行主键。默认 “id” */
    rowKey?: string;

    /** 空值显示的字符。默认 “-” */
    emptyText?: string;

    /** 数据列 */
    columns: Array<ProColumns<T>> | ((comp: Component<TableProps<T, DT, S>, TableState<T, S>>) => Array<ProColumns<T>>);

    /** 数据列配置 */
    columnsProps?: {

      /** 
       * 序号列属性
       * @type false | 不显示
       * @type object | 透传到ProColumns
      */
      index?: false | Pick<ProColumns<T>, 'width' | 'title'>;

      /** 
       * 选框列属性
       * @type false | 不显示
       * @type string | 类型，默认 checkbox
       * @type object | 透传到ProColumns
      */
      select?: false | 'checkbox' | 'radio'
      | (Pick<ProColumns<T>, 'width' | 'title'> & Pick<TableRowSelection<T>, 'getCheckboxProps'>);

      /** 
       * 状态列属性
       * @type string | 变更状态的异步动作
       * @type object | 透传到ProColumns
      */
      status?: TableStatusColumnProps<DT>['dtype'] | TableStatusColumnProps<DT>;

      /** 
       * 操作列属性
       * @type false | 不显示
       * @type Array | 菜单项
       * @type object | 菜单项以及其他配置
      */
      option?: false | Array<OptionColumnMenu<T, DT, S>> | TableOptionColumnProps<T, DT, S>;

      /** 固定操作列 */
      fixOption?: true;

      /** 固定选择列 */
      fixSelect?: true;

      /** 固定序号列 */
      fixIndex?: true;
    },
  }
  & Pick<AntTableProps<T>, 'pagination'>
  & Pick<ProTableProps<T, T>, 'search' | 'scroll'>


  /** 
   * 编辑表单属性
   * @type false | 不显示
   * @type string | 数据保存的异步动作
   * @type object | 数据保存的异步动作以及其他配置
  */
  editForm?: false | TableEditFormProps<T, DT, S>['dtype'] | TableEditFormProps<T, DT, S>;

  /** 工具栏 */
  toolbar?: false | ToolbarProps<T, DT, S> | ((comp: Component<TableProps<T, DT, S>, TableState<T, S>>) => ToolbarProps<T, DT, S>),

}
  & Partial<NConnectProps>
