/**
 * @license MIT
 * author: Cube Dev Team
 * @cube-dev/ui-kit v0.108.1
 * Released under the MIT license.
 */

import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { createContext, useContext, useEffect, useRef, useState, } from 'react';
import { CloseIcon } from '../../../icons/index.js';
import { tasty } from '../../../tasty/index.js';
import { useLayoutEffect } from '../../../utils/react/index.js';
import { Action, Button } from '../../actions/index.js';
import { Block } from '../../Block.js';
import { Flex } from '../../layout/Flex.js';
import { Space } from '../../layout/Space.js';
const FileTabsContext = createContext({
    addTab() { },
    removeTab() { },
    setTab() { },
    setDirtyTab() { },
});
const TabsPanelElement = tasty(Space, {
    qa: 'TabsPanel',
    styles: {
        position: 'relative',
        overflow: 'auto hidden',
        top: '1bw',
        gap: '.5x',
        flexShrink: 0,
        whiteSpace: 'nowrap',
        scrollbar: 'styled',
        padding: '1ow 1ow 0 1ow',
        fade: {
            '': false,
            'left-fade': '3x left',
            'right-fade': '3x right',
            'right-fade & left-fade': '3x left right',
        },
        transition: 'fade',
        '--scrollbar-radius': '1ow',
        '--scrollbar-width': '.75x',
        '--scrollbar-outline-width': '1px',
    },
});
const TabsContainerElement = tasty(Flex, {
    qa: 'TabsContainer',
    styles: {
        flow: 'column',
        height: 'max 100%',
        width: 'max 100%',
        position: 'relative',
    },
});
const DirtyBadge = tasty({
    element: 'DirtyBadge',
    styles: {
        position: 'absolute',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        width: '1x',
        height: '1x',
        fill: '#dark.30',
        radius: 'round',
    },
});
const TabElement = tasty(Action, {
    styles: {
        radius: '1r 1r 0 0',
        padding: '1x 1.5x',
        border: {
            '': 'left top right #clear',
            disabled: 'left top right #border',
        },
        fill: {
            '': '#dark.04',
            hovered: '#dark.08',
            'disabled, disabled & hover': '#white',
        },
        color: {
            '': '#dark-02',
            'disabled, hovered, hovered & disabled': '#dark',
        },
        cursor: {
            '': '$pointer',
            disabled: 'default',
        },
        fontWeight: 500,
        opacity: 1,
        preset: 'default',
        transform: {
            '': 'translate(0, 0)',
            disabled: 'translate(0, 1bw)',
        },
        transition: 'theme 0.2s',
        margin: '1bw bottom',
        DirtyBadge: {
            opacity: {
                '': 1,
                'dirty & :hover': 0,
            },
            pointerEvents: {
                '': 'auto',
                'dirty & :hover': 'none',
            },
        },
        CloseButton: {
            opacity: {
                '': 0,
                '!dirty | :hover': 1,
            },
        },
    },
});
const CloseButton = tasty(Button, {
    element: 'CloseButton',
    type: 'neutral',
    icon: _jsx(CloseIcon, {}),
    label: 'Close Tab',
    styles: {
        width: '3x',
        height: '3x',
        padding: 0,
    },
});
function Tab({ isDirty, isDisabled, children, isClosable, onClose, ...props }) {
    return (_jsx(TabElement, { mods: {
            dirty: isDirty,
        }, isDisabled: isDisabled, ...props, children: _jsxs(Space, { gap: ".75x", children: [_jsx(Block, { children: children }), (isClosable || isDirty) && (_jsxs(Flex, { placeItems: "center", style: { position: 'relative' }, children: [isClosable ? _jsx(CloseButton, { onPress: onClose }) : _jsx("div", {}), isDirty ? _jsx(DirtyBadge, {}) : null] }))] }) }));
}
export function FileTabs({ defaultActiveKey, activeKey: activeKeyProp, onTabClick, onTabClose, paneStyles, isClosable = true, children, ...props }) {
    const tabsRef = useRef(null);
    const [tabs, setTabs] = useState([]);
    const [activeKey, setActiveKey] = useState(activeKeyProp || defaultActiveKey);
    const [leftFade, setLeftFade] = useState(false);
    const [rightFade, setRightFade] = useState(false);
    function updateScroll() {
        const el = tabsRef && tabsRef.current;
        if (!el)
            return;
        setLeftFade(!!el.scrollLeft);
        setRightFade(el.scrollWidth !== el.offsetWidth &&
            !!(el.scrollWidth - el.offsetWidth - el.scrollLeft));
    }
    useLayoutEffect(updateScroll, [tabs]);
    function scrollCurrentIntoView() {
        const el = tabsRef && tabsRef.current;
        if (!el)
            return;
        const current = el.querySelector('button[disabled]');
        if (!current)
            return;
        current.scrollIntoView({ behavior: 'smooth', inline: 'end', block: 'end' });
    }
    useEffect(() => {
        function update() {
            updateScroll();
        }
        if (tabsRef && tabsRef.current) {
            tabsRef.current.addEventListener('scroll', update);
            tabsRef.current.addEventListener('mousewheel', update);
            window.addEventListener('resize', update);
        }
        return () => {
            if (tabsRef && tabsRef.current) {
                tabsRef.current.removeEventListener('scroll', update);
                tabsRef.current.removeEventListener('mousewheel', update);
            }
            window.removeEventListener('resize', update);
        };
    }, [tabsRef]);
    useEffect(scrollCurrentIntoView, [activeKey]);
    useEffect(() => {
        setActiveKey(activeKeyProp);
    }, [activeKeyProp]);
    function getTab(tabs, key) {
        return tabs.find((tab) => tab.id === key);
    }
    function setTab(key) {
        if (getTab(tabs, key)) {
            setActiveKey(key);
        }
    }
    function addTab(tab) {
        setTabs((tabs) => {
            if (!getTab(tabs, tab.id)) {
                return [...tabs, tab];
            }
            return tabs;
        });
    }
    function setDirtyTab(id, isDirty) {
        setTabs((tabs) => {
            const tab = getTab(tabs, id);
            if (tab) {
                tab.isDirty = isDirty;
                return [...tabs];
            }
            return tabs;
        });
    }
    function handleClose(tab) {
        if (getTab(tabs, tab.id)) {
            onTabClose && onTabClose(tab.id);
        }
    }
    function removeTab(tab) {
        setTabs((tabs) => {
            const _tabs = tabs.filter((_tab) => _tab.id !== tab.id);
            setActiveKey((prevActiveKey) => {
                if (prevActiveKey === tab.id) {
                    return _tabs[0] && _tabs[0].id;
                }
                return prevActiveKey;
            });
            return _tabs;
        });
    }
    function onPress(tab) {
        setTab(tab.id);
        onTabClick && onTabClick(tab.id);
    }
    return (_jsx(TabsContainerElement, { ...props, children: _jsxs(FileTabsContext.Provider, { value: {
                addTab,
                setTab,
                removeTab,
                setDirtyTab,
                currentTab: activeKey,
            }, children: [_jsx(TabsPanelElement, { ref: tabsRef, "data-left-fade": leftFade || null, "data-right-fade": rightFade || null, children: tabs.map((tab) => {
                        return (_jsx(Tab, { isClosable: isClosable, isDisabled: tab.id === activeKey || false, isDirty: tab.isDirty, onPress: () => onPress(tab), onClose: () => isClosable && handleClose(tab), children: tab.title }, tab.id));
                    }) }), _jsx(Flex, { flexGrow: 1, border: "top", ...(paneStyles || {}), children: children })] }) }));
}
FileTabs.TabPane = function FileTabPane(allProps) {
    let { id, title, isDirty, children, ...props } = allProps;
    const { addTab, removeTab, currentTab, setDirtyTab } = useContext(FileTabsContext);
    useEffect(() => {
        const tabData = {
            id,
            title,
            isDirty,
        };
        addTab(tabData);
        return () => {
            removeTab(tabData);
        };
    }, [id, title]);
    useEffect(() => {
        setDirtyTab(id, isDirty || false);
    }, [isDirty]);
    const isCurrent = id === currentTab;
    return (_jsx(Block, { style: { display: isCurrent ? 'block' : 'none', maxWidth: '100%' }, flexGrow: 1, ...props, children: children }));
};

        