import { __awaiter, __generator, __spreadArray } from "tslib";
import { useRef, useState } from 'functional-mini/compat';
import { useEffect, useEvent } from 'functional-mini/component';
import '../_util/assert-component2';
import { mountComponent } from '../_util/component';
import { useComponentEvent } from '../_util/hooks/useComponentEvent';
import { useInstanceBoundingClientRect } from '../_util/hooks/useInstanceBoundingClientRect';
import { useComponentUpdateEffect } from '../_util/hooks/useLayoutEffect';
import { useMixState } from '../_util/hooks/useMixState';
import { CollapseFunctionalProps } from './props';
import { useEvent as useStableCallback } from '../_util/hooks/useEvent';
var Collapse = function (props) {
    var _a = useState([]), contentHeight = _a[0], setContentHeight = _a[1];
    var _b = useState(false), hasChange = _b[0], setHasChange = _b[1];
    var taskQueueRef = useRef();
    var previousValueRef = useRef([]);
    var _c = useMixState(props.defaultCurrent, {
        value: props.current,
        postState: function (val) {
            var current = __spreadArray([], (val || []), true);
            var items = props.items;
            current = current.filter(function (item) {
                if (!items[item] || items[item].disabled) {
                    return false;
                }
                return true;
            });
            if (props.accordion) {
                current = current.length > 0 ? [current[0]] : [];
            }
            return {
                valid: true,
                value: __spreadArray([], current, true),
            };
        },
    }), value = _c[0], _d = _c[1], isControlled = _d.isControlled, update = _d.update;
    var triggerEvent = useComponentEvent(props).triggerEvent;
    useEvent('onChange', function (e) {
        var itemIndex = parseInt(e.currentTarget.dataset.index, 10);
        if (props.items[itemIndex] && props.items[itemIndex].disabled) {
            return;
        }
        var arr = value;
        var current = __spreadArray([], arr, true);
        var index = current.indexOf(itemIndex);
        if (index >= 0) {
            current.splice(index, 1);
        }
        else {
            if (props.accordion) {
                current = [itemIndex];
            }
            else {
                current.push(itemIndex);
                current.sort();
            }
        }
        if (!isControlled) {
            update(current);
        }
        triggerEvent('change', current);
    });
    var getBoundingClientRectWithBuilder = useInstanceBoundingClientRect().getBoundingClientRectWithBuilder;
    var updateContentHeight = useStableCallback(function (prevCurrent, nextCurrent) { return __awaiter(void 0, void 0, void 0, function () {
        var prevCurrentArray, nextCurrentArray, expandArray, closeArray, newContentHeight;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    prevCurrentArray = prevCurrent;
                    nextCurrentArray = nextCurrent;
                    expandArray = [];
                    closeArray = [];
                    nextCurrentArray.forEach(function (item) {
                        if (prevCurrentArray.indexOf(item) < 0) {
                            expandArray.push(item);
                        }
                    });
                    prevCurrentArray.forEach(function (item) {
                        if (nextCurrentArray.indexOf(item) < 0) {
                            closeArray.push(item);
                        }
                    });
                    return [4 /*yield*/, Promise.all(props.items.map(function (item, index) { return __awaiter(void 0, void 0, void 0, function () {
                            var height;
                            return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0:
                                        if (!(expandArray.indexOf(index) >= 0 ||
                                            closeArray.indexOf(index) >= 0)) return [3 /*break*/, 2];
                                        return [4 /*yield*/, getBoundingClientRectWithBuilder(function (id) { return ".ant-collapse-item-content".concat(id, "-").concat(index); })];
                                    case 1:
                                        height = (_a.sent()).height;
                                        return [2 /*return*/, "".concat(height, "px")];
                                    case 2: return [2 /*return*/, contentHeight[index]];
                                }
                            });
                        }); }))];
                case 1:
                    newContentHeight = _a.sent();
                    if (closeArray.length === 0) {
                        setContentHeight(newContentHeight);
                    }
                    else {
                        setContentHeight(newContentHeight);
                        taskQueueRef.current = function () {
                            setTimeout(function () {
                                setContentHeight(function (contentHeight) {
                                    return contentHeight.map(function (item, index) {
                                        if (closeArray.indexOf(index) >= 0) {
                                            return '0px';
                                        }
                                        return item;
                                    });
                                });
                            }, 10);
                        };
                    }
                    return [2 /*return*/];
            }
        });
    }); });
    useEffect(function () {
        if (taskQueueRef.current) {
            var task = taskQueueRef.current;
            taskQueueRef.current = null;
            if (typeof task === 'function') {
                task();
            }
        }
    });
    useEffect(function () {
        var current = value;
        var contentHeight = props.items.map(function (item, index) {
            if (current.indexOf(index) >= 0) {
                return '';
            }
            return '0px';
        });
        setContentHeight(contentHeight);
        setHasChange(true);
        previousValueRef.current = value;
    }, []);
    useComponentUpdateEffect(function () {
        var previous = previousValueRef.current;
        previousValueRef.current = value;
        updateContentHeight(previous, value);
    }, [props.items, JSON.stringify(value)]);
    useEvent('resetContentHeight', function (e) {
        var index = parseInt(e.currentTarget.dataset.index, 10);
        if (value.indexOf(index) < 0) {
            return;
        }
        setContentHeight(function (oldContentHeight) {
            var newContentHeight = __spreadArray([], oldContentHeight, true);
            newContentHeight[index] = '';
            return newContentHeight;
        });
    });
    return {
        contentHeight: contentHeight,
        hasChange: hasChange,
        mixin: {
            value: value,
        },
    };
};
mountComponent(Collapse, CollapseFunctionalProps);