/**
 * amis-ui v6.14.0-beta.1
 * Copyright 2018-2025 fex
 */

import { __extends, __spreadArray, __read, __decorate, __metadata, __values } from 'tslib';
import React__default from 'react';
import { getTreeAncestors, findTree, flattenTree, getTreeDepth, autobind, themeable } from 'amis-core';
import intersectionBy from 'lodash/intersectionBy';
import compact from 'lodash/compact';
import find from 'lodash/find';
import uniqBy from 'lodash/uniqBy';
import Button from './Button.js';
import Checkbox from './Checkbox.js';
import { Icon } from './icons.js';

/**
 * @file Cascader
 * @author fex
 */
var Cascader = /** @class */ (function (_super) {
    __extends(Cascader, _super);
    function Cascader(props) {
        var _this = _super.call(this, props) || this;
        _this.tabsRef = React__default.createRef();
        _this.tabRef = React__default.createRef();
        _this.getParentTree = function (option, arr) {
            var parentOption = _this.getOptionParent(option);
            if (parentOption) {
                arr.push(parentOption);
                return _this.getParentTree(parentOption, arr);
            }
            return arr;
        };
        _this.state = {
            activePaths: [],
            selectedOptions: _this.props.selectedOptions || [],
            tabs: [
                {
                    options: _this.props.options.slice() || []
                }
            ],
            disableConfirm: false
        };
        return _this;
    }
    Cascader.prototype.componentDidMount = function () {
        var _a = this.props, multiple = _a.multiple, options = _a.options, _b = _a.valueField, valueField = _b === void 0 ? 'value' : _b, cascade = _a.cascade; _a.onlyLeaf;
        var selectedOptions = this.props.selectedOptions.slice();
        var parentsCount = 0;
        var parentTree = [];
        selectedOptions.forEach(function (item) {
            var parents = getTreeAncestors(options, item);
            // 获取最长路径
            if (parents && (parents === null || parents === void 0 ? void 0 : parents.length) > parentsCount) {
                parentTree = parents;
                parentsCount = parentTree.length;
            }
        });
        var selectedValues = selectedOptions.map(function (option) { return option[valueField]; });
        var tabs = parentTree.map(function (option) {
            var _a;
            if (multiple && !cascade) {
                if (selectedValues.includes(option[valueField]) &&
                    ((_a = option === null || option === void 0 ? void 0 : option.children) === null || _a === void 0 ? void 0 : _a.length)) {
                    option.children.forEach(function (option) { return (option.disabled = true); });
                }
            }
            return {
                options: option.children ? option.children : []
            };
        });
        this.setState({
            selectedOptions: selectedOptions,
            tabs: __spreadArray(__spreadArray([], __read(this.state.tabs), false), __read(tabs), false)
        });
    };
    Cascader.prototype.getOptionParent = function (option) {
        var _a = this.props, options = _a.options, _b = _a.valueField, valueField = _b === void 0 ? 'value' : _b;
        var ancestors = [];
        findTree(options, function (item, index, level, paths) {
            if (item[valueField] === option[valueField]) {
                ancestors = paths;
                return true;
            }
            return false;
        });
        return ancestors.length ? ancestors[ancestors.length - 1] : null;
    };
    Cascader.prototype.dealParentSelect = function (option, selectedOptions) {
        var _a;
        var _b = this.props, _c = _b.valueField, valueField = _c === void 0 ? 'value' : _c, onlyLeaf = _b.onlyLeaf;
        var parentOption = this.getOptionParent(option);
        if (parentOption && !onlyLeaf) {
            var parentChildren = parentOption === null || parentOption === void 0 ? void 0 : parentOption.children;
            var equalOption = intersectionBy(selectedOptions, parentChildren, valueField);
            // 包含则选中父节点
            var isParentSelected = find(selectedOptions, (_a = {},
                _a[valueField] = parentOption[valueField],
                _a));
            if (equalOption.length === (parentChildren === null || parentChildren === void 0 ? void 0 : parentChildren.length) && !isParentSelected) {
                selectedOptions.push(parentOption);
            }
            if (equalOption.length !== (parentChildren === null || parentChildren === void 0 ? void 0 : parentChildren.length) && isParentSelected) {
                var index = selectedOptions.findIndex(function (item) { return item[valueField] === parentOption[valueField]; });
                selectedOptions.splice(index, 1);
            }
            return this.dealParentSelect(parentOption, selectedOptions);
        }
        else {
            return selectedOptions;
        }
    };
    Cascader.prototype.flattenTreeWithLeafNodes = function (option) {
        return compact(flattenTree(Array.isArray(option) ? option : [option], function (node) { return node; }));
    };
    Cascader.prototype.adjustOptionSelect = function (option) {
        var _a = this.props.valueField, valueField = _a === void 0 ? 'value' : _a;
        var selectedOptions = this.state.selectedOptions;
        function loop(arr) {
            if (!arr.length) {
                return false;
            }
            return arr.some(function (item) { return item[valueField] === option[valueField]; });
        }
        return loop(selectedOptions);
    };
    // 判断配置onlyChildren属性时节点选中情况
    Cascader.prototype.getOnlyChildrenSelect = function (option, selectedOptions) {
        var _a;
        var onlyChildren = this.props.onlyChildren;
        selectedOptions = selectedOptions || this.state.selectedOptions;
        return (onlyChildren &&
            ((_a = option.children) === null || _a === void 0 ? void 0 : _a.filter(function (option) { var _a; return !((_a = option.children) === null || _a === void 0 ? void 0 : _a.length); }).every(function (option) { var _a; return !((_a = option.children) === null || _a === void 0 ? void 0 : _a.length) && (selectedOptions === null || selectedOptions === void 0 ? void 0 : selectedOptions.includes(option)); })));
    };
    Cascader.prototype.getSelectedChildNum = function (option) {
        var _this = this;
        var count = 0;
        var loop = function (arr) {
            var e_1, _a;
            if (!arr || !arr.length) {
                return;
            }
            try {
                for (var arr_1 = __values(arr), arr_1_1 = arr_1.next(); !arr_1_1.done; arr_1_1 = arr_1.next()) {
                    var item = arr_1_1.value;
                    if (item.children) {
                        loop(item.children || []);
                    }
                    else {
                        if (_this.adjustOptionSelect(item)) {
                            count++;
                        }
                    }
                }
            }
            catch (e_1_1) { e_1 = { error: e_1_1 }; }
            finally {
                try {
                    if (arr_1_1 && !arr_1_1.done && (_a = arr_1.return)) _a.call(arr_1);
                }
                finally { if (e_1) throw e_1.error; }
            }
        };
        loop(option.children || []);
        return count;
    };
    Cascader.prototype.dealOptionDisable = function (selectedOptions) {
        var _a = this.props, _b = _a.valueField, valueField = _b === void 0 ? 'value' : _b, options = _a.options, cascade = _a.cascade, multiple = _a.multiple, onlyLeaf = _a.onlyLeaf, onlyChildren = _a.onlyChildren // 子节点可点击
        ;
        if (!multiple || cascade || onlyChildren || onlyLeaf) {
            return;
        }
        var selectedValues = selectedOptions.map(function (option) { return option[valueField]; });
        var loop = function (option) {
            if (!option.children) {
                return;
            }
            option.children &&
                option.children.forEach(function (childOption) {
                    if (!selectedValues.includes(option[valueField]) &&
                        !option.disabled) {
                        childOption.disabled = false;
                    }
                    if (selectedValues.includes(option[valueField]) || option.disabled) {
                        childOption.disabled = true;
                    }
                    loop(childOption);
                });
        };
        options.forEach(function (option) { return loop(option); });
    };
    Cascader.prototype.dealChildrenSelect = function (option, selectedOptions) {
        var _a;
        var _b = this.props, _c = _b.valueField, valueField = _c === void 0 ? 'value' : _c, onlyChildren = _b.onlyChildren;
        var index = selectedOptions.findIndex(function (item) { return item[valueField] === option[valueField]; });
        var isSelect = this.getOnlyChildrenSelect(option, selectedOptions);
        if (index !== -1) {
            selectedOptions.splice(index, 1);
        }
        else if (!isSelect) {
            if (!(onlyChildren && ((_a = option.children) === null || _a === void 0 ? void 0 : _a.length))) {
                selectedOptions.push(option);
            }
        }
        function loop(option) {
            if (!option.children) {
                return;
            }
            option.children.forEach(function (item) {
                var _a;
                if (index !== -1 || isSelect) {
                    // 删除选中节点及其子节点
                    selectedOptions = selectedOptions.filter(function (sItem) { return sItem[valueField] !== item[valueField]; });
                }
                else {
                    // 添加节点及其子节点
                    if (!(onlyChildren && ((_a = item.children) === null || _a === void 0 ? void 0 : _a.length))) {
                        selectedOptions.push(item);
                    }
                }
                loop(item);
            });
        }
        loop(option);
        return selectedOptions;
    };
    Cascader.prototype.onSelect = function (option, tabIndex) {
        var _a;
        var _b = this.props, multiple = _b.multiple, _c = _b.valueField, valueField = _c === void 0 ? 'value' : _c, cascade = _b.cascade, onlyLeaf = _b.onlyLeaf, onlyChildren = _b.onlyChildren, withChildren = _b.withChildren;
        var selectedOptions = this.state.selectedOptions;
        var isDisable = option.disabled;
        if (!isDisable) {
            if (multiple) {
                // 父子级分离
                if (cascade) {
                    var index = selectedOptions.findIndex(function (item) { return item[valueField] === option[valueField]; });
                    if (index !== -1) {
                        selectedOptions.splice(index, 1);
                    }
                    else {
                        selectedOptions.push(option);
                    }
                }
                else {
                    if (withChildren || onlyChildren) {
                        selectedOptions = this.dealChildrenSelect(option, selectedOptions);
                    }
                    else {
                        var index = selectedOptions.findIndex(function (item) { return item[valueField] === option[valueField]; });
                        if (index !== -1) {
                            selectedOptions.splice(index, 1);
                        }
                        else {
                            selectedOptions.push(option);
                        }
                    }
                    selectedOptions = this.dealParentSelect(option, selectedOptions);
                }
            }
            else {
                // 单选
                if (onlyLeaf) {
                    if (!((_a = option.children) === null || _a === void 0 ? void 0 : _a.length)) {
                        selectedOptions = [option];
                    }
                }
                else {
                    selectedOptions = [option];
                }
            }
        }
        this.dealOptionDisable(selectedOptions);
        var disableConfirm = false;
        if (onlyLeaf && selectedOptions.length && selectedOptions[0].children) {
            disableConfirm = true;
        }
        this.setState({
            selectedOptions: selectedOptions,
            disableConfirm: disableConfirm
        });
    };
    Cascader.prototype.handleExpand = function (option, tabIndex) {
        var _this = this;
        var _a;
        var activePaths = this.state.activePaths.slice();
        if ((_a = option.children) === null || _a === void 0 ? void 0 : _a.length) {
            activePaths[tabIndex] = option;
        }
        else {
            activePaths.splice(tabIndex);
        }
        var tabs = this.state.tabs.slice();
        if (tabs.length > tabIndex + 1) {
            tabs = tabs.slice(0, tabIndex + 1);
        }
        if (option === null || option === void 0 ? void 0 : option.children) {
            var nextTab = {
                options: option.children
            };
            if (tabs[tabIndex + 1]) {
                tabs[tabIndex + 1] = nextTab;
            }
            else {
                tabs.push(nextTab);
            }
        }
        requestAnimationFrame(function () {
            var _a, _b;
            var tabWidth = ((_a = _this.tabRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 1;
            var parentTree = _this.getParentTree(option, [option]);
            var scrollLeft = (parentTree.length - 2) * tabWidth;
            if (scrollLeft !== 0) {
                (_b = _this.tabsRef.current) === null || _b === void 0 ? void 0 : _b.scrollTo(scrollLeft, 0);
            }
        });
        this.setState({
            activePaths: activePaths,
            tabs: tabs
        });
    };
    Cascader.prototype.getSubmitOptions = function (selectedOptions) {
        var _selectedOptions = [];
        var _a = this.props, multiple = _a.multiple, options = _a.options, _b = _a.valueField, valueField = _b === void 0 ? 'value' : _b, cascade = _a.cascade, onlyChildren = _a.onlyChildren, withChildren = _a.withChildren;
        if (cascade || onlyChildren || withChildren || !multiple) {
            return selectedOptions;
        }
        var selectedValues = selectedOptions.map(function (option) { return option[valueField]; });
        function loop(options) {
            if (!options || !options.length) {
                return;
            }
            options.forEach(function (option) {
                if (selectedValues.includes(option[valueField])) {
                    _selectedOptions.push(option);
                }
                else {
                    loop(option.children ? option.children : []);
                }
            });
        }
        loop(options);
        return _selectedOptions;
    };
    Cascader.prototype.confirm = function () {
        var _a = this.props, onChange = _a.onChange, onClose = _a.onClose, onlyLeaf = _a.onlyLeaf;
        var selectedOptions = this.getSelectedOptions();
        if (onlyLeaf && selectedOptions.length && selectedOptions[0].children) {
            return;
        }
        onChange(selectedOptions);
        onClose && onClose();
    };
    Cascader.prototype.getSelectedOptions = function () {
        return uniqBy(this.getSubmitOptions(this.state.selectedOptions), this.props.valueField);
    };
    Cascader.prototype.renderOption = function (option, tabIndex) {
        var _this = this;
        var _a, _b, _c;
        var _d = this.props, onlyLeaf = _d.onlyLeaf, activeColor = _d.activeColor, optionRender = _d.optionRender, labelField = _d.labelField, _e = _d.valueField, valueField = _e === void 0 ? 'value' : _e, multiple = _d.multiple, cx = _d.classnames;
        var _f = this.state, selectedOptions = _f.selectedOptions, activePaths = _f.activePaths;
        var selectedValueArr = selectedOptions.map(function (item) { return item[valueField]; });
        var selfChecked = selectedValueArr.includes(option[valueField]);
        var color = option.color || (selfChecked ? activeColor : undefined);
        var Text = optionRender ? (optionRender({ option: option, selected: selfChecked })) : (React__default.createElement("span", null, option[labelField]));
        return (React__default.createElement("li", { className: cx('Cascader-option', {
                'selected': selfChecked,
                'disabled': option.disabled,
                'is-active': activePaths.includes(option)
            }, option.className), style: { color: color }, key: tabIndex + '-' + option[valueField], onClick: function () {
                !multiple && _this.onSelect(option, tabIndex);
                _this.handleExpand(option, tabIndex);
            } },
            multiple ? (React__default.createElement(Checkbox, { disabled: option.disabled || (onlyLeaf && ((_a = option.children) === null || _a === void 0 ? void 0 : _a.length)), checked: selectedOptions.includes(option) ||
                    this.getOnlyChildrenSelect(option), onChange: function () { return _this.onSelect(option, tabIndex); } },
                React__default.createElement("span", { className: cx('Cascader-option--text') }, Text))) : (React__default.createElement("span", { className: cx('Cascader-option--text', {
                    disabled: onlyLeaf && ((_b = option.children) === null || _b === void 0 ? void 0 : _b.length)
                }) }, Text)),
            ((_c = option.children) === null || _c === void 0 ? void 0 : _c.length) ? (React__default.createElement("span", { className: cx('Cascader-option-arrow') },
                React__default.createElement(Icon, { icon: "right-arrow-bold", className: "icon" }))) : null));
    };
    Cascader.prototype.renderOptions = function (options, tabIndex) {
        var _this = this;
        var cx = this.props.classnames;
        return (React__default.createElement("ul", { key: tabIndex, className: cx('Cascader-options') }, options.map(function (option) { return _this.renderOption(option, tabIndex); })));
    };
    Cascader.prototype.renderTabs = function () {
        var _this = this;
        var _a = this.props, cx = _a.classnames, options = _a.options;
        var tabs = this.state.tabs;
        var depth = getTreeDepth(options);
        return (React__default.createElement("div", { className: cx("Cascader-tabs", depth > 3 ? 'scrollable' : ''), ref: this.tabsRef },
            tabs.map(function (tab, tabIndex) {
                var options = tab.options;
                return (React__default.createElement("div", { className: cx("Cascader-tab depth-".concat(tabIndex)), ref: _this.tabRef, key: tabIndex }, _this.renderOptions(options, tabIndex)));
            }),
            depth <= 3 && options.length
                ? Array(getTreeDepth(options) - tabs.length)
                    .fill(1)
                    .map(function (item, index) { return (React__default.createElement("div", { className: cx("Cascader-tab depth-".concat(index + 1)), key: index })); })
                : null));
    };
    Cascader.prototype.render = function () {
        var _a = this.props; _a.classPrefix; var cx = _a.classnames, className = _a.className, onClose = _a.onClose; _a.valueField; var __ = _a.translate;
        return (React__default.createElement("div", { className: cx("Cascader", className) },
            React__default.createElement("div", { className: cx("Cascader-btnGroup") },
                React__default.createElement(Button, { className: cx("Cascader-btnCancel"), level: "link", onClick: onClose }, __('cancel')),
                React__default.createElement(Button, { className: cx("Cascader-btnConfirm"), level: "link", onClick: this.confirm, disabled: this.state.disableConfirm }, __('confirm'))),
            this.renderTabs()));
    };
    Cascader.defaultProps = {
        labelField: 'label',
        valueField: 'value'
    };
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object]),
        __metadata("design:returntype", void 0)
    ], Cascader.prototype, "getOptionParent", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object, Object]),
        __metadata("design:returntype", Object)
    ], Cascader.prototype, "dealParentSelect", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object]),
        __metadata("design:returntype", void 0)
    ], Cascader.prototype, "flattenTreeWithLeafNodes", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object]),
        __metadata("design:returntype", Boolean)
    ], Cascader.prototype, "adjustOptionSelect", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object, Array]),
        __metadata("design:returntype", void 0)
    ], Cascader.prototype, "getOnlyChildrenSelect", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object]),
        __metadata("design:returntype", Number)
    ], Cascader.prototype, "getSelectedChildNum", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object]),
        __metadata("design:returntype", void 0)
    ], Cascader.prototype, "dealOptionDisable", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object, Object]),
        __metadata("design:returntype", void 0)
    ], Cascader.prototype, "dealChildrenSelect", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object, Number]),
        __metadata("design:returntype", void 0)
    ], Cascader.prototype, "onSelect", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object, Number]),
        __metadata("design:returntype", void 0)
    ], Cascader.prototype, "handleExpand", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object]),
        __metadata("design:returntype", Object)
    ], Cascader.prototype, "getSubmitOptions", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", []),
        __metadata("design:returntype", void 0)
    ], Cascader.prototype, "confirm", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", []),
        __metadata("design:returntype", void 0)
    ], Cascader.prototype, "getSelectedOptions", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object, Number]),
        __metadata("design:returntype", void 0)
    ], Cascader.prototype, "renderOption", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object, Number]),
        __metadata("design:returntype", void 0)
    ], Cascader.prototype, "renderOptions", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", []),
        __metadata("design:returntype", void 0)
    ], Cascader.prototype, "renderTabs", null);
    return Cascader;
}(React__default.Component));
var Cascader$1 = themeable(Cascader);

export { Cascader, Cascader$1 as default };
