import React, { useCallback, useMemo } from 'react';
import { CRUDProps, CRUDState } from '../../types';
import { Schema } from '../../../../types';
import OverflowWrapper from '../../../../components/OverflowWrapper';
import omit from 'lodash/omit';
import { isObject, uuid } from '../../../../utils/helper';
import { Checkbox as AntdCheckbox, Select } from 'antd';
import DataCross from '../../../Table/DataCross';
import DataStatic from '../../../Table/DataStatic';
import FindAndReplace, { RowData } from '../../../Table/FindAndReplace';
import DataCharts from '../../../Table/DataCharts';
import SqlOptimize from '../../../Table/SqlOptimize';
import ColumnToggler, { Temp } from '../../../Table/ColumnToggler';
import { Icon } from '../../../../components/icons';
import { ContextMenu } from '../../../Lion/components/LionContextMenu';
import { Checkbox } from '../../../../components';
import { ITableStore } from '../../../../store/table';
import { Button } from '../../../../components/Button';

// 不做处理的按钮类型
const specialButtonType = ['rfid-action']

const canFindReplaceTypes = ['plain', 'input-text', 'number', 'input-number', 'static-number', 'html', 'static-html', 'input-rich-text', 'date', 'input-date', 'datetime', 'input-datetime', 'time', 'input-time', 'input-date-range', 'input-time-range', 'input-datetime-range', 'input-month', 'input-quarter', 'input-year', 'textarea']

interface IProps {
  props: CRUDProps
  state: CRUDState
  data: { items: any[], selectedItems: any[], itemRaws: [] }
  actionData: any
  inSmallDialog: boolean
  tableStore: ITableStore
  indexColShow: boolean
  columnSettingTemps: Temp[]
  showColumnsFilter: boolean
  getAllData: () => Promise<{ items: any[]; total: number }>
  onAction: (e: any, toolSchema: Schema, isBulkAction?: boolean) => void
  onPageChange: (page: number, perPage?: number) => void
  onDealData: (toolType: string, label: string, schema: any, extraProps: { [key: string]: any }) => void
  onBulkReplace: (rowDataList: RowData[]) => void;
  updateActiveCell: (row?: number, col?: string) => void;
  onCheckAll: (type: number) => void
  onColumnToggle: (columns: any[] | undefined, saveCols: Record<string, any>, canFetch: boolean, targetTemp?: Temp, needDebounce?: boolean) => void
  setIndexColShow: (show: boolean) => void
  setColumnSettingTemps: (temps: Temp[]) => void
  onFlush: () => void
}


const Toolbar: React.FC<IProps> = ({ props, state, data, actionData, inSmallDialog, tableStore, indexColShow, columnSettingTemps, showColumnsFilter,
  getAllData, onAction, onDealData, onPageChange, onBulkReplace, updateActiveCell, onCheckAll, onColumnToggle, onFlush,
  setIndexColShow, setColumnSettingTemps }) => {

  const { headerToolbar, footerToolbar, headerActions, headerBulkActions, multiple, columns, api,
    alwaysShowPagination, perPageAvailable, loadDataOnce, primaryField, name, aliasTitle, tabTitle, mode,
    render, env, store, classnames: cx, translate: __, classPrefix: ns, } = props

  const { checkedFieldTranslate, selectedIndex } = state

  const actions = useMemo(() => {
    return headerActions?.concat(headerBulkActions ?? [])
  }, [headerActions, headerBulkActions])


  const hasPaginator = useMemo(() => {
    return footerToolbar.some(schema => schema.type === 'pagination')
  }, [footerToolbar])

  const perPages = useMemo(() => {
    return (perPageAvailable ?? [5, 10, 20, 50, 100]).map((item) => ({ label: item + (inSmallDialog ? '' : ` ${__('CRUD.countPage')}`), value: item }));
  }, [perPageAvailable, inSmallDialog])

  // 字段翻译按钮
  const extraLeftBtns = useMemo(() => {
    return headerToolbar.filter((item) => item.align !== 'right')
  }, [headerToolbar])

  const leftToolButtons = useMemo(() => {
    return footerToolbar.filter(item => item.align == 'right' && item.type !== 'footerBulkActions').sort((a, b) => {
      const order = ['switch-per-page', 'pagination', 'statistics']
      return order.indexOf(a.type) - order.indexOf(b.type)
    })
  }, [footerToolbar])

  const rightToolButtons = useMemo(() => {
    return headerToolbar.filter((toolbar) => toolbar.align == 'right').reverse();
  }, [headerToolbar])

  const searchBtnIndex = useMemo(() => {
    return rightToolButtons.findIndex((toolbar) => toolbar.actionType === 'advanced-filter');
  }, [rightToolButtons])


  //统计数据记录, 141-交叉制表，142-统计，143-图表
  const staticRecords = useCallback((port: 141 | 142 | 143) => {
    env.fetcher({
      url: `/api/v1/opt/${name}_${port == 141 ? 'cross' : port == 142 ? 'total' : 'chart'}/record/${port}`,
      method: 'get'
    })
  }, [name])

  const renderPagination = () => {
    const { page, lastPage } = store
    if (store.mode !== 'simple' && store.lastPage < 2 && !alwaysShowPagination) {
      return null
    }
    return (
      <div className={cx('Crud-pager')}>
        {render('pagination', { type: 'pagination' }, {
          activePage: page,
          lastPage: lastPage,
          hasNext: store.hasNext,
          mode: store.mode,
          onPageChange: onPageChange
        })}
      </div>
    );
  }

  const renderStatistics = () => {
    return (
      <div className={cx('Crud-statistics')}>
        {mode == 'cross' ?
          __('CRUD.total', { total: mode == 'cross' ? tableStore?.rows?.length : store.data?.total }) :
          __('CRUD.stat', { total: store.total })}
      </div>
    );
  }

  const renderSwitchPerPage = () => {
    return (
      <div className={cx('Crud-pageSwitch')} >
        <Select
          options={perPages}
          placeholder={__('Select.placeholder')}
          defaultValue={perPages[0]?.value || ''}
          onChange={(value: any) => { onPageChange(1, value) }}
        />
      </div>
    )
  }

  const renderDataCross = (action: Schema) => {
    return (
      <DataCross
        tableName={name || uuid()}
        action={action}
        columns={tableStore.filteredColumns}
        data={data}
        modalContainer={(env?.getTopModalContainer || document.body)}
        getAllData={getAllData}
        staticRecords={staticRecords}
        onOK={(cross, crossColumns, datas, countColumns, extraProps) => {
          const linkTitle = `${props.aliasTitle?.trim?.()}-交叉制表`
          const schema = {
            aliasTitle: linkTitle,
            type: "crud",
            mode: 'cross',
            name: `${name || uuid()}_cross`,
            cross,
            crossColumns,
            isCross: true,
            combineNum: cross.positionType == 1 ? cross.rowFields.length : undefined,
            "affixHeader": true,
            "columns": columns,
            "defaultData": datas,
            'affixRow': countColumns,
            "perPage": 10000,
            "autoFillHeight": true,
            "multiple": true,
            "setBorder": true,
            "keepItemSelectionOnPageChange": false,
            "syncLocation": false,
            "headerToolbar": [{
              "redDot": false,
              "actionType": "export",
              "type": "action",
              "name": "default_export",
              "label": "导出",
              "icon": "#icon-tooltool_download",
              "tooltip": "默认导出",
              "align": "right",
              "close": true,
              "tooltipPlacement": "top"
            },
            {
              "type": "data-statics",
              "label": "统计",
              "icon": "#icon-tooltotal",
              "align": "right"
            },
            {
              "type": "data-cross",
              "label": "交叉制表",
              "icon": "#icon-toolcross",
              "align": "right"
            }],
            "footerToolbar": [{
              "type": "statistics",
              "align": "right"
            }],
            "checkOnItemClick": false,
            "header": [],
            "footer": []
          }
          onDealData('data-cross', linkTitle, schema, extraProps)
        }}
      />
    )
  }

  const renderDataStatic = (action: Schema) => {

    const colList = tableStore.columnsData.filter(col => !col.pristine.hidden && col.type !== 'operation')
      .map((item: any) => item.toJSON ? item.toJSON() : item)

    return <DataStatic originHeaderToolbar={headerToolbar} crudTitle={props.aliasTitle || props.tabTitle || ''}
      container={env?.getTopModalContainer} staticRecords={staticRecords}
      getAllData={getAllData} data={data} loadDataOnce={props.loadDataOnce}
      columns={colList} action={action} name={name!} isStatic={props.isStatic} handleDealData={onDealData} />
  }

  const renderDataCharts = (action: Schema) => {
    const colList = tableStore.columnsData.filter(col => !col.pristine.hidden && col.type !== 'operation')
      .map((item: any) => item.toJSON ? item.toJSON() : item)

    return <DataCharts crudTitle={aliasTitle || tabTitle || ''} container={env.getTopModalContainer}
      data={data} columns={colList} action={action} name={name!}
      handleDealData={onDealData} primaryField={primaryField} loadDataOnce={loadDataOnce}
      getAllData={getAllData} staticRecords={staticRecords} />
  }

  const renderFindReplace = (action: Schema) => {
    const colList = tableStore.columnsData.filter(col => !col.pristine.hidden && col.type !== 'operation')
      .map((item: any) => item.toJSON ? item.toJSON() : item).filter(item => !item.type || canFindReplaceTypes.includes(item.type))
    const canReplace = colList.some(item => !!item.pristine?.quickEdit)
    // const itemRaws = store.data?.itemsRaw
    return <FindAndReplace selectedList={data.selectedItems.map(item => item.index)} data={data.items} columns={colList}
      action={action} onBulkReplace={onBulkReplace} canReplace={canReplace}
      currentCheckIndex={props.currentSelectedRow} updateActiveCell={updateActiveCell}
      container={env?.getTopModalContainer} translate={__} crudRef={props.crudRef} />
  }

  const renderFieldTranslate = (action: Schema) => {
    return (
      <div className='show-field-translate-container'>
        <AntdCheckbox checked={checkedFieldTranslate} onChange={(e) => { }}>{action.label || '显示字段翻译'}</AntdCheckbox>
      </div>
    )
  }

  const renderSqlOptimize = (action: Schema) => {
    return (
      <SqlOptimize
        env={env}
        selectedList={data.selectedItems}
        action={action}
        columns={columns?.map((item) => item.name) ?? []}
        sqlStr={data?.sql}
        store={tableStore} />
    );
  }

  const renderColumnsToggler = (config?: any) => {

    return (
      <ColumnToggler
        {...props}
        {...(isObject(config) ? config : {})}
        tooltip={config?.tooltip || __('Table.columnsVisibility')}
        tooltipContainer={env?.getTopModalContainer}
        modalContainer={env?.getModalContainer}
        align={config?.align ?? 'left'}
        isActived={tableStore.hasColumnHidden()}
        classnames={cx}
        classPrefix={ns}
        key="columns-toggable"
        size={config?.size || 'sm'}
        label={config?.label || <Icon icon="columns" className="icon m-r-none" />}
        draggable={config?.draggable}
        columns={tableStore.columnsData}
        onColumnToggle={onColumnToggle}
        columnSettingTemps={columnSettingTemps}
        updateColumnSettingList={setColumnSettingTemps}
        indexColShow={indexColShow}
        setIndexCol={setIndexColShow}
        flushDebounced={onFlush}
      >
      </ColumnToggler>
    );
  }

  const renderReload = (toolbar: Schema) => {
    let reloadButton = {
      label: '',
      icon: toolbar.icon,
      tooltip: __('reload'),
      tooltipPlacement: 'top',
      type: 'button'
    };
    if (typeof toolbar === 'object') {
      reloadButton = { ...reloadButton, ...omit(toolbar, ['type', 'align']) };
    }
    return render(`toolbar`, reloadButton, { onAction });
  }

  const renderColumnsFilterBtn = (toolbar: Schema) => {
    return (
      <Button
        tooltip={'列过滤'}
        size="sm"
        iconOnly
        classnames={cx}
        butColor={showColumnsFilter}
        tooltipContainer={env?.getTopModalContainer || undefined}
        onClick={() => {

        }}
      >
        {toolbar?.icon ?
          <Icon icon={toolbar?.icon} className="icon" symbol /> :
          <Icon icon="packet-filtery" className="icon" />}
        {toolbar?.label && toolbar?.label}
      </Button>
    )
  }

  const renderChild = (schema: Schema) => {
    const { type, actionType } = schema
    if (type === 'action') {
      switch (actionType) {
        case 'label-print':
        case 'bill-print':
        case 'file-print':
        case 'report-print':
        case 'advanced-filter':
          return render(`action-print`, schema, { onAction })
        case 'export':
          return render(`action-export`, schema, { onAction })
      }
    } else {
      switch (type) {
        case 'pagination':
          return renderPagination()
        case 'statistics':
          return renderStatistics()
        case 'switch-per-page':
          return renderSwitchPerPage()
        case 'reload':
          return renderReload(schema)
        case 'columns-filter':
          return renderColumnsFilterBtn(schema)
        case 'data-cross':
          return renderDataCross(schema)
        case 'data-statics':
          return renderDataStatic(schema)
        case 'data-chart':
          return renderDataCharts(schema)
        case 'find-replace':
          return renderFindReplace(schema)
        case 'field-translate':
          return renderFieldTranslate(schema)
        case 'sql-optimize':
          return renderSqlOptimize(schema)
        case 'columns-toggler':
          return renderColumnsToggler(schema)

      }
    }
    return type
  }

  const renderPagenation = () => {
    const column = tableStore.filteredColumns[0]
    const leftFixedColumns = tableStore.leftFixedColumns;
    const lastLeftFixedIndex = leftFixedColumns[leftFixedColumns.length - 1]?.index;

    return (multiple || leftToolButtons.length) ? (
      <div className={cx('Table-affix')} >
        <span className={cx('Table-affixs')} style={{ marginRight: 0, alignItems: 'center' }}>
          <span className={cx('Table-affix-Arr')} >
            <ContextMenu
              menuItems={[{ id: 0, title: '全选' }, { id: 1, title: '反选' }, { id: 2, title: '不选' }]}
              onItemClick={index => multiple && onCheckAll(index)}
              key={Date()}
            >
              <th
                column-name={'__checkme'}
                style={{ cursor: 'pointer', textAlign: 'center', width: 25 }}
                className={cx(column.pristine.className, 'header-cell', {
                  'fixed-left-last': column.index === lastLeftFixedIndex,
                }) + ' last-th'}
                onClick={() => { multiple && onCheckAll(3) }}
              >
                {tableStore.rows.length ?
                  <Checkbox classPrefix={ns} partial={!tableStore.allChecked} checked={tableStore.someChecked} disabled={tableStore.disabledHeadCheckbox} /> :
                  <div>{'\u00A0'}</div>}
              </th>
            </ContextMenu>
          </span>
          <div className={cx('Table-affix-text')} >
            {tableStore.filterColumns?.size > 0 && <span>已筛选{tableStore.rows.length}条数据</span>}
            {(data.selectedItems.length == 0 ? "" : `已选：${data.selectedItems.length}行` + " , ")}
            {/* 有勾选效果展示第几行 */}
            {multiple ? (selectedIndex != undefined && `第${selectedIndex + 1}行`) : null}
          </div>
        </span>
        <div className={cx('Crud-toolbar', { footer: true })}>
          <div className={cx('Crud-toolbar-tool--actions')}>
            {leftToolButtons.map(toolbar => <div key={toolbar.type} className={cx('Crud-toolbar-item')} >{renderChild(toolbar)}</div>)}
          </div>
        </div>
      </div>) : null
  }

  return (
    <div className={cx('Table-toolbar Table-headToolbar')} key="header-toolbar">
      {(Array.isArray(actions) && actions.length) && (
        <div className={cx('Table-actions')} >
          {headerActions?.map((action, index) => {
            return render(
              `action/${index}`,
              {
                type: 'button',
                isTableAction: true,
                ...(action as any)
              },
              {
                onAction: onAction,
                key: index,
                isTableAction: true,
                data: actionData
              }
            )
          })}
          {headerBulkActions?.map((action, index) => {
            return render(
              `bulk-action/${index}`,
              {
                ...omit(action, ['visibleOn', 'hiddenOn', 'disabledOn']),
                type: specialButtonType.includes(action.type) ? action.type : 'button',
                ignoreConfirm: true,
                hidden: false
              },
              {
                key: `bulk-${index}`,
                data: actionData,
                disabled:
                  action.disabled ||
                  (action.requireSelected !== false ? !(data.selectedItems.length > 0) : false),
                onAction: (e: any, schema: any) => onAction(e, schema, true)
              }
            )
          })}
        </div>
      )}
      <div className={cx('Crud-toolbar')}>
        {extraLeftBtns.length > 0 && (
          <div className={cx('Crud-toolbar-tool--actions')}>
            {extraLeftBtns.map((toolbar, index) => <div key={index} className={cx('Crud-toolbar-item', toolbar.className)} >{renderChild(toolbar)}</div>)}
          </div>
        )}
        {(hasPaginator || headerToolbar.length > 0) && (
          <div className={cx('Crud-toolbar-tool--head')}>
            {hasPaginator && renderPagenation()}
            {headerToolbar.length && (
              <div className={cx('Crud-toolbar-tool')}>
                <div className={cx('Crud-toolbar-tool-content')}>
                  <OverflowWrapper env={env} classPrefix={cx} itemClassName={'toolbar-btn-item'}
                    showFixRight={searchBtnIndex > -1}
                    fixRightRenderIndex={searchBtnIndex}
                    items={
                      rightToolButtons.map((toolbar, index) => {
                        return (
                          {
                            key: index,
                            children: (<div key={index} className={cx('Crud-toolbar-item', 'toolbar-btn-item', toolbar.className)} >{renderChild(toolbar)}</div>)
                          }
                        );
                      })
                    }>
                  </OverflowWrapper>
                </div>
              </div>
            )}
          </div>)}
      </div>
    </div>
  )
};

export default Toolbar;
export type { Toolbar };