import _defineProperty from "babel-runtime/helpers/defineProperty";
import _toConsumableArray from "babel-runtime/helpers/toConsumableArray";
import _classCallCheck from "babel-runtime/helpers/classCallCheck";
import _createClass from "babel-runtime/helpers/createClass";
import _possibleConstructorReturn from "babel-runtime/helpers/possibleConstructorReturn";
import _inherits from "babel-runtime/helpers/inherits";
import _extends from "babel-runtime/helpers/extends";
import _slicedToArray from "babel-runtime/helpers/slicedToArray";
var __rest = this && this.__rest || function (s, e) {
    var t = {};
    for (var p in s) {
        if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
    }if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
        if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
    }
    return t;
};
import React, { Component } from "react";
import { findDOMNode } from "react-dom";
import AntdTable from "antd/es/table";
import cloneDeep from "lodash/cloneDeep";
import PropTypes from "prop-types";
import { Resizable } from "react-resizable";
import isEqual from "lodash/isEqual";
import isFunction from "lodash/isFunction";
import lodashGet from "lodash/get";
import { DragableBodyRow } from "./dragTable";
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { EditableFormCell, EditableCell } from "./editCell";
import { EditableFormRow, EditableRow } from "./editRow";
import update from "immutability-helper";
import PagePointEnhanced from "../page-point/pagePointEnhanced";
import PagePoint from "../page-point/index";
import { ConfigConsumer } from "../config-provider";
import message from "../message";
import Column from "antd/es/table/Column";
import "antd/es/table/style";
import "@whalecloud/fdx-theme-fdx/table.less";
var DEFAULT_COLUMN_WIDTH = 100;
var DEFAULT_COLUMN_EDITTYPE = "text";
var DEFAULT_COLUMN_OPTIONS_LABEL = "name";
var DEFAULT_COLUMN_OPTIONS_VALUE = "value";
var DEFAULT_PAGE_SIZE = 10;
var sendPagePoint = PagePoint.sendPagePoint,
    regKey = PagePoint.pagePointConfig.regKey,
    clickType = PagePoint.EventType.clickType;

var ResizeableTitle = function ResizeableTitle(props) {
    var onResize = props.onResize,
        width = props.width,
        restProps = __rest(props, ["onResize", "width"]);

    if (!width) {
        return React.createElement("th", restProps);
    }
    return React.createElement(
        Resizable,
        { width: width, height: 0, onResize: onResize },
        React.createElement("th", restProps)
    );
};
// 动态为columnItem创建dataIndex(lowcode专用)
var handleColumns = function handleColumns(columns) {
    if (!columns) return columns;
    columns.forEach(function (column) {
        if (!column.dataIndex && column.render) {
            var render = column.render.toString();
            // 处理column没有dataIndex属性情况
            if (render.includes('createElement("span"')) {
                var matches = render.match(/createElement\(\"span\"[\s\S]*?\)/gi);
                var dataIndex = '';
                if (matches.length > 0) {
                    var dataIndexExpresses = matches[0].split(',');
                    if (dataIndexExpresses.length) {
                        var dataIndexExpress = dataIndexExpresses[dataIndexExpresses.length - 1];

                        var _dataIndexExpress$spl = dataIndexExpress.split('.'),
                            _dataIndexExpress$spl2 = _slicedToArray(_dataIndexExpress$spl, 2),
                            express = _dataIndexExpress$spl2[1];

                        if (express) {
                            dataIndex = express.replace(')', '');
                        }
                    }
                }
                if (dataIndex) {
                    column.dataIndex = dataIndex;
                }
            }
        }
    });
    return columns;
};
var caluColumnWidth = function caluColumnWidth(columns, tableWidth) {
    var someWidth = 0;
    var noWidthCnt = 0;
    var newColumns = columns.map(function (col) {
        var width = void 0;
        if (typeof col.width === "string") {
            if (col.width.includes("%")) {
                width = Math.floor(tableWidth * (parseInt(col.width.replace("%", "")) / 100));
            } else {
                width = +col.width;
            }
        } else if (typeof col.width === "number") {
            width = col.width;
        } else {
            width = 0;
            noWidthCnt++;
        }
        someWidth += width;
        return _extends(_extends({}, col), { width: width });
    });
    if (noWidthCnt) {
        var restWidth = parseFloat(((tableWidth - someWidth) / noWidthCnt).toFixed(2));
        newColumns = newColumns.map(function (col) {
            if (!col.width) {
                col.width = restWidth;
            }
            return col;
        });
    }
    return newColumns;
};
// 根据value找到key(深度遍历)
var findKeyByValue = function findKeyByValue(value, obj) {
    var allKeys = {};
    var map = function map(mapObj, parentKey) {
        if (typeof mapObj === 'object' && !Array.isArray(mapObj)) {
            Object.keys(mapObj).forEach(function (key) {
                var realKey = key;
                var val = mapObj[key];
                if (parentKey) {
                    realKey = parentKey + "." + key;
                }
                allKeys[realKey] = val;
                if (val && typeof val === 'object') {
                    map(val, realKey);
                }
            });
        }
    };
    map(obj);
    var targetKey = Object.keys(allKeys).find(function (key) {
        return allKeys[key] === value;
    });
    return targetKey;
};

var Table = function (_Component) {
    _inherits(Table, _Component);

    function Table(props) {
        _classCallCheck(this, Table);

        var _a;

        var _this = _possibleConstructorReturn(this, (Table.__proto__ || Object.getPrototypeOf(Table)).call(this, props));

        _this.handleSave = function (row, type) {
            var _this$props = _this.props,
                rowKey = _this$props.rowKey,
                onSaveRowEdit = _this$props.onSaveRowEdit,
                onSaveCellEdit = _this$props.onSaveCellEdit,
                onCancelRowEdit = _this$props.onCancelRowEdit;
            var dataSource = _this.state.dataSource;

            var newData = [].concat(_toConsumableArray(dataSource));
            var tableKey = '';
            if (isFunction(rowKey)) {
                tableKey = findKeyByValue(rowKey(row), row);
            } else {
                tableKey = rowKey;
            }
            var index = newData.findIndex(function (item) {
                return lodashGet(row, tableKey) === lodashGet(item, tableKey);
            });
            if (index > -1) {
                var item = newData[index];
                newData.splice(index, 1, _extends(_extends({}, item), row));
                _this.setState({ dataSource: newData, update: true });
            } else {
                // 新增功能
                newData.push(row);
                _this.setState({ dataSource: newData, update: true });
            }
            var dataRegId = _this.props[regKey];

            if (type === "save") {
                onSaveRowEdit(row, newData);
                if (dataRegId) sendPagePoint(_defineProperty({
                    eventType: clickType,
                    tagname: "table",
                    value: row
                }, regKey, dataRegId));
            } else if (type === "cancel") {
                onCancelRowEdit(row);
            } else if (type === "saveCell") {
                onSaveCellEdit(newData[index], index);
            }
        };
        _this.moveRow = function (dragIndex, hoverIndex) {
            var dataSource = _this.state.dataSource;
            var afterRowDrag = _this.props.afterRowDrag;

            var dragRow = dataSource[dragIndex];
            /* eslint-disable */
            var dragData = update(dataSource, {
                $splice: [[dragIndex, 1], [hoverIndex, 0, dragRow]]
            });
            afterRowDrag(dragData);
            _this.setState({ dataSource: dragData, update: true });
        };
        _this.handleResize = function (index) {
            return function (_e, _ref) {
                var size = _ref.size;

                _this.setState(function (_ref2) {
                    var columns = _ref2.columns;

                    var nextColumns = [].concat(_toConsumableArray(columns));
                    nextColumns[index] = _extends(_extends({}, nextColumns[index]), { width: size.width });
                    return { columns: nextColumns, update: true };
                });
            };
        };
        _this.isEditing = function (record) {
            var rowKey = _this.props.rowKey;

            var key = isFunction(rowKey) ? rowKey(record) : record[rowKey];
            var editingKey = _this.state.editingKey;

            return key === editingKey;
        };
        _this.toggleEditRow = function () {
            var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
            var record = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
            var method = arguments[2];
            var _this$props2 = _this.props,
                onRowEditing = _this$props2.onRowEditing,
                saveAddRowMsg = _this$props2.saveAddRowMsg;

            if (method === 'edit' && _this.state.freezAddRow) {
                message.warn(saveAddRowMsg || '请先保存当前新增行！');
                return;
            }
            if (key) {
                onRowEditing(record);
            }
            _this.setState({ editingKey: key, update: true, freezAddRow: false });
        };
        _this.judgeCellEdit = function (columns) {
            return columns.some(function (item) {
                return item.editable === true;
            });
        };
        _this.selectRow = function (record) {
            _this.setState({ highlightRow: record, update: true });
        };
        _this.handleSelectRow = function (selectedRowKeys, selectedRows, onChange) {
            var onSelectRows = _this.props.onSelectRows;

            if (onChange) {
                onChange(selectedRowKeys, selectedRows);
            }
            if (onSelectRows) {
                onSelectRows(selectedRowKeys);
            }
        };
        _this.handleRowSelection = function (selection) {
            var selectType = _this.props.selectType;

            var rowSelection = typeof selection === 'boolean' ? {} : selection || {};
            if (selectType === 'radio') {
                rowSelection.type = selectType;
            }
            var newRowSelection = _extends(_extends({}, rowSelection), { onChange: function onChange(selectedRowKeys, selectedRows) {
                    return _this.handleSelectRow(selectedRowKeys, selectedRows, rowSelection.onChange);
                } });
            if (!newRowSelection.onChange) {}
            return newRowSelection;
        };
        _this.handleTableChange = function (pagination, filters, sorter, extra) {
            var _this$props3 = _this.props,
                onChange = _this$props3.onChange,
                onSortChange = _this$props3.onSortChange;

            if (onChange) {
                onChange(pagination, filters, sorter, extra);
            }
            // 分页 筛选 排序都会触发onChange，需要区分排序
            if (onSortChange) {
                var currentSortInfo = _this.state.currentSortInfo;

                if (currentSortInfo.field !== sorter.field || currentSortInfo.order !== sorter.order) {
                    onSortChange(sorter.field, sorter.order);
                    _this.setState({ currentSortInfo: { field: sorter.field, order: sorter.order } });
                }
            }
        };
        _this.handlePageChange = function (currentPage, pageSize) {
            if (_this.state.freezAddRow) {
                message.warn(_this.props.saveAddRowMsg || '请先保存当前新增行！');
                return;
            }
            if (_this.props.pagination && _this.props.pagination.onChange) {
                _this.props.pagination.onChange(currentPage, pageSize);
            } else if (_this.props.pagination) {
                _this.setState({
                    currentPage: currentPage
                });
            }
        };
        var _this$props4 = _this.props,
            dataSource = _this$props4.dataSource,
            editingKey = _this$props4.editingKey,
            highlightRow = _this$props4.highlightRow,
            children = _this$props4.children;

        var newColumns = [];
        if (children) {
            if (Array.isArray(children)) {
                for (var i = 0; i < children.length; i++) {
                    var child = children[i];
                    if (child.props) {
                        newColumns.push(child.props);
                    }
                }
            } else {
                newColumns.push(children.props);
            }
            newColumns = handleColumns(cloneDeep(newColumns));
        } else {
            newColumns = handleColumns(cloneDeep(_this.props.columns));
        }
        _this.state = {
            tableWidth: 0,
            columns: newColumns,
            dataSource: dataSource,
            editingKey: editingKey,
            update: false,
            highlightRow: highlightRow,
            currentSortInfo: {},
            currentPage: ((_a = _this.props.pagination) === null || _a === void 0 ? void 0 : _a.current) || 1,
            freezAddRow: false,
            copyDataSource: dataSource
        };
        return _this;
    }

    _createClass(Table, [{
        key: "componentDidMount",
        value: function componentDidMount() {
            var columns = this.state.columns;

            var newColumns = caluColumnWidth(columns, this.table.offsetWidth);
            if (this.table && !isEqual(columns, newColumns)) {
                this.setState({
                    columns: newColumns,
                    update: true,
                    tableWidth: this.table.offsetWidth
                });
            }
        }
    }, {
        key: "render",
        value: function render() {
            var _this2 = this;

            var _props = this.props,
                dragable = _props.dragable,
                _rowClassName = _props.rowClassName,
                editRow = _props.editRow,
                rowKey = _props.rowKey,
                onRow = _props.onRow,
                propRowSelection = _props.rowSelection,
                onSelectRows = _props.onSelectRows,
                onSortChange = _props.onSortChange;
            var _state = this.state,
                columns = _state.columns,
                dataSource = _state.dataSource,
                highlightRow = _state.highlightRow;

            var rowSelection = typeof propRowSelection === 'boolean' ? {} : propRowSelection;
            var editClass = "";
            if (editRow || this.judgeCellEdit(columns)) {
                editClass += "editable-row ";
            }
            this.components = {
                header: {
                    cell: ResizeableTitle
                }
            };
            if (editRow) {
                this.components.body = {
                    row: EditableFormRow,
                    cell: EditableRow
                };
            } else if (this.judgeCellEdit(columns)) {
                this.components.body = {
                    row: EditableFormCell,
                    cell: EditableCell
                };
            } else if (dragable) {
                this.components.body = {
                    row: DragableBodyRow
                };
            }
            var onRowNew = function onRowNew(record, index) {
                return _extends(_extends(_extends({}, dragable ? { moveRow: _this2.moveRow } : {}), onRow ? onRow(record, index) : {}), { index: index, onClick: function onClick(event) {
                        function findDomAncestor(dom) {
                            if (dom.nodeName === "A" || dom.nodeName === "BUTTON" || dom.nodeName === "INPUT") {
                                return true;
                            } else if (dom.nodeName === "BODY") {
                                return false;
                            } else {
                                return findDomAncestor(dom.parentNode);
                            }
                        }
                        if (findDomAncestor(event.target)) {
                            return;
                        }
                        if (onRow && onRow(record, index)["onClick"]) {
                            onRow(record, index)["onClick"](event);
                        }
                        _this2.selectRow(record);
                    } });
            };
            var opts = _extends(_extends({}, this.props), { rowSelection: rowSelection, components: this.components, dataSource: dataSource, columns: columns.map(function (col, index) {
                    return _extends(_extends(_extends({}, col), { onHeaderCell: function onHeaderCell(column) {
                            return {
                                width: column.width || DEFAULT_COLUMN_WIDTH,
                                onResize: _this2.handleResize(index)
                            };
                        } }), col.editable ? {
                        onCell: function onCell(record) {
                            return _extends({ record: record, width: col.width || DEFAULT_COLUMN_WIDTH, editType: col.editType || DEFAULT_COLUMN_EDITTYPE, dataIndex: col.dataIndex, editRules: col.editRules, editOptions: col.editOptions || [], optionsLabel: col.optionsLabel || DEFAULT_COLUMN_OPTIONS_LABEL, optionsValue: col.optionsValue || DEFAULT_COLUMN_OPTIONS_VALUE, editInitValue: col.editInitValue, title: col.title, editContent: isFunction(col.editContent) ? col.editContent() : "Edit", saveContent: isFunction(col.saveContent) ? col.saveContent() : "Save", cancelContent: isFunction(col.cancelContent) ? col.cancelContent() : "Cancel" }, editRow ? {
                                editing: _this2.isEditing(record),
                                handleSave: _this2.handleSave,
                                toggleEditRow: _this2.toggleEditRow,
                                keyValue: isFunction(rowKey) ? rowKey(record) : record[rowKey]
                            } : { editable: col.editable, handleSave: _this2.handleSave });
                        }
                    } : {});
                }), rowClassName: function rowClassName(record, index) {
                    var res = [];
                    if (_rowClassName) {
                        res.push(_rowClassName(record, index));
                    }
                    if (editClass) {
                        res.push(editClass);
                    }
                    if (isFunction(rowKey)) {
                        if (rowKey(record) === rowKey(highlightRow)) {
                            res.push("fdx-table-row-selected");
                        }
                    } else {
                        if (record[rowKey] === highlightRow[rowKey]) {
                            res.push("fdx-table-row-selected");
                        }
                    }
                    return res.join(" ");
                }, ref: function ref(_ref3) {
                    _this2.table = findDOMNode(_ref3);
                } });
            // 若用户直接设置rowSelection=true，或rowSelection未定义onChange 则行选择在table内部处理并触发onSelectRows
            if (onSelectRows) {
                opts.rowSelection = this.handleRowSelection(rowSelection);
            }
            // 若用户设置onSortChange,需要在内部onChange事件并触发onSortChange
            if (onSortChange) {
                opts.onChange = this.handleTableChange;
            }
            return React.createElement(
                DndProvider,
                { backend: HTML5Backend },
                React.createElement(
                    ConfigConsumer,
                    null,
                    function (_ref4) {
                        var pagePoint = _ref4.pagePoint;
                        return React.createElement(
                            "div",
                            { className: "fdx-table" },
                            pagePoint ? React.createElement(PagePointEnhanced, _extends({ compType: "Table" }, _this2.props, { onRow: onRowNew, render: function render(eventprops) {
                                    return React.createElement(AntdTable, _extends({}, opts, { rowSelection: rowSelection ? _extends(_extends({}, rowSelection), eventprops.onChange ? { onChange: eventprops.onChange } : {}) : null, onRow: eventprops.onRow ? eventprops.onRow : onRowNew, pagination: opts.pagination ? _extends({ current: _this2.state.currentPage, onChange: _this2.handlePageChange }, opts.pagination) : false, "data-ui-role": "Table" }));
                                } })) : React.createElement(AntdTable, _extends({}, opts, { pagination: opts.pagination ? _extends({ current: _this2.state.currentPage, onChange: _this2.handlePageChange }, opts.pagination) : false, onRow: onRowNew }))
                        );
                    }
                )
            );
        }
    }], [{
        key: "getDerivedStateFromProps",
        value: function getDerivedStateFromProps(nextProps, prevState) {
            var changeObj = {};
            if (nextProps.editingKey !== prevState.editingKey) {
                if (nextProps.update === prevState.update) {
                    changeObj.editingKey = nextProps.editingKey;
                } else {
                    changeObj.update = false;
                }
            }
            if (!isEqual(nextProps.columns, prevState.columns)) {
                if (nextProps.columns && nextProps.update === prevState.update) {
                    var newColumns = nextProps.columns;
                    if (nextProps.columns.findIndex(function (col) {
                        return !col.width;
                    }) !== -1) {
                        //如果传入的columns中有位置width的列，则重新算一下每列的width，确保每一列都有确定的width
                        newColumns = caluColumnWidth(nextProps.columns, prevState.tableWidth);
                    }
                    changeObj.columns = newColumns;
                } else {
                    changeObj.update = false;
                }
            }
            if (nextProps.children) {
                var columns = prevState.columns;
                var children = nextProps.children;

                var _newColumns = [];
                if (Array.isArray(children)) {
                    for (var i = 0; i < children.length; i++) {
                        var child = children[i];
                        if (child.props) {
                            _newColumns.push(child.props);
                        }
                    }
                } else {
                    _newColumns.push(children.props);
                }
                _newColumns = handleColumns(cloneDeep(_newColumns));
                if (!isEqual(columns, _newColumns) && nextProps.update === prevState.update) {
                    changeObj.columns = _newColumns;
                } else {
                    changeObj.update = false;
                }
            }
            if (!isEqual(nextProps.highlightRow, prevState.highlightRow)) {
                if (nextProps.update === prevState.update) {
                    changeObj.highlightRow = nextProps.highlightRow;
                } else {
                    changeObj.update = false;
                }
            }
            if (!isEqual(nextProps.dataSource, prevState.dataSource)) {
                if (!prevState.freezAddRow && nextProps.update === prevState.update) {
                    changeObj.dataSource = nextProps.dataSource;
                } else {
                    changeObj.copyDataSource = nextProps.dataSource;
                    changeObj.update = false;
                }
                if (nextProps.editRow && nextProps.dataSource.length - prevState.dataSource.length === 1) {
                    changeObj.freezAddRow = true;
                }
                if (nextProps.dataSource.length >= prevState.dataSource.length) {
                    if (!prevState.freezAddRow && nextProps.pagination && !nextProps.pagination.onChange) {
                        var pageSize = nextProps.pagination.pageSize || DEFAULT_PAGE_SIZE;
                        if (nextProps.dataSource.length / pageSize > prevState.currentPage) {
                            changeObj.currentPage = Math.ceil(nextProps.dataSource.length / pageSize);
                        }
                    }
                    if (nextProps.editRow && prevState.freezAddRow && prevState.editingKey && nextProps.editingKey !== prevState.editingKey) {
                        changeObj.editingKey = prevState.editingKey;
                        if (!isEqual(nextProps.dataSource, prevState.copyDataSource)) {
                            message.warn(nextProps.saveAddRowMsg || '请先保存当前新增行！');
                        }
                    }
                } else if (nextProps.editRow) {
                    changeObj.freezAddRow = false;
                    changeObj.editingKey = '';
                    changeObj.dataSource = nextProps.dataSource;
                }
            } else {
                // 如果不把 state 中的 update 重置为 false 在先编辑行，再新增行的场景 新增行会有一行的延迟
                changeObj.update = false;
            }
            return Object.keys(changeObj).length ? changeObj : null;
        }
    }]);

    return Table;
}(Component);

Table.componentName = "Table";
Table.Column = Column;
Table.propTypes = {
    dragable: PropTypes.bool,
    editRow: PropTypes.bool,
    onSaveCellEdit: PropTypes.func,
    onSaveRowEdit: PropTypes.func,
    editingKey: PropTypes.string,
    highlightRow: PropTypes.object,
    onCancelRowEdit: PropTypes.func,
    onRowEditing: PropTypes.func,
    afterRowDrag: PropTypes.func,
    onSortChange: PropTypes.func,
    onSelectRows: PropTypes.func
};
Table.defaultProps = {
    pagination: false,
    dragable: false,
    bordered: true,
    editRow: false,
    rowKey: "key",
    size: "small",
    //扩展属性
    update: false,
    highlightRow: {},
    editingKey: "",
    onSaveCellEdit: function onSaveCellEdit() {},
    onSaveRowEdit: function onSaveRowEdit() {},
    onCancelRowEdit: function onCancelRowEdit() {},
    onRowEditing: function onRowEditing() {},
    afterRowDrag: function afterRowDrag() {}
};
export default Table;