import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useLayoutEffect, useRef, useState, } from "react";
import { twMerge } from "tailwind-merge";
import { Spinner } from "./Spinner";
export function SimpleTabs({ tabs, setActiveTab, activeTab, className, tabClassName, isLoading = false, hideContent = false, variant = "default", }) {
    const containerRef = useRef(null);
    const tabRefs = useRef([]);
    const tabsLayoutSignature = tabs
        .map((tab) => `${tab.id}:${tab.label}:${tab.disabled ? "1" : "0"}:${tab.icon ? "1" : "0"}:${tab.badge != null ? "1" : "0"}`)
        .join("|");
    const prevSignatureRef = useRef(tabsLayoutSignature);
    const [underlineStyle, setUnderlineStyle] = useState({
        left: 0,
        width: 0,
        top: 0,
    });
    const [isInitialized, setIsInitialized] = useState(false);
    const [skipTransition, setSkipTransition] = useState(false);
    const lastContainerWidth = useRef(null);
    if (activeTab > tabs.length - 1) {
        activeTab = 0;
    }
    if (activeTab < 0) {
        activeTab = 0;
    }
    const [canCenter, setCanCenter] = useState(true);
    const updateUnderlinePosition = useCallback(() => {
        const activeTabEl = tabRefs.current[activeTab];
        const container = containerRef.current;
        if (activeTabEl && container) {
            const underlineHeight = variant === "elegant" ? 2 : 3;
            setUnderlineStyle({
                left: activeTabEl.offsetLeft,
                width: activeTabEl.offsetWidth,
                top: activeTabEl.offsetTop + activeTabEl.offsetHeight - underlineHeight,
            });
        }
    }, [activeTab, variant]);
    useLayoutEffect(() => {
        tabRefs.current.length = tabs.length;
        // When the tab set itself changed (not just the active index), skip the
        // slide animation so the underline appears instantly at the new position.
        const tabSetChanged = tabsLayoutSignature !== prevSignatureRef.current;
        prevSignatureRef.current = tabsLayoutSignature;
        if (tabSetChanged) {
            setSkipTransition(true);
            requestAnimationFrame(() => setSkipTransition(false));
        }
        // Synchronously recompute centering before measuring. The async
        // ResizeObserver can't run until after paint, so when the tab set changes
        // the old canCenter value may no longer be correct. Updating state inside
        // useLayoutEffect triggers a synchronous re-render before paint so the
        // follow-up effect sees the correct justify-center layout.
        const container = containerRef.current;
        if (container) {
            const shouldCenter = container.scrollWidth <= container.clientWidth;
            if (shouldCenter !== canCenter) {
                setCanCenter(shouldCenter);
                // The state update will cause another layout-effect pass with the
                // corrected flex layout; skip measuring until then.
                return;
            }
        }
        updateUnderlinePosition();
        // Scroll active tab into view if needed
        const activeTabEl = tabRefs.current[activeTab];
        if (activeTabEl) {
            activeTabEl.scrollIntoView({
                behavior: "smooth",
                block: "nearest",
                inline: "nearest",
            });
        }
        // scrollIntoView can change scrollLeft; recompute after layout settles.
        requestAnimationFrame(updateUnderlinePosition);
        // Enable transitions after first render
        if (!isInitialized) {
            requestAnimationFrame(() => setIsInitialized(true));
        }
    }, [activeTab, canCenter, isInitialized, tabs.length, tabsLayoutSignature, updateUnderlinePosition]);
    // Handle container resize
    useEffect(() => {
        const container = containerRef.current;
        if (!container)
            return;
        const resizeObserver = new ResizeObserver((entries) => {
            const entry = entries[0];
            if (!entry)
                return;
            const currentWidth = entry.contentRect.width;
            const prevWidth = lastContainerWidth.current;
            // Re-check centering and reposition underline on actual container resize
            if (prevWidth !== null && Math.abs(currentWidth - prevWidth) > 1) {
                setSkipTransition(true);
                setCanCenter(container.scrollWidth <= container.clientWidth);
                updateUnderlinePosition();
                requestAnimationFrame(() => setSkipTransition(false));
            }
            lastContainerWidth.current = currentWidth;
        });
        resizeObserver.observe(container);
        return () => {
            resizeObserver.disconnect();
        };
    }, [updateUnderlinePosition]);
    if (tabs.length === 0)
        return null;
    return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { ref: containerRef, className: twMerge("scrollbar-hide relative flex shrink-0 items-start gap-2 overflow-x-auto", canCenter && "justify-center", className), onScroll: updateUnderlinePosition, children: [tabs.map((tab, index) => (_jsxs("button", { ref: (el) => {
                            tabRefs.current[index] = el;
                        }, id: tab.id, className: twMerge("flex min-w-0 shrink-0 cursor-pointer items-center justify-center gap-2 truncate px-3 pt-2 pb-2 text-xs whitespace-nowrap transition-colors", tabClassName, activeTab === index ? "active-tab" : "", variant === "elegant" &&
                            "px-4 pt-3 pb-3 text-[13px] font-medium tracking-tight"), "data-testid": tab.testId, disabled: tab.disabled, onClick: () => setActiveTab(index), style: {
                            fontWeight: index === activeTab
                                ? variant === "elegant"
                                    ? "600"
                                    : "medium"
                                : "normal",
                            color: tab.disabled
                                ? "#ccc"
                                : index === activeTab
                                    ? "black"
                                    : variant === "elegant"
                                        ? "#666"
                                        : "gray",
                            cursor: tab.disabled ? "not-allowed" : "pointer",
                        }, children: [tab.icon && _jsx("i", { className: tab.icon }), _jsx("span", { children: tab.label }), tab.badge != null && tab.badge] }, tab.id))), isLoading && (_jsx("div", { className: "flex items-center", children: _jsx(Spinner, { size: "md" }) })), _jsx("div", { className: twMerge("pointer-events-none absolute transition-all", variant === "elegant" ? "h-[2px] bg-black" : "h-[3px] bg-black"), style: {
                            left: underlineStyle.left,
                            top: underlineStyle.top,
                            width: underlineStyle.width,
                            transition: isInitialized && !skipTransition
                                ? "left 250ms cubic-bezier(0.4, 0, 0.2, 1), width 250ms cubic-bezier(0.4, 0, 0.2, 1)"
                                : "none",
                        } })] }), !hideContent && (_jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children: tabs[activeTab]?.content }))] }));
}
//# sourceMappingURL=SimpleTabs.js.map