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

import { __extends, __read, __assign, __decorate, __metadata } from 'tslib';
import { resizeSensor, autobind } from 'amis-core';
import React__default from 'react';
import debounce from 'lodash/debounce';
import { Icon } from './icons.js';

var HorizontalScroll = /** @class */ (function (_super) {
    __extends(HorizontalScroll, _super);
    function HorizontalScroll(props) {
        var _this = _super.call(this, props) || this;
        _this.innerWrapper = React__default.createRef(); // 内部滚动容器
        _this.resizeDom = React__default.createRef(); // 外部容器
        _this.toDispose = []; // 监听函数数组
        /**
         * 根据滚动条位置更新左右箭头的禁用状态
         */
        _this.checkArrowStatus = debounce(function () {
            var _a, _b;
            var wrapElement = ((_b = (_a = _this.props).getScrollParentElement) === null || _b === void 0 ? void 0 : _b.call(_a)) || _this.innerWrapper.current;
            var _c = wrapElement || {
                scrollLeft: 0,
                scrollWidth: 0,
                clientWidth: 0
            }, scrollLeft = _c.scrollLeft, scrollWidth = _c.scrollWidth, clientWidth = _c.clientWidth;
            var _d = _this.state, arrowRightDisabled = _d.arrowRightDisabled, arrowLeftDisabled = _d.arrowLeftDisabled;
            if (scrollLeft === 0 && !arrowLeftDisabled) {
                _this.setState({
                    arrowRightDisabled: false,
                    arrowLeftDisabled: true
                });
            }
            else if (scrollWidth === scrollLeft + clientWidth &&
                !arrowRightDisabled) {
                _this.setState({
                    arrowRightDisabled: true,
                    arrowLeftDisabled: false
                });
            }
            else if (scrollLeft !== 0 && arrowLeftDisabled) {
                _this.setState({
                    arrowLeftDisabled: false
                });
            }
            else if (scrollWidth !== scrollLeft + clientWidth &&
                arrowRightDisabled) {
                _this.setState({
                    arrowRightDisabled: false
                });
            }
        }, 100, {
            trailing: true,
            leading: false
        });
        _this.resizeDom = React__default.createRef();
        _this.state = {
            isOverflow: false,
            arrowLeftDisabled: false,
            arrowRightDisabled: false,
            scroll: false
        };
        return _this;
    }
    /**
     * 处理箭头点击事件
     * @param type 箭头方向，'left' 表示向左，'right' 表示向右
     */
    HorizontalScroll.prototype.handleArrow = function (type) {
        var _a, _b, _c, _d;
        // 滚动元素的父元素
        var wrapElement = ((_b = (_a = this.props).getScrollParentElement) === null || _b === void 0 ? void 0 : _b.call(_a)) || this.innerWrapper.current;
        var _e = wrapElement || {
            scrollLeft: 0,
            scrollWidth: 0,
            clientWidth: 0
        }, scrollLeft = _e.scrollLeft, scrollWidth = _e.scrollWidth, clientWidth = _e.clientWidth;
        if (type === 'left' && scrollLeft > 0) {
            var newScrollLeft = scrollLeft - clientWidth;
            (_c = wrapElement === null || wrapElement === void 0 ? void 0 : wrapElement.scrollTo) === null || _c === void 0 ? void 0 : _c.call(wrapElement, {
                left: newScrollLeft > 0 ? newScrollLeft : 0,
                behavior: 'smooth'
            });
            this.setState({
                arrowRightDisabled: false,
                arrowLeftDisabled: newScrollLeft <= 0
            });
        }
        else if (type === 'right' && scrollWidth > scrollLeft + clientWidth) {
            var newScrollLeft = scrollLeft + clientWidth;
            (_d = wrapElement === null || wrapElement === void 0 ? void 0 : wrapElement.scrollTo) === null || _d === void 0 ? void 0 : _d.call(wrapElement, {
                left: newScrollLeft > scrollWidth ? scrollWidth : newScrollLeft,
                behavior: 'smooth'
            });
            this.setState({
                arrowRightDisabled: newScrollLeft > scrollWidth - clientWidth,
                arrowLeftDisabled: false
            });
        }
        this.setState({
            scroll: true
        });
    };
    /**
     * 保证选中的yua始终显示在可视区域
     */
    HorizontalScroll.prototype.showSelected = function (isOverflow) {
        var _a, _b, _c, _d;
        var isContentOverflow = isOverflow === undefined ? this.state.isOverflow : isOverflow;
        var activeChildClassName = this.props.activeChildClassName;
        if (!isContentOverflow || !activeChildClassName) {
            return;
        }
        // 滚动子元素容器
        var wrapperDom = ((_b = (_a = this.props).getScrollParentElement) === null || _b === void 0 ? void 0 : _b.call(_a)) || this.innerWrapper.current;
        // 查找第一个命中的元素
        var activeElement = null;
        var searchClassNames = Array.isArray(activeChildClassName)
            ? activeChildClassName
            : [activeChildClassName];
        // 根据传入类名数组从前到后查找是否能匹配到对应元素
        var classNameIndex = 0;
        while (!activeElement && classNameIndex < searchClassNames.length) {
            activeElement = wrapperDom === null || wrapperDom === void 0 ? void 0 : wrapperDom.querySelector(".".concat(activeChildClassName[classNameIndex]));
            classNameIndex++;
        }
        // 检查查找到的元素是否是直接子元素，如果不是则一直向上找
        while (activeElement && activeElement.parentElement !== wrapperDom) {
            activeElement = activeElement.parentElement;
        }
        if (!activeElement) {
            return;
        }
        var activeLeftOffset = activeElement === null || activeElement === void 0 ? void 0 : activeElement.offsetLeft;
        var activeWidth = activeElement === null || activeElement === void 0 ? void 0 : activeElement.clientWidth;
        var scrollLeft = (wrapperDom === null || wrapperDom === void 0 ? void 0 : wrapperDom.scrollLeft) || 0;
        var clientWidth = (wrapperDom === null || wrapperDom === void 0 ? void 0 : wrapperDom.clientWidth) || 0;
        // 左边被遮住了
        if (scrollLeft > activeLeftOffset) {
            (_c = wrapperDom === null || wrapperDom === void 0 ? void 0 : wrapperDom.scrollTo) === null || _c === void 0 ? void 0 : _c.call(wrapperDom, {
                left: activeLeftOffset,
                behavior: 'smooth'
            });
        }
        // 右边被遮住了
        if (activeLeftOffset + activeWidth > scrollLeft + clientWidth) {
            (_d = wrapperDom === null || wrapperDom === void 0 ? void 0 : wrapperDom.scrollTo) === null || _d === void 0 ? void 0 : _d.call(wrapperDom, {
                left: activeLeftOffset + activeWidth - clientWidth,
                behavior: 'smooth'
            });
        }
    };
    /**
     * 处理内容与容器之间的位置关系
     */
    HorizontalScroll.prototype.checkIsOverflow = function () {
        var _a, _b;
        var navMainRef = ((_b = (_a = this.props).getScrollParentElement) === null || _b === void 0 ? void 0 : _b.call(_a)) || this.innerWrapper.current;
        var clientWidth = (navMainRef === null || navMainRef === void 0 ? void 0 : navMainRef.clientWidth) || 0;
        var scrollWidth = (navMainRef === null || navMainRef === void 0 ? void 0 : navMainRef.scrollWidth) || 0;
        var isOverflow = scrollWidth > clientWidth;
        // 内容超出容器长度标记溢出
        if (isOverflow !== this.state.isOverflow) {
            this.setState({ isOverflow: isOverflow });
        }
        if (isOverflow) {
            this.showSelected(isOverflow);
        }
    };
    /**
     * 渲染箭头图标
     * @param type 箭头类型，'left' 表示左箭头，'right' 表示右箭头
     * @returns 返回渲染的箭头图标组件或 null
     */
    HorizontalScroll.prototype.renderArrow = function (type) {
        var _this = this;
        var _a = this.props, cx = _a.classnames, testIdBuilder = _a.testIdBuilder, icons = _a.icons, iconsClassName = _a.iconsClassName;
        var _b = this.state, isOverflow = _b.isOverflow, arrowLeftDisabled = _b.arrowLeftDisabled, arrowRightDisabled = _b.arrowRightDisabled;
        var disabled = type === 'left' ? arrowLeftDisabled : arrowRightDisabled;
        // 优先使用外部传入图标
        var _c = __read(Array.isArray(icons) ? icons : [icons, icons], 2), leftIcon = _c[0], rightIcon = _c[1];
        var renderIconContent = type === 'left' ? leftIcon : rightIcon;
        var _d = __read(Array.isArray(iconsClassName)
            ? iconsClassName
            : [iconsClassName, iconsClassName], 2), leftIconClassName = _d[0], rightIconClassName = _d[1];
        var renderIconClassName = type === 'left' ? leftIconClassName : rightIconClassName;
        return isOverflow ? (React__default.createElement("div", __assign({ onClick: function () { return _this.handleArrow(type); }, className: cx('HorizontalScroll-arrow', 'HorizontalScroll-arrow--' + type, disabled && 'HorizontalScroll-arrow--disabled') }, testIdBuilder === null || testIdBuilder === void 0 ? void 0 : testIdBuilder.getChild("arrow-".concat(type)).getTestId()), renderIconContent ? (React__default.createElement(Icon, { icon: renderIconContent, className: renderIconClassName })) : (React__default.createElement(Icon, { icon: "right-arrow-bold", className: "icon" })))) : null;
    };
    /**
     * 监听导航上的滚动事件
     */
    HorizontalScroll.prototype.handleWheel = function (e) {
        var _a, _b, _c;
        var deltaY = e.deltaY, deltaX = e.deltaX;
        var absX = Math.abs(deltaX);
        var absY = Math.abs(deltaY);
        // 当鼠标上下滚动时转换为左右滚动
        if (absY > absX) {
            var wrapElement = ((_b = (_a = this.props).getScrollParentElement) === null || _b === void 0 ? void 0 : _b.call(_a)) || this.innerWrapper.current;
            (_c = wrapElement === null || wrapElement === void 0 ? void 0 : wrapElement.scrollTo) === null || _c === void 0 ? void 0 : _c.call(wrapElement, {
                left: (wrapElement === null || wrapElement === void 0 ? void 0 : wrapElement.scrollLeft) + deltaY
            });
            e.preventDefault();
        }
        this.checkArrowStatus();
        this.setState({
            scroll: true
        });
    };
    HorizontalScroll.prototype.componentDidMount = function () {
        var _this = this;
        var _a, _b, _c;
        this.checkIsOverflow();
        var wrapElement = ((_b = (_a = this.props).getScrollParentElement) === null || _b === void 0 ? void 0 : _b.call(_a)) || this.innerWrapper.current;
        if (wrapElement) {
            wrapElement.addEventListener('wheel', this.handleWheel, {
                passive: false
            });
            this.checkArrowStatus();
        }
        ((_c = this.resizeDom) === null || _c === void 0 ? void 0 : _c.current) &&
            this.toDispose.push(resizeSensor(this.resizeDom.current, function () {
                return _this.checkIsOverflow();
            }));
    };
    HorizontalScroll.prototype.componentWillUnmount = function () {
        this.checkArrowStatus.cancel();
        this.toDispose.forEach(function (fn) { return fn(); });
        this.toDispose = [];
    };
    HorizontalScroll.prototype.render = function () {
        var _a = this.props, cx = _a.classnames, children = _a.children, testIdBuilder = _a.testIdBuilder, className = _a.className;
        return (React__default.createElement("div", { ref: this.resizeDom, className: cx('HorizontalScroll-wrapper', className) },
            React__default.createElement("div", __assign({ className: cx('HorizontalScroll-Container', this.state.isOverflow && 'HorizontalScroll-Container--overflow') }, testIdBuilder === null || testIdBuilder === void 0 ? void 0 : testIdBuilder.getChild('links').getTestId()),
                this.renderArrow('left'),
                React__default.createElement("div", { className: cx('HorizontalScroll-Container-main'), ref: this.innerWrapper }, typeof children === 'function'
                    ? children(this.showSelected)
                    : children),
                this.renderArrow('right'))));
    };
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [String]),
        __metadata("design:returntype", void 0)
    ], HorizontalScroll.prototype, "handleArrow", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Boolean]),
        __metadata("design:returntype", void 0)
    ], HorizontalScroll.prototype, "showSelected", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", []),
        __metadata("design:returntype", void 0)
    ], HorizontalScroll.prototype, "checkIsOverflow", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [WheelEvent]),
        __metadata("design:returntype", void 0)
    ], HorizontalScroll.prototype, "handleWheel", null);
    return HorizontalScroll;
}(React__default.Component));

export { HorizontalScroll };
