import Column from '../js/Column.js';
import ColumnGroup from '../js/ColumnGroup.js';
import { Table as ATable, Icon } from 'ant-design-vue';
import _default from '../js/default.js';
import { reload } from '../js/reload.js';
import rows from '../js/row.js';
import getTypes from '../js/getTypes.js';
const { props } = ATable;
// import filterColumnsTable from '../js/filterColumnsTable.mixins.js';
import customScrollbarFN from '../js/scrollbar.js';
import tFilterColumns from '../js/tFilterColumns.vue';

import isEqual from 'lodash/isEqual';

const definevScrollY = {
  enabled: false,
  gt: 40,
  oSize: 20,
  rows: 10
}
const definevScrollX = {
  enabled:false,
  gt:0,
  oSize:20,
};

let Table = {
  name: 'TTable',
  Column,
  ColumnGroup,
  provide() {
    return {
      tableType: 't-table',
      scrollbar() {
        return this.sidebar;
      }
    };
  },
  //filterColumnsTable
  mixins: [],
  props: {
    def: { type: null, default: false },
    ...getTypes(props)
  },

  data() {
    this.paginationHeight = 28 + 16 + 16;
    this.clickTime = 0;
    this.state = null;
    this.addCount(this.dataSource);
    this._def = !this.$props.columns && this.$slots.default?.length > 0;
    //this.sColumns = void 0;
    this.fields = {};
    this.filterReset = false;
    this._befforeRecord = null;
    this._beforeChecks = this.selectedRowKeys||[];
    this.setRowKeys = new Set(this.selectedRowKeys);
    this.loadOver = true
    this.filterTitle=null
    this.colCount= null
    this.isSlotsDefault=!this.$props.columns && this.$slots.default?.length > 0
    this.defaultColumns=void 0
    return {
      // colCount:null,
      backupColMap: null,
      sColumns:void 0,
      // _befforeRecord:null,
      tData: this.dataSource || [],
      sPagination: _default.getDefaultPagination(this.$props.pagination),
      currentCol: { index: null, name: null, focus: false }, //当前单元格的值
      vLoading: this.$props.loading,
      currentRow: null,
    //  storage: [], //存储器
      vautoLoad: this.$props.autoLoad,
      dragLine: null,
      sidebar: null,
      confirmLoading: false,
      //isShow: false,
      sFilters: [],
      dragState: {},
    //  colLocation: {},
      reloadParams: null,
      autoMaxHeight: this.scroll?.y === 'max' ?? null
    };
  },
  destroy() {
    this._befforeRecord=null
    this.sidebar?.destroy();
    this.sidebar = null;
    this.fields = null;
  },
  computed: {
    // tableColumn() {
    //   return this.normalize(this.$slots['default']);
    // },
    selectType() {
      this.rowSelectType;
    },

    isExp() {
      let exp = this.$scopedSlots.expandedRowRender || this.$props.expandedRowRender;
      return exp ? true : false;
    },
    row_Selection({table_rowSelection}) {
      return table_rowSelection();
    },
    treeData() {
      if (this.tree && this.dataSource && this.dataSource.length > 0) {
        return resultTreeNodes(this.dataSource, this.rowKey);
      }
      return null;
    },
    isautoLoad() {
      return this.autoLoad && this.remoteUrl;
    },
    paramsPage() {
      if (!this.sPagination) return false;
      const { current, pageSize } = this.sPagination;
      return {
        pageNum: current,
        pageSize,

      };
    }
  },

  watch: {
    '$attrs.id'(id,oldId) {
      if (id!=oldId) {
        this.filterReset = false;
        this.colCount.title=null
        this.colCount = null;
        this.backupColMap = null;
        //debugger


      }
    },

    // backupColMap(id, oldId) {
    //   if (this.$attrs.id =='RES1000000413_dispatched') {
    //     debugger
    //           }
    // },

    '$props.columns'(list, oldlist) {

       if (!isEqual(list,oldlist)) {
        this.filterReset = false;
        this.colCount = null;
     }


    },
    '$props.loading'(value) {
      this.vLoading = value;
    },

    '$props.activeKey'(value) {
      if (this._befforeRecord) {
        this._befforeRecord.classList.remove('active');
        this._befforeRecord=null
      }
      if (value) {
        this.$nextTick(() => {
          let tr = this.$el.querySelector(`tr[data-row-key="${value}"]`);
          if (tr) {
            tr.classList.add('active')
            this._befforeRecord=tr
          }
        })
      } else {

      }






    },
    '$props.remoteParams'(params, oldParams) {
      if (this.loadOver) {
        this.reload({ params });
      }
    },
    '$props.remoteData'(data, oldData) {

      if (this.loadOver) {
        this.reload({ data });
      }
    },
    '$props.dataSource'(newValue, prev) {
      this.addCount(newValue);
      this.tData = newValue;

    },

    tData(newValue) {


      this.scrollResize()
    },

    editorRowTable(v) {
      if (v) {
        this.$emit('update:dataSource', this.tData);
      }
    }
  },
  // created() {
  // },
  updated() {
    // if (this.$refs.table && !this.dragLine) {
    //   this.dragLine = this.createDragLine();
    //   this.$refs.table.$el.children[0].append(this.dragLine.$el);
    // }
    if (this.$refs.table) {
      if (!this.sidebar && this.customScrollbar) {
        this.sidebar = this.customScrollbarFN(this);
      }
    }
  },

  created() {
    this.isautoLoad && this.reload();
  },
  mounted() {
    console.log(this.$refs.table);
  },
  methods: {
    reload,
    ...rows,
    scrollResize() {
      return this.$el.dispatchEvent(new Event('scrollResize'));

     },
    setCheckboxRow(rows, checked) {

    },
    getCheckedFilters() {
      let key = [];
      for (let i = 0; i < this.tData.length; i++) {
        let record = this.tData[i];
        let rowkey = this.getRecordKey(record, i);
        record._$checked && key.push(rowkey);
      }
      return key;
    },

    getRecordKey(record, index) {
      const { rowKey } = this;
      const recordKey = typeof rowKey === 'function' ? rowKey(record, index) : record[rowKey];

      return recordKey;
    },
    table_customRow(record, index) {
      let _this = this;

      let _config = {
        selectData: [],
        on: {
          // 事件
          click: (event) => {
            if (event.currentTarget.disabled) return;
            if (typeof this.$props.activeKey == 'undefined') {

              if (this._befforeRecord) {
                this._befforeRecord.classList.remove('active')
              }
              let tr = event.target.closest("tr");
              tr.classList.add('active');
              this._befforeRecord = tr;

            }
           let  nativeEvent=event
            if (this.hasRowSelectCheck && event.target.parentNode == event.currentTarget) {
              let input = event.currentTarget.querySelector('.ant-table-selection-column .ant-checkbox-input');
              this.$nextTick(() => {
                var event = new Event('change');
                input.checked = !input.checked;
                input.dispatchEvent(event);

              })

            }

            this.$emit(
              'clickRow',
              {
                target: event.target,
                record,
                index,
                preventDefault: () => {
                  event.preventDefault();
                },
                stopPropagation: () => {
                  event.stopPropagation();
                },
                nativeEvent
              },

              this.getRecordKey(record, index),
              record
            );
          }, // 双击行
          dblclick: (event) => {
            event.index = index;

            let rowRecord = record;
            _this.$emit('dblclickRow', event,this.getRecordKey(record, index), rowRecord);
          },
          contextmenu: (event) => {
            if (!this.editorRowTable) return;
            //右键菜单
          },
          mouseover: () => {
            // console.log(arguments);
          },
          mouseenter: () => {}, // 鼠标移入行
          mouseleave: () => {}
        }
      };
      if (typeof this.customRow === 'function') {
        return { ..._config, ...this.customRow(record, index) };
      }
      return _config;
    },
    // infoState(data) {
    //   var arr = [];
    //   let i = 1;
    //   data &&
    //     data.map((item, index) => {
    //       var k = item.key || item.dataIndex;
    //       if (k == this.defaultCountKey) {
    //         i = i - 1;
    //       } else {
    //         var Obj = {};
    //         item._s = index + i;
    //         for (let key in item) {
    //           Obj[key] = item[key];
    //         }
    //         arr.push({ ...item });
    //       }
    //     });
    //   return arr;
    // },

    getSelectData() {
      let keys = this.selectedRowKeys;
      let data = this.tData;
      let rowKey = this.rowKey;
      if (Array.isArray(keys)) {
        let _map = [];
        keys.forEach(function (key) {
          let f = data.find((item) => item[rowKey] == key);
          if (f) {
            _map.push(f);
          }
        });
        return _map;
      }
    },
    // setClosure(data = []) {
    //   this.storage = [...data];
    // },

    setColProps(dataIndex, object) {
      let table, columns;
      if (this.$options._componentTag == 't-table') {
        table = this.$refs.table;
        columns = table.columns;
      } else if (this.$options._componentTag == 't-table-edit-pro') {
        table = this.$refs.table.$refs.table;
        columns = this.columns;
      } else {
        return;
      }
      let config = null;
      if (columns) {
        config = columns.find((item) => {
          let key = item.dataIndex || item.key;
          return key === dataIndex;
        });
      }
      if (!config) {
        return console.error('this ' + dataIndex + ' not find');
      }
      for (let key in object) {
        object[key];
        this.$set(config, key, object[key]);
      }
      // table.filterChecked(table.updateVisibleKey(columns).concat(this.defaultCountKey));
      // table.filterOnFixed(table.updateFixedKey(columns));
    },
    addCount(newValue) {
      if (newValue && newValue.length > 0) {
        let num = 0;
        if (this.paramsPage && newValue.length <= this.paramsPage.pageSize) {
          let { pageNum, pageSize } = this.paramsPage;
          num = pageNum * pageSize - pageSize;
        }
        let _this = this;
        return this._l(newValue, (item, index) => {
          item[_this.defaultCountKey] = index + 1 + num;
        });
      } else {
        return;
      }
    },

    getRowById(rowKey) {
      if (rowKey) return this.tData.filter((item) => item[this.rowKey] === rowKey);
    },
    delRowItem(key) {
      var index = -1;
      this.tData.filter((item, i, arr) => {
        if (item[this.rowKey] == key) {
          index = i;
          arr.splice(index, 1);
          this.currentRow = null;
        }
      }, this);
    },
    removeRows(key) {
      if (Array.isArray(key) && key.length > 0) {
        key.forEach((ikey) => {
          this.delRowItem(ikey);
        }, this);
      } else {
        this.delRowItem(key);
      }
      this.$emit('delRow', key);
    },
    normalize: ATable.methods.normalize,
    renderResetBtn() {
      if (this.editorRowTable) return;
      if (this.pagination) {
        let vm = this;
        this.$nextTick(() => {
          if (this.hasResetBtn && this.renderResetBtn && this.$el && this.$el.querySelector('.ant-pagination')) {
            this.renderResetBtn = null;
            let clickSync = (event) => {
              event.preventDefault();
              if (vm.vLoading) return;
              if (typeof this.$listeners.change == 'function') {
                this.$listeners.change(this.pagination);
                return vm.$emit('refresh', event);
              } else {
                let vnode = vm.reload((vm.remoteParams && { params: vm.remoteParams }) || (vm.remoteData && { data: vm.remoteData }));
                vm.$emit('refresh', event, vnode);
              }
            };
            let reset_btn = this.constructor.extend({
              render() {
                return (
                  <li class="ant-pagination-item" style="margin:0 10px 0 10px">
                    <a class="ant-pagination-item-link" onClick={clickSync}>
                      <Icon type={vm.vLoading ? 'loading' : 'redo'} />
                    </a>
                  </li>
                );
              }
            });
            reset_btn = new reset_btn().$mount().$el;
            this.$el.querySelector('.ant-pagination').append(reset_btn);
          }
        });
      }
    },
    updateDataSource(data) {
      this.tData = data;
      this.$emit('update:dataSource', data);
    },
    tableChange(pagination, filters, sorter, currentDataSource) {
      const { pageSize = beforePageSize, current = beforeCurrent } = this.sPagination;

      if (this.sPagination.pageSize == pagination.pageSize && this.sPagination.current == pagination.current) {
      } else {
        this.sPagination = pagination;
        this.sFilters = filters;
        let paramsObj = {};
        paramsObj[this.remoteParams && 'params'] = { ...this.remoteParams, ...filters };
        paramsObj[this.remoteData && 'data'] = { ...this.remoteData, ...filters };
        this.reload(paramsObj).then(() => {});
      }
      // this.$refs.table?.sidebar?.resize();
      if (typeof this.$listeners.change === 'function') {
        return this.$emit('change', pagination, filters, sorter, currentDataSource);
      }
    },
    resize() {
      return this.$refs.table?.sidebar?.resize();
    },

    createDragLine() {
      let el = this.constructor.extend({
        data() {
          return { x: 0, y: 0, show: false, rowEdge: false };
        },
        render() {
          return this._c('div', {
            class: ['t-table-drag-line', this.rowEdge && 'row-edge'],
            directives: [{ name: 'show', value: this.show }],
            style: {
              transform: `translate(${this.x}px,${this.y}px)`
            }
          });
        }
      });

      return new el().$mount();
    },
    customScrollbarFN,

    filterOnReset(map) {
      let sColumns = this.defaultColumns||this.sColumns;


        for (let i = 0; i<sColumns.length; i++){
          try {
            let col = thissColumns[i];
            let mapItem = map[col.dataIndex];
            if (mapItem) {
              col._s=mapItem._s
              col.hidden=mapItem.hidden
              col.width=mapItem.width
            }
          } catch (err) {
            throw new Error(err);

          }

        }
        sColumns.sort((a, b) => {
          return a._s - b._s;
        });
        this.$forceUpdate()

    },
    filterOnConfirm(map, fu) {
      let sColumns = this.defaultColumns||this.sColumns;


      for (let i = 0; i<sColumns.length; i++){
        try {
          let col = sColumns[i];
          let mapItem = map[col.dataIndex];
          if (mapItem) {
            col._s=mapItem._s
            col.hidden=mapItem.hidden
            col.width=mapItem.width
          }
        } catch (err) {
          throw new Error(err);

        }

      }
      sColumns.sort((a, b) => {
        return a._s - b._s;
      });
      fu?.()


    },



    renderFilterTitle() {
      let _this=this
      const {
        defaultCountKey,
        filterOnReset,
        filterOnConfirm,
        showHeader,
        hasRowCount,
        isSlotsDefault
      } = this;
      let _columns = [];
      if (isSlotsDefault) return '序号';
      let sColumns=isSlotsDefault?this.defaultColumns:this.sColumns
      if (sColumns && sColumns.length > 0) {

      for (let i = 0; i < sColumns.length; i++){
        let { dataIndex, title, _s, width,flex, hidden} = sColumns[i];
        if (dataIndex&&defaultCountKey!=dataIndex&&!flex) {
          _columns.push({ title,dataIndex, _s, width,hidden })
        }
      }

        return showHeader&&hasRowCount ?this._c(tFilterColumns, {
        key:this.$attrs.id_+'_tfilterColumns',
        // ref:'tfilterColumns',
        on: {
          confirm: filterOnConfirm,
          reset: filterOnReset,
          columnPosition(map) {
           return filterOnConfirm(map)
          }

        },
          attrs: {
          ids: this.$attrs.id,
          extendedObjectCode:this.$attrs.extendedObjectCode,
          table:this,
          list:_columns,
          defaultCountKey,


        },

      }):'序号'
     }

    },

    renderColCount(_columns) {
      const { defaultCountKey, isSlotsDefault, showHeader, rowDrag } = this;
      //如果没设置序列
      const def = {
        width: 40,
        key: defaultCountKey,
        ...this.filterDropdownColumn
      };
      const { width, key } = def;

      this.filterTitle=this.filterTitle||this.renderFilterTitle()
      let count = {
        dataIndex: key,
        className: 't-col-count',
        align: 'center',
        skip: true,
        ellipsis: false,
        width,
        title: this.filterTitle,
        //fixed: !this.isExp ? 'left' : false,
        fixed:false,
        className:'ant-table-column-has-actions ant-table-column-has-filters',
        _s: -1
      };

      //行拖拽
      if (rowDrag) {
        let h = this._c,
          v = this._v;
        count.customRender = (text, record, index) => {
          return (
            text &&
            h('div', { class: 'row-drag' }, [
              h('span', { class: 'row-drag-count' }, [v(text || ' ')]),
              h('a-icon', {
                class: 'row-drag-icon',
                style: {
                  fontSize: '14px'
                },
                attrs: { type: 'fullscreen' }
              })
            ])
          );
        };
      }
      return count;
    },

    resolveColumns(props) {
      const { isSlotsDefault,customCell, columns, defaultCountKey, autoColWidth, filterDropdownColumn, dragState } = this;
      const { vScrollX } = props;

      let _columns = columns;
      let s = 0;

      if (isSlotsDefault) {
        _columns = this.normalize(this.$slots['default']);
        s = 1;
      }

      this.fields = {};

      console.log('加入序号列columns');
      //加入序号列columns
      if (_columns && _columns.length > 0) {
        let _i;
        _columns.forEach((col, i) => {
          let k = col.key || col.dataIndex || 'col-th' + i;
          //重复
          if (this.fields[k]) {
            console.warn(k, 'dataIndex重复');
            k = col.dataIndex + '_col-th' + i;
          }
          if (typeof customCell === 'function') {

            col.customCell=customCell
          }


          if ((vScrollX.enabled ? true : autoColWidth) && !col.hasOwnProperty('width')) {
            let i = col?.title?.length ?? 3;
            col.width = i * 12 + 44;
          }
          col.key = k;
          if (k) {
            if (typeof col.fixed === 'undefined') {
              this.$set(col, 'fixed', false);
            }
            if (typeof col.hidden === 'undefined') {
              this.$set(col, 'hidden', false);
            }
            if (typeof col.ellipsis === 'undefined' && !this.editorRowTable && this.dragle) {
              this.$set(col, 'ellipsis', true);
            }
            col._s = s + i;
          }
          let key = k,
            d = dragState[key],
            item = col;
          if (d) {
            if (d.width) {
              this.$set(item, 'width', d.width);
            }
            if (typeof d.hidden !== 'undefined') {
              this.$set(item, 'hidden', d.hidden);
            }
            if (typeof d.fixed !== 'undefined') {
              this.$set(item, 'fixed', d.fixed);
            }
            if (d._s) {
              this.$set(item, '_s', d._s);
            }
          }

          if (typeof item.tooltip === 'undefined') {
            item.tooltip = true;
          }
          this.fields[key] = item;
        });
        if (!isSlotsDefault) {
          this.filterReset = true;
        }


        return _columns;
      }
      this.filterReset = false;

      return [];
    }
  },
  renderError(h,err) {
    console.error(err)
  },
  render(h) {

    const _default = this.$slots.default;
    let $scopedSlots = this.$scopedSlots;
    let props = { ...this.$props };
    const defaultRowHeight = 39;
    const {
      vScrollX,
      vScrollY,
      filterReset,
      customScrollbar,
      isSlotsDefault,
      defaultCountKey,
      showHeader,
      autoMaxHeight,
      hasRowCount,
      attachFooter,
      hasRowSelectCheck,
      selectedRowKeys,
      hideDefaultSelections,
      customCell
    } = this;
    customCell
    props.vScrollY = {
      ...definevScrollY,
      ...vScrollY
    }
    props.vScrollX = {
      ...definevScrollX,
      ...vScrollX
    }

    //this.sPagination;

    if (!filterReset) {
     let sColumns= this.resolveColumns(props);
      if (sColumns && !sColumns.length) {
        return null
      } else {
        if (isSlotsDefault) {
          this.defaultColumns = sColumns
        } else {
          this.sColumns = sColumns
        }
      }
    } else {
      if (!_default) {
        this.filterReset = true;
      }
    }

    let sColumns = this.defaultColumns||this.sColumns;
    if (!sColumns) return null;

    //    props.def = this._def;
    props.loading = this.vLoading;
    props.customRow = this.table_customRow;

    if (!props.rowSelectType) {
      delete props.rowSelection;
    } else {
      props.rowSelection = props.rowSelection ? props.rowSelection : this.row_Selection;
    }

    //配置树型展开图标位置
    if (!props.expandIconColumnIndex) {
      let e_i = 0;
      if (props.rowSelection || props.hasRowCount) {
        e_i = 1;
      }
      if (props.rowSelection && props.hasRowCount) {
        e_i = 2;
      }
      props.expandIconColumnIndex = e_i;
    }

    if (this.isExp) {
      //启用展开scroll不能是undefined,不然会报错
      props.scroll = { ...this.scroll };
    }
    if (this.scroll && (isNaN(this.scroll.x) || typeof this.scroll.x === 'boolean')) {
      props.scroll.x = '100%';
    }

    let lastCol = sColumns[sColumns.length - 1];
    lastCol = lastCol?.key || lastCol?.dataIndex || '';

    // props.components = {
    //   header: {
    //     cell: (h, _props, children) => {
    //       let { key } = _props;
    //       let col = this.fields[key];
    //       if (['rc-table-expand-icon-cell', 'selection-column', defaultCountKey, lastCol].includes(key)) {
    //         return h('th', _props, [children]);
    //       }
    //       return this.renderTH(h, _props, children, { col, columns: sColumns });
    //     }
    //   },
    //   ...props.components
    // };

    let y = props?.scroll?.y ?? undefined;

    if (this?.$el && autoMaxHeight) {
      const { width, height } = this.$el.getBoundingClientRect();

      if (height > 0) {
        let parentStyles = window.getComputedStyle(this.$el);
        let padding = parseFloat(parentStyles.paddingTop) - parseFloat(parentStyles.paddingBottom);
        if (props.pagination) {
          padding = padding + this.paginationHeight;
        }
        y = height - (showHeader ? 40 : 0) - padding;
        this.$el.style.overflowY = 'hidden';
      }
    }
    if (typeof y == 'undefined' && props.vScrollY.enabled) {
      y = defaultRowHeight * props.vScrollY.rows;
    }


    let selectType = ['', 'radio', 'checkbox'];
    props.pagination = this.sPagination;
    props.dataSource = this.tree ? this.treeData : this.tData;

    if (props.dataSource.length === 0) {
      delete props.bodyStyle;
    }

    props.columns =sColumns.filter((col) => {
      let key=col.dataIndex
      if (!col.hidden) {
        if (col.fixed) {
          let fixed = col.fixed;
          col._vc_class = 'ant-table-column-fixed-sticky-' + fixed;
          col.customHeaderCell = (column) => {
            column.class = 'ant-table-column-fixed-sticky-' + fixed;
            return column;
          };
        }
        return true;
      }
    });

    this.colCount = this.colCount || this.renderColCount()
    if (props.columns.length > 0) {
      if (props.columns[0].dataIndex !== defaultCountKey) {
        props.columns.unshift(this.colCount);
      } else {
        props.columns[0]=this.colCount
      }
    }


    //this.renderFilterColumn
    let tConfig = {
      ref: 'table',
      class: [
        't-table',
        selectType[this.rowSelectType] && 't-' + selectType[this.rowSelectType],
        attachFooter && 't-attach-footer',
        customScrollbar && 't-custom-scrollbar',
        props.vScrollX.enabled && 'virtual-scroll-x',
        props.vScrollY.enabled && 'virtual-scroll-y'
      ],
      props: {
        ...props,
        hideDefaultSelections,
        defaultCountKey,
        customCell,
        hasRowSelectCheck,
        scroll: {
          ...props.scroll,
          y
        }
      },
      selectedRowKeys,
      scopedSlots: $scopedSlots,
      slots: this.$slots,
      on: {
        ...this.$listeners,
        'update:dataSource': this.updateDataSource,
        change: this.tableChange,

      }
    };
    return h('a-table', tConfig);
  }
};

ATable.props.tPagination = {
  type: null
};
ATable.props.attachFooter = {
  type: null
};

ATable.props.defaultCountKey = {
  type: null
};
ATable.props.verticalState = {
  type: null
};
ATable.props.getBodyWrapper = {
  type: Function
};
ATable.props.hasRowSelectCheck = {};
ATable.props.selectedRowKeys = {};

ATable.props.getCheckboxProps = {};
ATable.props.setCheckboxProps = {};
ATable.props.rowSelectType = {};
ATable.props.customCell= {
  type: Function
};

ATable.props.vScrollX = {
  type: Object
};
ATable.props.vScrollY = {
  type: Object
};
ATable.props.hideDefaultSelections = {
  type: null
};

Table.TableChild = Table;
export default Table;
