import React from 'react';
import { ClassNamesFn } from '../../theme';
import { IColumn, IRow, ITableStore } from '../../store/table';
import { SchemaNode, Action } from '../../types';
import { TableBody } from './TableBody';
import { LocaleProps } from '../../locale';
import { observer } from 'mobx-react';
import { ActionSchema } from '../Action';
import ItemActionsWrapper from './ItemActionsWrapper';
import Tooltip from 'antd/lib/tooltip';
import { Icon } from '../../components/icons';

export interface TableContentProps extends LocaleProps {
  className?: string;
  tableClassName?: string;
  classnames: ClassNamesFn;
  columns: Array<IColumn>;
  columnsGroup: Array<{
    label: string;
    index: number;
    colSpan: number;
    rowSpan: number;
    has: Array<any>;
  }>;
  rows: Array<IRow>;
  placeholder?: string;
  render: (region: string, node: SchemaNode, props?: any) => JSX.Element;
  onMouseMove: (event: React.MouseEvent) => void;
  onScroll: (event: React.UIEvent) => void;
  tableRef: (table?: HTMLTableElement | null) => void;
  renderHeadCell: (column: IColumn, props?: any) => JSX.Element;
  renderCell: (
    region: string,
    column: IColumn,
    item: IRow,
    props: any
  ) => React.ReactNode;
  onCheck: (item: IRow, value: boolean, shift?: boolean) => void;
  onQuickChange?: (
    item: IRow,
    values: object,
    saveImmediately?: boolean | any,
    savePristine?: boolean
  ) => void;
  footable?: boolean;
  footableColumns: Array<IColumn>;
  checkOnItemClick?: boolean;
  buildItemProps?: (item: IRow, index: number) => any;
  onAction?: (e: React.UIEvent<any> | null, action: Action | ActionSchema, ctx: object) => void;
  rowClassNameExpr?: string;
  rowClassName?: string;
  data?: any;
  prefixRow?: Array<any>;
  affixRow?: Array<any>;
  itemAction?: ActionSchema;
  itemActions?: Array<Action>;
  store: ITableStore;
  // Jay
  autoFillHeight?: boolean;
  position: [rowIndex: number, colName: string];
  primaryField: string;
  contextMenuVisible: boolean;
  onContextMenuVisibleChange: (visible: boolean) => void;
  infinteLoad: any;
  onLoadMore: () => void;
  loadHasMore: any;
  loading: boolean;
  tableType?: string;
  handleMultiColumnSort: (name: string, isMultiple?: boolean, columnMapValue?: object) => void;
  tableRotate?: boolean;
  classPrefix: string,
  setBorder?: boolean,
  rowItems: any[],//字段表格数据
  tableName?: string
}

@observer
export class TableContent extends React.Component<TableContentProps, object> {
  tableWindowRef: React.RefObject<any | null> = React.createRef();
  renderItemActions() {
    const { itemActions, render, store, classnames: cx } = this.props;
    const finalActions = Array.isArray(itemActions)
      ? itemActions.filter(action => !action.hiddenOnHover)
      : [];

    if (!finalActions.length) {
      return null;
    }

    return (
      <ItemActionsWrapper store={store} classnames={cx}>
        <div className={cx('Table-itemActions')}>
          {finalActions.map((action, index) =>
            render(
              `itemAction/${index}`,
              {
                ...(action as any),
                isMenuItem: true
              },
              {
                key: index,
                item: store.hoverRow,
                data: store.hoverRow!.locals,
                rowIndex: store.hoverRow!.index
              }
            )
          )}
        </div>
      </ItemActionsWrapper>
    );
  }

  handleMouseLeave = (e: any) => {
    e?.stopPropagation();
    const store = this.props.store;
    const row = store.hoverRow;
    row?.setIsHover(false);
  }

  renderSortCell(item: any, index: number, classNames: string) {
    const { store, render, classnames: cx, handleMultiColumnSort } = this.props
    const column: IColumn = item.has[0]
    const order = store.getOrderColumn?.(column.name ?? '')?.order
    const title = order === 'asc' ? '点击降序' : order === 'desc' ? '点击取消排序' : '点击升序'
    const hasData = store.data.items?.length > 0
    const stickyWidths = store.stickyWidths

    return (
      <Tooltip
        title={title}
        color='white'
        placement='top'
        overlayInnerStyle={{ color: 'black' }}
        overlayStyle={{ visibility: column.sortable && hasData ? 'visible' : 'hidden' }}>
        <th
          className={cx('TableCell--sortable', classNames)}
          key={index}
          data-index={item.index}
          colSpan={item.colSpan}
          rowSpan={item.rowSpan}
          onClick={(e) => handleMultiColumnSort(item.has[0].name, e.ctrlKey, column.map)}
          // Aug
          style={{
            cursor: 'pointer',
            position: "sticky",
            left: item.fixed === 'left' && stickyWidths?.[`${index}`],
            right: item.fixed === 'right' && stickyWidths?.[`${index}`],
            zIndex: item.fixed && 2,
            top: 0,
            borderLeft: item.has[0].type === 'operation' ? '1px solid #eceff8' : 'none'
          }}
        >
          {render('tpl', item.label)}
          <span
            className={cx('TableCell-sortBtn')}
          >
            <i
              className={cx(
                'TableCell-sortBtn--down',
                store.orderColumns?.has(column.name) && store.getOrderColumn?.(column.name as string)?.order === 'desc'
                  ? 'is-active'
                  : ''
              )}
            >
              <Icon icon="sort-desc" className="icon" />
            </i>
            <i
              className={cx(
                'TableCell-sortBtn--up',
                store.orderColumns?.has(column.name) && store.getOrderColumn?.(column.name as string)?.order === 'asc'
                  ? 'is-active'
                  : ''
              )}
            >
              <Icon icon="sort-asc" className="icon" />
            </i>
            <i
              className={cx(
                'TableCell-sortBtn--default',
                store.orderColumns?.has(column.name)
                  ? '' : 'is-active'
              )}
            >
            </i>
          </span>
        </th>
      </Tooltip>
    )
  }
  componentDidUpdate(prevProps: TableContentProps) {
    const { itemAction, onAction, data } = this.props;
    if (prevProps.data !== data && !data?.items?.length && itemAction) {
      onAction?.(null, itemAction, {})
    }
  }

  render() {
    const {
      placeholder,
      classnames: cx,
      render,
      className,
      columns,
      columnsGroup,
      onMouseMove,
      onScroll,
      tableRef,
      rows,
      renderHeadCell,
      renderCell,
      onCheck,
      rowClassName,
      onQuickChange,
      footable,
      footableColumns,
      checkOnItemClick,
      buildItemProps,
      onAction,
      rowClassNameExpr,
      data,
      prefixRow,
      locale,
      translate,
      itemAction,
      affixRow,
      store,
      position,
      primaryField,
      classPrefix
    } = this.props;

    const emptyWidth = this.tableWindowRef.current?.clientWidth || this.tableWindowRef.current?.closest(`.${classPrefix}Tabs-content`)?.clientWidth;
    const tableClassName = cx('Table-table', this.props.tableClassName);
    const hideHeader = columns.every(column => !column.label);
    // Jay
    const stickyWidths = store.stickyWidths
    const leftFixedColumns = store.leftFixedColumns
    const lastLeftFixedIndex = leftFixedColumns[leftFixedColumns.length - 1]?.index
    const rightFixedColumns = store.rightFixedColumns
    const firstRightFixedIndex = rightFixedColumns[0]?.index
    const { autoFillHeight, loading } = this.props

    return (
      <div
        onMouseMove={onMouseMove}
        ref={this.tableWindowRef}
        className={cx('Table-content', className)}
        onScroll={onScroll}
      >
        {store.hoverRow ? this.renderItemActions() : null}
        <table onMouseLeave={this.handleMouseLeave} ref={tableRef} className={tableClassName}>
          <thead>
            {columnsGroup.length ? (
              <tr>
                {columnsGroup.map((item: any, index) => {
                  if (item.has[0].type === '__checkme') {
                    return renderHeadCell(item.has[0], {
                      'data-index': item.index,
                      rowspan: item.rowSpan,
                      colspan: item.colSpan,
                      key: item.index,
                      className: item.index === lastLeftFixedIndex ? 'fixed-left-last'
                        : item.index === firstRightFixedIndex ? 'fixed-right-first' : null,
                      style: {
                        position: "sticky",
                        left: stickyWidths?.[`${index}`],
                        right: stickyWidths?.[`${index}`],
                        top: 0,
                        zIndex: 6
                      }
                    })
                  }
                  if (item.colSpan == 1 && item.has[0].sortable) {
                    return this.renderSortCell(item, item.index, `${item.index === lastLeftFixedIndex
                      ? 'fixed-left-last ' : ''} ${item.index === firstRightFixedIndex
                        ? ' fixed-right-first'
                        : ''}`)
                  }
                  return (
                    <th
                      key={index}
                      data-index={item.index}
                      colSpan={item.colSpan}
                      rowSpan={item.rowSpan}
                      // Aug
                      style={{
                        position: "sticky",
                        left: item.fixed === 'left' && stickyWidths?.[`${item.index}`],
                        right: item.fixed === 'right' && stickyWidths?.[`${item.index}`],
                        top: 0,
                        zIndex: item.fixed && 2,
                        borderLeft: item.has[0].type === 'operation' ? '1px solid #eceff8' : 'none'
                      }}
                      className={`${item.index === lastLeftFixedIndex
                        ? 'fixed-left-last ' : ''} ${item.index === firstRightFixedIndex
                          ? ' fixed-right-first'
                          : ''}`}
                    >
                      {render('tpl', item.label)}
                    </th>
                  )
                })}
              </tr>
            ) : null}
            <tr className={hideHeader ? 'fake-hide' : ''}>
              {columns.map(column =>
                columnsGroup.find(group => ~group.has.indexOf(column))?.rowSpan === 2 ? null : renderHeadCell(column, {
                  'data-index': column.index,
                  'key': column.index,
                  // Jay
                  // 'className': column.index === lastLeftFixedIndex ? 'fixed-left-last'
                  //   : column.index === firstRightFixedIndex ? 'fixed-right-first' : null,
                  "style": {
                    position: (column.fixed || autoFillHeight) && "sticky",
                    left: column.fixed === 'left' && stickyWidths?.[`${column.index}`],
                    right: column.fixed === 'right' && stickyWidths?.[`${column.index}`],
                    zIndex: autoFillHeight && column.fixed ? 4 : autoFillHeight ? 3 : column.fixed && 2,
                    top: autoFillHeight ? (columnsGroup.length ? 26 : 0) : undefined
                  },
                  'className':
                    column.index === lastLeftFixedIndex
                      ? 'fixed-left-last'
                      : column.index === firstRightFixedIndex
                        ? 'fixed-right-first'
                        : ''
                })
              )}
            </tr>
          </thead>
          {loading ? null : !rows.length ? (
            <tbody>
              <tr className={cx('Table-placeholder')}>
                <td className="empty-not-hover" colSpan={columns.length} style={{ padding: 0 }}>
                  <div style={{ width: emptyWidth, position: 'sticky', left: 0, color: '#999', fontSize: 13, textAlign: 'center' }}>{translate(placeholder || 'placeholder.noData')}</div>
                </td>
              </tr>
            </tbody >
          ) : (
            <TableBody
              tableName={this.props.tableName}
              itemAction={itemAction}
              classnames={cx}
              render={render}
              renderCell={renderCell}
              onCheck={onCheck}
              onQuickChange={onQuickChange}
              footable={footable}
              footableColumns={footableColumns}
              checkOnItemClick={checkOnItemClick}
              buildItemProps={buildItemProps}
              onAction={onAction}
              rowClassNameExpr={rowClassNameExpr}
              rowClassName={rowClassName}
              rows={rows}
              columns={columns}
              locale={locale}
              translate={translate}
              prefixRow={prefixRow}
              affixRow={affixRow}
              data={data}
              // Jay
              store={store}
              stickyWidths={stickyWidths}
              position={position}
              primaryField={primaryField}
              contextMenuVisible={this.props.contextMenuVisible}
              onContextMenuVisibleChange={this.props.onContextMenuVisibleChange}
              setBorder={this.props.setBorder}
              rowItems={this.props.rowItems}
            ></TableBody>
          )}
        </table>
      </div >
    );
  }
}
