import React, { useCallback, useEffect, useMemo, useState, useRef, createRef } from 'react';
import { makeStyles, MenuItem, Typography, Popover, ButtonBase, Badge, IconButton } from '@material-ui/core';
import { FluentIcon } from '../../../utilities/iconLibrary/FluentIcon';
import clsx from 'clsx';
import { MoreVerticalIcon } from '@fluentui/react-icons';
const useStyles = makeStyles((theme) => ({
    root: {
        flexSkrink: 0,
        overflow: 'hidden'
    },
    tabsWrapper: {
        display: 'flex',
        gap: (props) => ((props === null || props === void 0 ? void 0 : props.variant) === 'block' ? theme.spacing(1) : null),
        flexGrow: 1
    },
    tab: {
        padding: `8px 18px`,
        flex: 1
    },
    blockTab: {
        backgroundColor: theme.palette.background.paper
    },
    activeTab: {
        borderBottom: (props) => (props === null || props === void 0 ? void 0 : props.variant) === 'block'
            ? null
            : `2px solid ${theme.palette.secondary.main}`,
        backgroundColor: (props) => (props === null || props === void 0 ? void 0 : props.variant) === 'block' ? theme.palette.secondary.light : null,
        color: (props) => (props === null || props === void 0 ? void 0 : props.variant) === 'block'
            ? theme.palette.getContrastText(theme.palette.secondary.light)
            : null
    },
    moreButton: {
        marginTop: theme.spacing(1),
        width: theme.spacing(1),
        height: theme.spacing(1),
        borderRadius: 2
    },
    menuItem: {
        whiteSpace: 'normal',
        width: (props) => ((props === null || props === void 0 ? void 0 : props.menuWidth) ? props === null || props === void 0 ? void 0 : props.menuWidth : '170px')
    },
    popoverWrapper: {
        maxHeight: (props) => (props === null || props === void 0 ? void 0 : props.menuMaxHeight) ? props === null || props === void 0 ? void 0 : props.menuMaxHeight : '250px'
    }
}));
export const UdpTabs = (props) => {
    const { value, onChange, className, menuItemProps, tabList, variant, buttonWidth } = props;
    const classes = useStyles(props);
    const tabContainerRef = useRef(null);
    const innerTabContainerRef = useRef(null);
    const [anchorEl, setAnchorEl] = useState(null);
    const [visibleTabList, setVisibleTabList] = useState(null);
    const [menuTabList, setMenuTabList] = useState(null);
    const [initialTotalTabWidth, setInitialTotalTabWidth] = useState(null);
    const [initialTabWidth, setInitialTabWidth] = useState();
    const gapWidth = 8;
    const open = Boolean(anchorEl);
    const currentTabList = useMemo(() => {
        return tabList === null || tabList === void 0 ? void 0 : tabList.map((tab, index) => (Object.assign(Object.assign({ id: index }, tab), { ref: createRef() })));
    }, [tabList]);
    const handlePopoverClick = useCallback((event, index) => {
        setAnchorEl(event.currentTarget);
    }, []);
    const handlePopoverClose = () => {
        setAnchorEl(null);
    };
    const menuItemSelected = useMemo(() => {
        return !!(menuTabList === null || menuTabList === void 0 ? void 0 : menuTabList.find((tab) => (tab === null || tab === void 0 ? void 0 : tab.id) === value));
    }, [value, menuTabList]);
    const getInitialTabWidth = useCallback((tabsElements, currentTabList) => {
        let totalTabWidth = 0;
        let tabWidth = [];
        if ((tabsElements === null || tabsElements === void 0 ? void 0 : tabsElements.length) === (currentTabList === null || currentTabList === void 0 ? void 0 : currentTabList.length) &&
            !initialTotalTabWidth) {
            for (let i = 0; i < tabsElements.length; i++) {
                totalTabWidth += tabsElements[i].clientWidth;
                if (variant === 'block') {
                    totalTabWidth += gapWidth;
                }
                tabWidth[i] = tabsElements[i].clientWidth;
            }
            setInitialTotalTabWidth(totalTabWidth);
            setInitialTabWidth(tabWidth);
            return { totalTabWidth, tabWidth };
        }
        return { totalTabWidth: initialTotalTabWidth, tabWidth: initialTabWidth };
    }, [initialTabWidth, initialTotalTabWidth, variant]);
    const calculateHiddenTabs = useCallback(() => {
        if (innerTabContainerRef.current) {
            const containerWidth = innerTabContainerRef.current.clientWidth;
            const tabsElements = Array.from(innerTabContainerRef.current.children);
            const moreBtnWidth = 24;
            let hiddenTabsArray = [];
            let visibleTabsArray = Array.from(currentTabList);
            const { totalTabWidth, tabWidth } = getInitialTabWidth(tabsElements, currentTabList);
            if (totalTabWidth > containerWidth) {
                let accumulatedWidth = 0;
                for (let i = 0; i < (tabWidth === null || tabWidth === void 0 ? void 0 : tabWidth.length); i++) {
                    accumulatedWidth += tabWidth[i];
                    if (variant === 'block') {
                        accumulatedWidth += gapWidth;
                    }
                    if (accumulatedWidth > containerWidth - moreBtnWidth) {
                        hiddenTabsArray = Array.from(currentTabList).slice(i);
                        visibleTabsArray = Array.from(currentTabList).slice(0, i);
                        break;
                    }
                }
            }
            setVisibleTabList(visibleTabsArray);
            setMenuTabList(hiddenTabsArray);
        }
    }, [currentTabList, getInitialTabWidth, variant]);
    useEffect(() => {
        // initial visible tab list
        setVisibleTabList(currentTabList);
    }, [currentTabList]);
    useEffect(() => {
        calculateHiddenTabs();
        const observer = new ResizeObserver((entries) => {
            handlePopoverClose();
            calculateHiddenTabs();
        });
        if (tabContainerRef.current) {
            observer.observe(tabContainerRef.current);
        }
        // Cleanup observer on component unmount
        return () => {
            observer.disconnect();
        };
    }, [calculateHiddenTabs]);
    return (React.createElement("div", null, React.createElement("div", { className: clsx(classes.root, className), ref: tabContainerRef }, React.createElement("div", { className: classes.tabsWrapper, ref: innerTabContainerRef, style: variant === 'spread' ? { justifyContent: 'space-between' } : null }, visibleTabList === null || visibleTabList === void 0 ? void 0 : visibleTabList.map((item, index) => {
        var _a, _b;
        return (React.createElement(ButtonBase
        // style={variant === 'spread' ? { flex: 1 } : null}
        , { 
            // style={variant === 'spread' ? { flex: 1 } : null}
            style: {
                flex: variant === 'spread' && 1,
                width: !!buttonWidth && buttonWidth
            }, key: index, id: 'udpRecord-UdpTabs-MenuItem-' + ((_a = item === null || item === void 0 ? void 0 : item.label) === null || _a === void 0 ? void 0 : _a.replace(/ /g, '-')), udprecordid: 'udpRecord-UdpTabs-MenuItem-' + ((_b = item === null || item === void 0 ? void 0 : item.label) === null || _b === void 0 ? void 0 : _b.replace(/ /g, '-')) }, React.createElement("div", { className: clsx(classes.tab, {
                [classes.blockTab]: variant === 'block',
                [classes.activeTab]: value === (item === null || item === void 0 ? void 0 : item.id)
            }), onClick: (e) => {
                onChange(e, item === null || item === void 0 ? void 0 : item.id);
                if (item === null || item === void 0 ? void 0 : item.onClick) {
                    item.onClick();
                }
                setAnchorEl(null);
            } }, React.createElement(Typography, { noWrap: true, style: {
                fontWeight: variant === 'spread' ? 'bold' : 'normal'
            } }, item === null || item === void 0 ? void 0 : item.label))));
    }), (menuTabList === null || menuTabList === void 0 ? void 0 : menuTabList.length) > 0 && (React.createElement(IconButton, { onClick: handlePopoverClick, className: classes.moreButton, color: "primary", id: "udpRecord-UdpTabs-MoreActions", udprecordid: "udpRecord-UdpTabs-MoreActions" }, React.createElement(Badge, { color: "secondary", variant: "dot", invisible: menuItemSelected === false }, React.createElement(FluentIcon, { component: MoreVerticalIcon, size: "medium" }))))), !!(menuTabList === null || menuTabList === void 0 ? void 0 : menuTabList.length) && (React.createElement("div", null, React.createElement(Popover, { id: "menuTabList", open: open, anchorEl: anchorEl, onClose: handlePopoverClose, anchorOrigin: {
            vertical: 'bottom',
            horizontal: 'left'
        }, transformOrigin: {
            vertical: 'top',
            horizontal: 'left'
        }, className: classes.popoverWrapper }, menuTabList === null || menuTabList === void 0 ? void 0 : menuTabList.map((tab) => {
        var _a, _b;
        return (React.createElement(MenuItem, Object.assign({ key: tab === null || tab === void 0 ? void 0 : tab.id, id: 'udpRecord-UdpTabs-MenuItem-' +
                ((_a = tab === null || tab === void 0 ? void 0 : tab.label) === null || _a === void 0 ? void 0 : _a.replace(/ /g, '-')), udprecordid: 'udpRecord-UdpTabs-MenuItem-' +
                ((_b = tab === null || tab === void 0 ? void 0 : tab.label) === null || _b === void 0 ? void 0 : _b.replace(/ /g, '-')), onClick: (e) => {
                if (tab === null || tab === void 0 ? void 0 : tab.onClick) {
                    tab.onClick();
                }
                if (onChange) {
                    onChange(e, tab === null || tab === void 0 ? void 0 : tab.id);
                }
                setAnchorEl(null);
            }, className: clsx(classes.menuItem, className), selected: (tab === null || tab === void 0 ? void 0 : tab.id) === value }, menuItemProps), React.createElement(Typography, null, tab === null || tab === void 0 ? void 0 : tab.label)));
    })))))));
};
//# sourceMappingURL=UdpTabs.js.map