var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
import React, { useCallback, useMemo, useState, useRef, useEffect } from 'react';
import classnames from 'classnames';
import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
import { useTheme } from '@mui/material/styles';
import ReactResizeDetector from 'react-resize-detector';
import { debounce } from '@reltio/mdm-sdk';
import { useStyles } from './styles';
var HANDLE_CHANGE_DEBOUNCE_INTERVAL = 250;
var isHorizontal = function (orientation) { return orientation === 'horizontal'; };
var isEqualSize = function (a, b) { return a.toFixed(2) === b.toFixed(2); };
export var ResizablePanes = function (_a) {
    var _b;
    var className = _a.className, children = _a.children, _c = _a.orientation, orientation = _c === void 0 ? 'vertical' : _c, _d = _a.primary, primary = _d === void 0 ? 'first' : _d, size = _a.size, minSize = _a.minSize, maxSize = _a.maxSize, allowResize = _a.allowResize, _e = _a.debounceInterval, debounceInterval = _e === void 0 ? HANDLE_CHANGE_DEBOUNCE_INTERVAL : _e, onChange = _a.onChange;
    var styles = useStyles();
    var theme = useTheme();
    var panelRef = useRef();
    var _f = useState(null), containerEl = _f[0], setContainerEl = _f[1];
    var _g = useState(0), percentageMinSize = _g[0], setPercentageMinSize = _g[1];
    var _h = useState(0), percentageMaxSize = _h[0], setPercentageMaxSize = _h[1];
    var _j = useState(true), isPaneAnimationEnabled = _j[0], setIsPaneAnimationEnabled = _j[1];
    var enableAnimation = useCallback(function () { return setIsPaneAnimationEnabled(true); }, []);
    var disableAnimation = useCallback(function () { return setIsPaneAnimationEnabled(false); }, []);
    var getContainerSize = useCallback(function () { return (isHorizontal(orientation) ? containerEl === null || containerEl === void 0 ? void 0 : containerEl.clientHeight : containerEl === null || containerEl === void 0 ? void 0 : containerEl.clientWidth); }, [containerEl, orientation]);
    if (typeof size === 'number' && size < 0) {
        size = (getContainerSize() || 0) + size;
    }
    var convertSize = useCallback(function (size) {
        if (typeof size === 'string' && size.endsWith('%')) {
            return +size.replace('%', '');
        }
        if (typeof size === 'string' && size.endsWith('px')) {
            size = size.replace('px', '');
        }
        return isNaN(+size) ? null : (+size / getContainerSize()) * 100;
    }, [getContainerSize]);
    var convertMinMaxSize = useCallback(function (size, minMaxSize) {
        if (size === 0 || size === 100)
            return 0;
        return convertSize(minMaxSize) || 0;
    }, [convertSize]);
    var actualizeSizes = useCallback(function () {
        if (containerEl && panelRef.current) {
            var convertedSize = convertSize(size);
            if (convertedSize != null && !isNaN(convertedSize)) {
                setPercentageMaxSize(convertMinMaxSize(convertedSize, maxSize));
                setPercentageMinSize(convertMinMaxSize(convertedSize, minSize));
                panelRef.current.resize(convertedSize);
            }
        }
    }, [convertSize, convertMinMaxSize, minSize, maxSize, size, containerEl]);
    useEffect(function () {
        actualizeSizes();
    }, [actualizeSizes, percentageMaxSize, percentageMinSize]);
    var handleChange = useCallback(debounce(function (size, containerSize) {
        if (size === undefined || containerSize === 0)
            return;
        onChange({
            percentageSize: size + '%',
            isMaxSize: +percentageMaxSize > 0
                ? isEqualSize(size, percentageMaxSize)
                : isEqualSize(size, 100 + percentageMaxSize),
            isMinSize: isEqualSize(size, percentageMinSize),
            size: Math.round((size * containerSize) / 100)
        });
    }, debounceInterval), [onChange, percentageMaxSize, percentageMinSize]);
    var handleDragging = useCallback(function (isDragging) {
        if (isDragging) {
            // Why do we need handleChange() here?
            // Case - user resized panels, and then immediately started resizing again.
            // We need to prevent onChange calling with "previous" data (handleChange is debounced calling of onChange)
            handleChange();
            disableAnimation();
        }
        else {
            handleChange(panelRef.current.getSize(), getContainerSize());
            enableAnimation();
        }
    }, [disableAnimation, enableAnimation, handleChange, getContainerSize]);
    var paneAnimationStyle = useMemo(function () { return ({
        transition: theme.transitions.create('flex', {
            easing: theme.transitions.easing.sharp,
            duration: theme.transitions.duration.leavingScreen
        })
    }); }, [theme]);
    var primaryPanelProps = __assign(__assign({ className: styles.panel, minSize: percentageMinSize }, (percentageMaxSize > 0 ? { maxSize: percentageMaxSize } : {})), { ref: panelRef, style: isPaneAnimationEnabled ? paneAnimationStyle : undefined });
    var secondaryPanelProps = __assign({ className: styles.panel, style: isPaneAnimationEnabled ? paneAnimationStyle : undefined }, (percentageMaxSize < 0 ? { minSize: -percentageMaxSize } : {}));
    return (React.createElement("div", { ref: setContainerEl, className: classnames(styles.container, className) },
        React.createElement(ReactResizeDetector, { handleHeight: isHorizontal(orientation), handleWidth: !isHorizontal(orientation), onResize: actualizeSizes, refreshMode: "debounce", refreshRate: 50 }),
        React.createElement(PanelGroup, { direction: isHorizontal(orientation) ? 'vertical' : 'horizontal' },
            React.createElement(Panel, __assign({}, (primary === 'first' ? primaryPanelProps : secondaryPanelProps)), children[0]),
            React.createElement(PanelResizeHandle, { className: classnames(styles.resizer, styles[orientation], (_b = {}, _b[styles.disabled] = !allowResize, _b)), disabled: !allowResize, hitAreaMargins: { coarse: 0, fine: 0 }, onDragging: handleDragging }),
            React.createElement(Panel, __assign({}, (primary === 'second' ? primaryPanelProps : secondaryPanelProps)), children[1]))));
};
ResizablePanes.displayName = 'ResizablePanes';
