import { useEffect, useState } from 'react';
import { toast } from 'react-toastify-next';
import { useViewportType } from '../../../useViewportType';
import { NOTIFY_NO_TRANSITION_ATTR, notifyClassnames } from '../../constants';
import { sleep } from '../../utils/sleep';
import { useHover, useTouchStackExpand } from './hooks';
export const useLogic = ({ containerId: externalContainerId, }) => {
    const { isMobile } = useViewportType();
    const [toasts, setToasts] = useState([]);
    const [container, setContainer] = useState();
    const [isStartedClosingNotify, setStartedClosingNotify] = useState(false);
    useEffect(() => {
        if (toasts.length) {
            const scrollContainer = document.querySelector(`#${externalContainerId} .Toastify__toast-container`);
            setContainer(scrollContainer);
        }
    }, [externalContainerId, toasts]);
    // Ориентируемся на data-атрибут для отключении анимации стека при добавлении нового уведомления
    const handleAddNoTransitionAttr = () => {
        const elements = document.querySelectorAll(`.${notifyClassnames.root}`);
        elements.forEach((element) => element.setAttribute(NOTIFY_NO_TRANSITION_ATTR, 'true'));
    };
    const handleRemoveNoTransitionAttr = () => {
        const elements = document.querySelectorAll(`.${notifyClassnames.root}[${NOTIFY_NO_TRANSITION_ATTR}='true']`);
        elements.forEach((element) => element.removeAttribute(NOTIFY_NO_TRANSITION_ATTR));
    };
    useEffect(() => {
        handleRemoveNoTransitionAttr();
        // Синхронизирует скрытие кнопки при ручном закрытии всех уведомлений
        if (!toasts.length) {
            setStartedClosingNotify(false);
        }
    }, [toasts]);
    const hasOpenNotify = Boolean(toasts.length);
    const { isHovered } = useHover(container, {
        enabled: !isMobile,
    });
    const isTouchExpanded = useTouchStackExpand({
        stackContainerElement: container ?? null,
        enabled: isMobile,
        hasOpenNotify,
    });
    const isStackExpanded = isMobile ? isTouchExpanded : isHovered;
    const handleAddToast = ({ id, containerId }) => {
        if (Object.is(containerId, externalContainerId)) {
            setToasts((currentToasts) => [...currentToasts, id]);
        }
    };
    const handleRemoveToast = ({ id, containerId }) => {
        if (Object.is(containerId, externalContainerId)) {
            setToasts((currentToasts) => currentToasts.filter((toastId) => toastId !== id));
        }
    };
    const handleChange = ({ status, ...rest }) => {
        if (Object.is(status, 'added')) {
            handleAddToast({ status, ...rest });
            handleAddNoTransitionAttr();
            // Снимаем флаг запуска анимации на закрытие, если происходит добавление уведомлений.
            // Позволяет решить проблему отображения кнопки закрытия уведомлений,
            // при условии что пользователь нажал на нее, но новые уведомления продолжают появляться
            setStartedClosingNotify(false);
        }
        if (Object.is(status, 'removed')) {
            handleRemoveToast({ status, ...rest });
        }
    };
    useEffect(() => {
        const unsubscribe = toast.onChange(handleChange);
        return unsubscribe;
    }, []);
    useEffect(() => {
        if (!isStackExpanded || !container) {
            return;
        }
        (async () => {
            // Ожидаем пока отработает анимация и стек с уведомлениями раскроется
            await sleep(300);
            const hasVerticalScroll = container.scrollHeight > container.clientHeight;
            if (hasVerticalScroll) {
                container.scrollTo({
                    top: container.scrollHeight,
                    behavior: 'smooth',
                });
            }
        })();
    }, [container, isStackExpanded]);
    const closeAll = () => {
        setStartedClosingNotify(true);
        toast.dismiss({ containerId: externalContainerId });
    };
    return {
        isVisibleCloseButton: hasOpenNotify && (isMobile ? isStackExpanded : true),
        isStackExpanded,
        isStartedClosingNotify,
        closeAll,
    };
};
