import * as React from 'react';
import classNames from 'classnames/bind';
import TextItem from 'components/items/TextItem';
import DateItem from 'components/items/DateItem';
import CustomIcon from 'components/items/CustomIcon';

import qs from 'query-string';
import _ from 'lodash';

import ModuleButton from 'components/items/ModuleButton';
import { NavLink } from 'react-router-dom';
import { Form } from 'react-final-form';

import { transformFunctions, options, models } from 'config/root';
import { Column, Table, AutoSizer } from 'react-virtualized';
import { config } from 'config/general';
import { getPageInfo, getLinkWithVariables } from 'store/utils/adminHelpers';
import CellRowForm from 'components/forms/CellRowForm';
import { useDispatch } from 'react-redux';
import { CgSortAz, CgSortZa } from 'react-icons/cg';
import Tooltip from 'components/items/Tooltip';
import { FaImage } from 'react-icons/fa';
import styleIdentifiers from './virtualTable.scss';

const styles = classNames.bind(styleIdentifiers);

export interface VirtualTableProps {
  type: string;
  items: object[];
  headers: object[];
  sort: Function;
  order?: string;
  asc?: boolean;
  history: object[];
  // do not edit
  noUpdate?: boolean;
  rowHeight?: number;
  // do not see detail
  noDetail?: boolean;
  doubleTap?: string;
  dialogShow: Function;
}

interface VirtualTableState {}

const SIZE_ICON_BUTTON = 35;

const CheckBoxList = props => {
  const { onCheck, active, ...rest } = props;
  return (
    <div className={styles('CheckBoxList')}>
      <div className={styles('check', active && 'active')} onClick={() => onCheck({ ...rest })} />
    </div>
  );
};

const ButtonAction = props => {
  const { columnData, action, rowData, ...rest } = props;
  const dispatch = useDispatch();

  function customAction() {
    if (columnData?.action) {
      return dispatch(columnData.action(rowData, dispatch));
    }

    return action();
  }

  return <ModuleButton small {...rest} noShadow action={customAction} />;
};

export default class VirtualTable extends React.Component<VirtualTableProps, VirtualTableState> {
  constructor(props) {
    super(props);

    this.state = {
      editedPart: null,
      scrolled: false,
    };
  }

  componentDidMount() {
    this.handleScroll();
  }

  componentDidUpdate() {
    this.handleScroll();
  }

  handleScroll = () => {
    const { meta, items, type } = this.props;
    const { scrolled } = this.state;

    const pageInfo = getPageInfo(this.props, options);

    const { listData } = pageInfo;
    // type is the resource type, should be unique
    if (
      items &&
      items.length &&
      type &&
      this.table &&
      meta[`${type}ScrollTop`] &&
      !scrolled &&
      !listData
    ) {
      this.table.scrollToPosition(meta[`${type}ScrollTop`]);

      this.setState({
        scrolled: true,
      });
    }
  };

  // Basic edit action
  edit = (item, index: number, newTab?: boolean) => {
    const { history, location, resetDetail, editLink, actionEdit } = this.props;

    const pageInfo = getPageInfo(this.props, options);

    if (actionEdit) {
      actionEdit(item);
      return;
    }

    if (typeof pageInfo === 'string') return;

    const { type, id, listData, modelOptions } = pageInfo;

    const separated = modelOptions.separated;

    // standalone resource
    const standalone = modelOptions.standalone;

    if (editLink) {
      history.push({
        pathname: getLinkWithVariables(editLink, { ...pageInfo, ...item }),
      });
      return;
    }
    if (listData && id) {
      if (!separated) {
        if (!newTab) {
          history.push({
            pathname: `/${config.resourcePath}/${type}/${id}/listdata/${listData}/${index}/update`,
            search: location.search,
          });
        } else {
          window.open(
            `/${config.resourcePath}/${type}/${id}/listdata/${listData}/${index}/update${location.search}`,
            '_blank',
          );
        }
      } else {
        const search = standalone ? '' : `?parentType=${type}&parentId=${id}`;

        if (!newTab) {
          // reset if same view
          resetDetail();
          history.push({
            pathname: `/${config.resourcePath}/${listData}/${item[config.idKey]}/update`,
            search,
          });
        } else {
          window.open(
            `/${config.resourcePath}/${listData}/${item[config.idKey]}/update${search}`,
            '_blank',
          );
        }
      }
      return;
    }
    if (!newTab) {
      history.push({
        pathname: `/${config.resourcePath}/${type}/${item[config.idKey]}/update`,
        search: location.search,
      });
    } else {
      window.open(
        `/${config.resourcePath}/${type}/${item[config.idKey]}/update${location.search}`,
        '_blank',
      );
    }
  };

  // Basic edit action
  detail = (item, index: number, newTab?: boolean) => {
    const { resetDetail, history, location, detailLink, actionDetail } = this.props;

    const pageInfo = getPageInfo(this.props, options);

    if (actionDetail) {
      actionDetail(item);
      return;
    }

    if (typeof pageInfo === 'string') return;

    const { type, id, listData, modelOptions } = pageInfo;

    const separated = modelOptions.separated;
    // standalone resource
    const standalone = modelOptions.standalone;

    if (listData && id) {
      if (!separated) {
        if (!newTab) {
          history.push({
            pathname: `/${
              config.resourcePath
            }/${type}/${id}/listdata/${listData}/${index}/${detailLink || 'detail'}`,
            search: location.search,
          });
        } else {
          window.open(
            `/${config.resourcePath}/${type}/${id}/listdata/${listData}/${index}/${detailLink ||
              'detail'}${location.search}`,
            '_blank',
          );
        }
      } else {
        const search = standalone ? '' : `?parentType=${type}&parentId=${id}`;

        if (!newTab) {
          // reset if same view
          resetDetail();
          history.push({
            pathname: `/${config.resourcePath}/${listData}/${item[config.idKey]}/${detailLink ||
              'detail'}`,
            search,
          });
        } else {
          window.open(
            `/${config.resourcePath}/${listData}/${item[config.idKey]}/${detailLink ||
              'detail'}${search}`,
            '_blank',
          );
        }
      }

      return;
    }

    if (!newTab) {
      history.push({
        pathname: `/${config.resourcePath}/${type}/${item[config.idKey]}/${detailLink || 'detail'}`,
        search: location.search,
      });
    } else {
      window.open(
        `/${config.resourcePath}/${type}/${item[config.idKey]}/${detailLink || 'detail'}${
          location.search
        }`,
        '_blank',
      );
    }
  };

  delete = item => {
    const { deleteItem, deleteApollo, loadApollo, actionDelete } = this.props;

    const pageInfo = getPageInfo(this.props, options);

    if (actionDelete) {
      actionDelete(item);
    }

    if (typeof pageInfo === 'string') return;

    const { id, type, parentType, resourceOptions, parentId, modelOptions, listData } = pageInfo;

    const resourceType = type;

    if (modelOptions.apollo) {
      const inputs = {};
      if (modelOptions.parent) {
        inputs[modelOptions.parent] = id;
      }
      deleteApollo({
        id: item[config.idKey],
        options: modelOptions,
        inputs,
        callback: () => {
          if (listData) {
            loadApollo({
              id,
              options: resourceOptions,
            });
          }
        },
      });

      return;
    }

    deleteItem({
      resourceId: item[config.idKey],
      resourceType,
      parentType: modelOptions.linkedRessource && parentType,
      parentId: modelOptions.linkedRessource && parentId,
    });
  };

  // Button action
  actionButton = action => {
    const { history } = this.props;

    history.push({
      pathname: action.url,
      search: qs.stringify(action.data),
    });
  };

  // Rendering of the text
  renderText = (value: string, columnData, style) => {
    // All other case
    if (Array.isArray(value)) {
      return value.map((val, index) => (
        <span key={index} style={style}>
          {index > 0 && <span>,&nbsp;</span>}
          {this.renderText(val, columnData)}
        </span>
      ));
    }
    if (columnData.list) {
      return (
        <TextItem
          className={styles('text-cell-container')}
          style={style}
          list={columnData.list}
          item={value}
        />
      );
    }
    if (columnData.values) {
      return (
        <TextItem
          className={styles('text-cell-container')}
          style={style}
          path={columnData.values}
          item={value}
        />
      );
    }

    if (columnData.avoidContentText) {
      return <span style={style}>{value}</span>;
    }

    if (columnData.decimal) {
      return <span style={style}>{value && value.toFixed(columnData.decimal)}</span>;
    }
    if (columnData.noTextItem) {
      return value;
    }

    if (columnData?.transform) value = columnData.transform(value);

    return (
      <TextItem
        className={styles('text-cell-container')}
        style={style}
        path={value}
        isHtml={columnData.isHtml}
      />
    );
  };

  renderActionButton = (type: string, data, index) => {
    if (type === 'edit') {
      return this.edit(data, index);
    }
    if (type === 'detail') {
      return this.detail(data, index);
    }
    if (type === 'delete') {
      return this.delete(data, index);
    }
    return false;
  };

  renderButtonIcon = (type: string) => {
    switch (type) {
      case 'detail':
        return 'eye';
      case 'edit':
        return 'pen';
      case 'delete':
        return 'trash';
      default:
        return 'pen';
    }
  };

  preview = (value: string) => {
    const { dialogShow } = this.props;

    dialogShow({
      id: 'preview',
      img: value,
      large: true,
    });
  };

  cellFields = (item, resourceName) => {
    const pageInfo = getPageInfo(this.props, options, models, transformFunctions);

    let { fields } = pageInfo;

    if (resourceName) {
      fields = models[resourceName];
    }

    const section = _.find(fields, e => {
      const subFields = e.fields;
      return _.find(subFields, (el, k) => k === item || el.name === item);
    });

    if (section) {
      return _.find(section.fields, (e, key) => key === item || e.name === item);
    }

    return false;
  };

  handleSubmitCellValue = (values, columnData) => {
    const { update, updateApollo, loadApollo, loadListApollo } = this.props;

    const pageInfo = getPageInfo(this.props, options, models, transformFunctions);

    const { id, type, modelOptions, resourceOptions, listData, subData } = pageInfo;
    let { parentType, parentId } = pageInfo;

    const data = (modelOptions.treatData && modelOptions.treatData(values)) || values;

    const resourceId =
      (columnData.pathIdKey && _.get(values, columnData.pathIdKey)) || values[config.idKey] || id;
    const resourceType = type;

    if (columnData.otherResource) {
      parentType = null;
      parentId = null;
    }

    let newData;
    if (columnData.objectToSend) {
      newData = data[columnData.objectToSend];
    }
    const sendData = newData || data;

    if (modelOptions.apollo) {
      const inputs = {};
      // modelOptions if the current model
      if (modelOptions.parent) {
        inputs[modelOptions.parent] = id;
      }
      const subResource = listData || subData;

      console.log('TODO: handle apollo update');
      // updateApollo({
      //   options: modelOptions,
      //   // ID of the list data (data[config.idKey] or id the parent (id)
      //   id: data[config.idKey] || id,
      //   data: sendData,
      //   // For list data or subdata
      //   inputs,
      //   noLoading: true,
      //   // Avoid to reset the parent detail
      //   subResource,
      //   success: modelOptions.successUpdate,
      //   callback: (): void => {
      //     // If subresource => reload parent
      //     if (subResource) {
      //       // reload
      //       loadApollo({
      //         id: resourceId,
      //         options: resourceOptions,
      //       });
      //     }
      //   },
      // });
      return;
    }

    update({
      resourceId,
      resourceType,
      parentType,
      parentId,
      data: sendData,
      success: modelOptions.successUpdate,
      transform: e => {
        if (columnData.objectToSend) {
          data[columnData.objectToSend] = e;
          return data;
        }
        return e;
      },
    });

    this.setState({ editedPart: null });
  };

  cellContainerRenderer = cellOptions => {
    const { noUpdate, noCheckBox } = this.props;

    const { editedPart } = this.state;
    const { columnData, rowData } = cellOptions;

    const cellActive =
      (editedPart &&
        editedPart.col === columnData.key &&
        editedPart.row === rowData[config.idKey]) ||
      false;

    // Check if can update the cell or nots
    const canUpdate =
      // !noUpdate &&
      // not updatable types
      ['picture'].indexOf(columnData.type) < 0 &&
      columnData.key &&
      !columnData.noUpdate &&
      !columnData.noCellUpdate &&
      !config.noCellUpdate;

    return (
      <div
        onDoubleClick={() => {
          if (canUpdate) {
            this.setState({
              editedPart: { col: columnData.key, row: rowData[config.idKey] },
            });
          }
        }}
        className={styles(
          'cell-container',
          canUpdate && 'can-update',
          cellActive && 'cell-container-active',
          cellOptions.dataKey === 'index' && !noCheckBox && 'center-value',
          columnData?.type === 'list' && 'cell-container-with-overflow',
        )}
      >
        {/* {cellActive ? (
          <Form
            initialValues={rowData}
            inputName={columnData.key}
            component={CellRowForm}
            onClickOutside={() => this.setState({ editedPart: null })}
            field={this.cellFields(
              columnData.fieldName || columnData.key,
              columnData.otherResource || null,
            )}
            onSubmit={val => this.handleSubmitCellValue(val, columnData)}
          />
        ) : (
          this.cellRenderer(cellOptions)
        )} */}
        {this.cellRenderer(cellOptions)}
      </div>
    );
  };

  renderStatusInfo = (item, index) => {
    if (typeof item !== 'object') return <div className={styles(`info${index}`)} />;

    if (item.active) return <div className={styles(`info${index}`, 'label')}>{item.label}</div>;

    return false;
  };

  // Render of A cell in the table
  cellRenderer = cellOptions => {
    const { items, noCheckbox, checkedItems, onCheck, noModule } = this.props;
    // from virtual
    const { cellData, columnData, dataKey, rowData, rowIndex } = cellOptions;

    const dynamicInfos = this.getTransformedData(rowData);

    let style = {};

    if (columnData.style) {
      if (typeof columnData.style === 'function') {
        style = columnData.style(rowData);
      } else {
        style = columnData.style;
      }
    }

    if (typeof style !== 'object') style = {};

    // Index cell
    if (dataKey === 'index') {
      let indexValue = rowIndex + 1;

      if (config.invertedRowIndex) {
        indexValue = items.length - rowIndex;
      }

      if (!noCheckbox) {
        const isActive = checkedItems && checkedItems.indexOf(rowData[config.idKey]) >= 0;

        return <CheckBoxList item={rowData} active={isActive} onCheck={onCheck} />;
      }

      return (
        <div className={styles('clickable', 'index')} onClick={() => this.edit(rowData)}>
          {indexValue}
        </div>
      );
    }
    const type = columnData.type;

    // indication according to the data
    if (type === 'status' && dynamicInfos.infos) {
      const infoHasLabel = dynamicInfos.infos.info1?.label;

      return (
        <div className={styles('status')}>
          <div className={styles('infos', (!noModule || infoHasLabel) && 'label-info')}>
            {dynamicInfos.infos.info1 ? this.renderStatusInfo(dynamicInfos.infos.info1, 1) : false}
            {dynamicInfos.infos.info2 ? this.renderStatusInfo(dynamicInfos.infos.info2, 2) : false}
            {dynamicInfos.infos.info3 ? this.renderStatusInfo(dynamicInfos.infos.info3, 3) : false}
            {dynamicInfos.infos.info4 ? this.renderStatusInfo(dynamicInfos.infos.info4, 4) : false}
            {dynamicInfos.infos.info5 ? this.renderStatusInfo(dynamicInfos.infos.info5, 5) : false}
          </div>
        </div>
      );
    }

    // custom button action
    if (type === 'button') {
      const button = dynamicInfos[columnData.action];

      return (
        <div className={styles('action')}>
          <ModuleButton
            small
            noMargin
            className={button.className}
            label={button.label}
            relative
            color="primary"
            action={() => this.actionButton(button.action)}
          />
        </div>
      );
    }
    // handle date type
    if (type === 'date') {
      return <DateItem style={style} date={cellData} format={columnData.format} />;
    }

    // last button
    if (type === 'edit' || type === 'detail' || type === 'delete' || type === 'action') {
      let color = 'primary';
      if (type === 'delete') color = 'red';
      if (type === 'detail') color = 'secondary';
      return (
        <div className={styles('action')}>
          <ButtonAction
            icon={columnData?.icon || this.renderButtonIcon(type)}
            color={color}
            rowData={rowData}
            rowIndex={rowIndex}
            columnData={columnData}
            action={() => !columnData?.action && this.renderActionButton(type, rowData, rowIndex)}
            className={styles('button-icon')}
            relative
            noMargin
          />
        </div>
      );
    }
    const value = _.get(rowData, dataKey);

    if (type === 'picture') {
      return (
        <div className={styles('picture-wrapper')}>
          <div
            className={styles('picture', columnData.contain && 'contain')}
            style={{
              backgroundImage: `url(${value})`,
            }}
            onClick={() => value && this.preview(value)}
          />
        </div>
      );
    }
    if (type === 'link' || columnData.link) {
      const path = columnData.link || columnData.key;
      const dynamicLink = _.get(dynamicInfos, path);
      if (dynamicLink) {
        return <NavLink to={dynamicLink.href}>{this.renderText(value, columnData, style)}</NavLink>;
      }
    }
    if (columnData.id) {
      let resource = columnData.resource || columnData.key;
      if (columnData.dynamic) {
        resource = _.get(dynamicInfos, resource);
      }

      let link = `/${config.resourcePath}/${resource}`;
      if (columnData.resourceType !== 'listing') {
        const id = _.get(rowData, columnData.id);
        if (id) link += `/${id}/${columnData.resourceType || 'detail'}`;
      }
      if (columnData.searchParameters) {
        link += `?${qs.stringify(columnData.searchParameters)}`;
      }
      return <NavLink to={link}>{this.renderText(value, columnData, style)}</NavLink>;
    }

    if (type === 'email') {
      const email = _.get(rowData, columnData.key);
      return (
        <a target="_blank" rel="noopener noreferrer" href={`mailto:${email}`}>
          {this.renderText(value, columnData, style)}
        </a>
      );
    }

    if (type === 'dynamic') {
      const val = _.get(dynamicInfos, columnData.key);
      return this.renderText(val, columnData, style);
    }

    if (type === 'list') {
      const listKey = columnData.key
        .split('.')
        .slice(0, -1)
        .join('.');

      const val = _.get(rowData, listKey);

      if (val && Array.isArray(val)) {
        const item = withBr => (
          <div className={styles('list-cell-values', withBr && 'list-cell-column')}>
            {val?.map((valItem, key) => (
              <div key={key}>
                {!withBr && key > 0 && <span>,&nbsp;</span>}
                {withBr ? (
                  <div>{valItem[columnData.key.split('.').pop()]}</div>
                ) : (
                  valItem[columnData.key.split('.').pop()]
                )}
              </div>
            ))}
          </div>
        );
        return (
          <Tooltip className={styles('list-cell-container')} item={item()}>
            {item(true)}
          </Tooltip>
        );
      }
    }

    return this.renderText(value, columnData, style);
  };

  // Get transformed data from model (TODO: add that in the headerConfig)
  getTransformedData = item => {
    const { noModule, moduleOptions } = this.props;

    let pageInfo;

    if (noModule) pageInfo = getPageInfo(this.props, options, models, transformFunctions);

    if (!noModule) pageInfo = moduleOptions;

    if (typeof pageInfo === 'string') return {};

    let data = {};

    if (pageInfo) {
      const { transformFunction } = pageInfo;

      if (transformFunction) {
        data = transformFunction(item);
      }
    }

    return data;
  };

  getColumnWidth = headerItem => {
    const type = headerItem.type;
    if (headerItem.minWidth) return headerItem.minWidth;
    if (headerItem.width) return headerItem.width;
    switch (type) {
      case 'picture':
        return 60;
      case 'status':
        return 60;
      case 'small':
        return 120;
      // as big as possible
      default:
        return 150;
    }
  };

  getColumnMaxWidth = headerItem => {
    const type = headerItem.type;
    if (headerItem.maxWidth) return headerItem.maxWidth;
    switch (type) {
      case 'picture':
        return 60;
      case 'status':
        return 60;
      default:
        return null;
    }
  };

  headerRenderer = headerOptions => {
    const { dataKey, disableSort, label, columnData } = headerOptions;

    const { order, asc, noCheckbox, onCheck, masterCheck } = this.props;

    if (columnData.type === 'picture') {
      return (
        <div className={styles('head', 'head-label', columnData.type)}>
          <FaImage />
        </div>
      );
    }
    return (
      <div className={styles('head', 'head-label', columnData.type)}>
        {!noCheckbox && columnData.type === 'index' ? (
          <CheckBoxList onCheck={onCheck} active={masterCheck} all />
        ) : (
          <TextItem path={label} />
        )}
        {!disableSort && order === dataKey && (
          <div className={styles('filter')}>
            {asc ? (
              <CgSortZa className={styles('icon')} />
            ) : (
              <CgSortAz className={styles('icon')} />
            )}
          </div>
        )}
      </div>
    );
  };

  headerRowRenderer = headerOptions => {
    const { className, columns, style } = headerOptions;
    return (
      <div className={styles(className, 'header-row')} role="row" style={style}>
        {columns}
      </div>
    );
  };

  onRowDoubleClick = rowOptions => {
    const { rowData, index } = rowOptions;

    const { noUpdate, noDetail, doubleTap, newTab } = this.props;

    const pageInfo = getPageInfo(this.props, options);

    if (typeof pageInfo === 'string') return;

    const { modelOptions } = pageInfo;

    if (noUpdate && noDetail) return;

    // Disable double click link if cellUpdate enabled
    if (!config.noCellUpdate && !modelOptions.apollo) {
      return;
    }

    if (doubleTap === 'detail' || noUpdate) {
      this.detail(rowData, index, newTab);
      return;
    }

    this.edit(rowData, index, newTab);
  };

  checkFixedColumn = item => {
    if (item.type === 'status') return true;
    if (item.type === 'picture') return true;
    return false;
  };

  checkDisableSort = item => {
    const { listData } = this.props;
    if (this.checkFixedColumn(item)) return true;
    if (item.disableSort) return true;
    if (item.noOrder) return true;
    if (listData) return true;
    return false;
  };

  getWidthTable = () => {
    const { headers } = this.props;

    let width = config.widthIndex + 2 * SIZE_ICON_BUTTON + 40; // 40 for the side margin
    for (let i = 0; i < headers.length; i++) {
      width += 10 + this.getColumnWidth(headers[i]); // 10 for the margin
    }
    return width;
  };

  saveScroll = scrollData => {
    if (!scrollData) return;

    // type is the resource type, should be unique
    const { setMeta, type } = this.props;

    const { scrollTop, clientHeight, scrollHeight } = scrollData;

    // do not save when 0 or always reset
    if (!type || clientHeight < 0 || clientHeight === scrollHeight) return;

    //
    setMeta({
      [`${type}ScrollTop`]: scrollTop,
    });
  };

  render() {
    const {
      headers,
      rowHeight,
      items,
      sort,
      noUpdate,
      noDetail,
      fastDelete,
      fastActions,
      noCheckBox,
    } = this.props;

    const itemHeight = rowHeight || 50;

    return (
      <div className={styles('VirtualTable')}>
        <AutoSizer>
          {({ height, width }) => {
            const tableWidth = Math.max(this.getWidthTable(), width);

            return (
              <Table
                ref={table => {
                  this.table = table;
                }}
                onRowDoubleClick={this.onRowDoubleClick}
                headerRowRenderer={this.headerRowRenderer}
                className={styles('table')}
                headerClassName={styles('head')}
                rowClassName={styles('row')}
                width={tableWidth}
                height={height}
                headerHeight={50}
                rowHeight={itemHeight}
                sort={sort}
                onScroll={this.saveScroll}
                rowCount={items.length}
                rowGetter={({ index }) => items[index]}
              >
                <Column
                  headerRenderer={this.headerRenderer}
                  disableSort
                  label="#"
                  columnData={{ type: 'index' }}
                  dataKey="index"
                  style={{ textAlign: 'center' }}
                  width={config.widthIndex}
                  minWidth={config.widthIndex}
                  cellRenderer={this.cellContainerRenderer}
                />
                {headers &&
                  headers
                    .filter(e => !e.hide)
                    .map((headerItem, index) => {
                      const dataKey = headerItem.key || headerItem.title || headerItem.label;
                      return (
                        <Column
                          key={headerItem.id || index}
                          headerRenderer={this.headerRenderer}
                          // sort={sort}
                          disableSort={this.checkDisableSort(headerItem)}
                          columnData={headerItem}
                          flexGrow={!this.checkFixedColumn(headerItem) ? 3 : 1}
                          label={headerItem.title}
                          minWidth={this.getColumnWidth(headerItem)}
                          width={this.getColumnWidth(headerItem)}
                          maxWidth={this.getColumnMaxWidth(headerItem)}
                          dataKey={dataKey}
                          cellRenderer={this.cellContainerRenderer}
                        />
                      );
                    })}
                {fastActions?.map((actionItem, actionKey) => (
                  <Column
                    key={actionKey}
                    headerRenderer={this.headerRenderer}
                    disableSort
                    columnData={{
                      type: 'action',
                      icon: actionItem?.icon,
                      action: actionItem?.action,
                    }}
                    label=""
                    dataKey="action"
                    width={SIZE_ICON_BUTTON}
                    minWidth={SIZE_ICON_BUTTON}
                    maxWidth={SIZE_ICON_BUTTON}
                    cellRenderer={this.cellContainerRenderer}
                  />
                ))}
                {!noDetail && (
                  <Column
                    headerRenderer={this.headerRenderer}
                    disableSort
                    columnData={{ type: 'detail' }}
                    label=""
                    dataKey="detail"
                    width={SIZE_ICON_BUTTON}
                    minWidth={SIZE_ICON_BUTTON}
                    maxWidth={SIZE_ICON_BUTTON}
                    cellRenderer={this.cellContainerRenderer}
                  />
                )}
                {!noUpdate && (
                  <Column
                    headerRenderer={this.headerRenderer}
                    disableSort
                    columnData={{ type: 'edit' }}
                    label=""
                    dataKey="edit"
                    width={SIZE_ICON_BUTTON}
                    minWidth={SIZE_ICON_BUTTON}
                    maxWidth={SIZE_ICON_BUTTON}
                    cellRenderer={this.cellContainerRenderer}
                  />
                )}
                {fastDelete && (
                  <Column
                    headerRenderer={this.headerRenderer}
                    disableSort
                    columnData={{ type: 'delete' }}
                    label=""
                    dataKey="delete"
                    width={SIZE_ICON_BUTTON}
                    minWidth={SIZE_ICON_BUTTON}
                    maxWidth={SIZE_ICON_BUTTON}
                    cellRenderer={this.cellContainerRenderer}
                  />
                )}
              </Table>
            );
          }}
        </AutoSizer>
      </div>
    );
  }
}
