import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
// (C) 2007-2025 GoodData Corporation
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import cx from "classnames";
import { differenceInCalendarDays, differenceInMonths, format } from "date-fns";
import { debounce } from "lodash-es";
import { FormattedMessage, injectIntl } from "react-intl";
import { v4 as uuid } from "uuid";
import { withTheme } from "@gooddata/sdk-ui-theme-provider";
import { addCssToStylesheet } from "./addCssToStylesheet.js";
import { getItemActiveColor, getItemHoverColor, getSeparatorColor, getTextColor, getWorkspacePickerHoverColor, } from "./colors.js";
import { HeaderAccount } from "./HeaderAccount.js";
import { HeaderChatButton } from "./HeaderChatButton.js";
import { HeaderHelp } from "./HeaderHelp.js";
import { HeaderMenu } from "./HeaderMenu.js";
import { HeaderSearchButton } from "./HeaderSearchButton.js";
import { HeaderSearchProvider } from "./headerSearchContext.js";
import { HeaderUpsellButton } from "./HeaderUpsellButton.js";
import { Icon } from "../Icon/index.js";
import { Overlay } from "../Overlay/index.js";
import { Typography } from "../Typography/index.js";
import { removeFromDom } from "../utils/domUtilities.js";
function getOuterWidth(element) {
    const width = element.offsetWidth;
    const { marginLeft, marginRight } = getComputedStyle(element);
    return width + parseInt(marginLeft, 10) + parseInt(marginRight, 10);
}
function getWidthOfChildren(element, selector = "> *") {
    const SAFETY_PADDING = 10;
    return Array.from(element.querySelectorAll(selector))
        .map(getOuterWidth)
        .reduce((sum, childWidth) => sum + childWidth, SAFETY_PADDING);
}
function AppHeaderCore(props) {
    const { logoHref = "/", accountMenuItems = [], helpMenuItems = [], menuItemsGroups = [], search = null, notificationsPanel = null, workspacePicker, isAccessibilityCompliant, intl, logoUrl, logoTitle, className, activeColor, headerColor, headerTextColor, documentationUrl, expiredDate, showUpsellButton, onUpsellButtonClick, badges, showStaticHelpMenu, userName, theme, helpMenuDropdownAlignPoints: helpDropdownAlign, disableHelpDropdown, onHelpClick, helpRedirectUrl, showChatItem, onChatItemClick, onLogoClick, onMenuItemClick, } = props;
    const [state, setState] = useState({
        childrenWidth: 0,
        guid: `header-${uuid()}`,
        isOverlayMenuOpen: false,
        responsiveMode: false,
        isHelpMenuOpen: false,
        isSearchMenuOpen: false,
        isNotificationsMenuOpen: false,
    });
    const nodeRef = useRef(null);
    const stylesheetRef = useRef(null);
    const measureChildren = useCallback(() => {
        const currentDOMNode = nodeRef.current;
        const childrenWidth = getWidthOfChildren(currentDOMNode, ".gd-header-measure");
        setState((prevState) => ({
            ...prevState,
            childrenWidth,
        }));
    }, []);
    const measure = useCallback(() => {
        const currentDOMNode = nodeRef.current;
        if (!currentDOMNode) {
            // ref is null because 'this.measure()' is called after 100ms 'componentWillUnmount' called,
            // which cleans the nodeRef
            return;
        }
        const currentWidth = currentDOMNode.clientWidth;
        const responsiveMode = currentWidth < state.childrenWidth;
        if (state.responsiveMode !== responsiveMode) {
            setState((prevState) => ({
                ...prevState,
                responsiveMode,
                isOverlayMenuOpen: false,
                isHelpMenuOpen: false,
                isSearchMenuOpen: false,
                isNotificationsMenuOpen: false,
            }));
        }
    }, [state.childrenWidth, state.responsiveMode]);
    const resizeHandler = useMemo(() => debounce(() => measure(), 100), [measure]);
    useEffect(() => {
        measure();
    }, [state.childrenWidth, measure]);
    useEffect(() => {
        window.addEventListener("resize", resizeHandler);
        return () => {
            window.removeEventListener("resize", resizeHandler);
            if (stylesheetRef.current) {
                removeFromDom(stylesheetRef.current);
            }
        };
    }, [resizeHandler]);
    const createStyles = useCallback(() => {
        const { guid } = state;
        const textColor = getTextColor(headerTextColor, headerColor);
        const itemActiveColor = getItemActiveColor(activeColor, headerColor);
        const itemHoverColor = getItemHoverColor(headerColor, activeColor);
        const separatorColor = getSeparatorColor(headerColor, activeColor);
        const workspacesPickerHoverColor = getWorkspacePickerHoverColor(headerColor);
        const css = [];
        css.push(`.${guid} { color: ${textColor}; background: ${headerColor}}`);
        css.push(`.${guid} .gd-header-menu-section { border-color: ${separatorColor}}`);
        css.push(`.${guid} .gd-header-menu-item:hover { border-color: ${itemHoverColor}}`);
        css.push(`.${guid} .gd-header-menu-item.active { border-color: var(--gd-palette-primary-base-from-theme, ${itemActiveColor})}`);
        css.push(`.${guid} .gd-header-project { border-color: ${separatorColor}}`);
        css.push(`.${guid} .gd-header-project:hover { background-color: ${workspacesPickerHoverColor}; color: ${textColor}}`);
        css.push(`.${guid} .hamburger-icon:not(.is-open) i { border-color: ${textColor}}`);
        css.push(`.${guid} .hamburger-icon:not(.is-open):after { border-color: ${textColor}}`);
        css.push(`.${guid} .hamburger-icon:not(.is-open):before { border-color: ${textColor}}`);
        stylesheetRef.current = addCssToStylesheet(`header-css-${guid}`, css.join("\n"), true);
    }, [state, activeColor, headerColor, headerTextColor]);
    const setOverlayMenu = useCallback((isOverlayMenuOpen) => {
        setState((prevState) => ({
            ...prevState,
            isOverlayMenuOpen,
            isHelpMenuOpen: false,
            isSearchMenuOpen: false,
            isNotificationsMenuOpen: false,
        }));
    }, []);
    const toggleSearchMenu = useCallback(() => {
        setState((prevState) => ({
            ...prevState,
            isSearchMenuOpen: !prevState.isSearchMenuOpen,
            isHelpMenuOpen: false,
            isNotificationsMenuOpen: false,
        }));
    }, []);
    const toggleNotificationsMenu = useCallback(() => {
        setState((prevState) => ({
            ...prevState,
            isNotificationsMenuOpen: !prevState.isNotificationsMenuOpen,
            isHelpMenuOpen: false,
            isSearchMenuOpen: false,
        }));
    }, []);
    const closeNotificationsMenu = useCallback(() => {
        setState((prevState) => ({
            ...prevState,
            isNotificationsMenuOpen: false,
            isHelpMenuOpen: false,
            isSearchMenuOpen: false,
            isOverlayMenuOpen: false,
        }));
    }, []);
    const setHelpMenu = useCallback((isHelpMenuOpen) => {
        setState((prevState) => ({
            ...prevState,
            isHelpMenuOpen,
            isSearchMenuOpen: false,
            isNotificationsMenuOpen: false,
        }));
    }, []);
    const toggleHelpMenu = useCallback(() => setHelpMenu(!state.isHelpMenuOpen), [setHelpMenu, state]);
    const handleMenuItemClick = useCallback((item, event) => {
        if (state.isHelpMenuOpen) {
            setOverlayMenu(false);
        }
        onMenuItemClick(item, event);
    }, [state, setOverlayMenu, onMenuItemClick]);
    const getHelpMenuLink = useCallback((icon = "gd-icon-header-help") => ({
        key: "gs.header.help",
        className: `s-menu-help ${icon}`,
        href: state.responsiveMode && helpMenuItems ? undefined : documentationUrl,
        onClick: state.responsiveMode && helpMenuItems ? toggleHelpMenu : undefined,
    }), [state, helpMenuItems, documentationUrl, toggleHelpMenu]);
    const addHelpItemGroup = useCallback((itemGroups) => {
        return documentationUrl ? [...itemGroups, [getHelpMenuLink()]] : itemGroups;
    }, [documentationUrl, getHelpMenuLink]);
    const addAdditionalItems = useCallback((itemGroups) => {
        const additionalItems = [];
        if (search) {
            additionalItems.push({
                key: "gs.header.search",
                className: "gd-icon-header-search",
                onClick: toggleSearchMenu,
            });
        }
        if (notificationsPanel) {
            const AlertIcon = Icon["Alert"];
            additionalItems.push({
                key: "gs.header.notifications",
                className: "gd-icon-header-notifications",
                icon: _jsx(AlertIcon, { width: 16, height: 16 }),
                onClick: toggleNotificationsMenu,
            });
        }
        if (!additionalItems.length) {
            return itemGroups;
        }
        return [...itemGroups, additionalItems];
    }, [search, notificationsPanel, toggleSearchMenu, toggleNotificationsMenu]);
    const getHelpMenu = useCallback(() => [[getHelpMenuLink("gd-icon-header-help-back"), ...helpMenuItems]], [getHelpMenuLink, helpMenuItems]);
    const getTrialCountdown = useCallback((expiredDate) => {
        // expiredDate is the last day that user can use the service
        const trialDaysLeft = differenceInCalendarDays(new Date(expiredDate), new Date()) + 1;
        if (trialDaysLeft === 1) {
            return _jsx(FormattedMessage, { id: "gs.header.countdown.lastDay" });
        }
        if (trialDaysLeft === 30) {
            return _jsx(FormattedMessage, { id: "gs.header.countdown.oneMonthLeft" });
        }
        if (trialDaysLeft > 1 && trialDaysLeft < 30) {
            return (_jsx(FormattedMessage, { id: "gs.header.countdown.numberOfDaysLeft", values: { number: trialDaysLeft } }));
        }
        if (trialDaysLeft > 30 && trialDaysLeft <= 91) {
            const currentDateWithoutTime = format(new Date(), "yyyy-MM-dd");
            const trialMonthsLeft = differenceInMonths(new Date(expiredDate), new Date(currentDateWithoutTime));
            return (_jsx(FormattedMessage, { id: "gs.header.countdown.numberOfMonthsLeft", values: { number: trialMonthsLeft + 1 } }));
        }
        return "";
    }, []);
    const getClassNames = useCallback(() => {
        return cx({
            "gd-header": true,
            [state.guid]: true,
            [className]: !!className,
        });
    }, [state.guid, className]);
    const renderLogo = useCallback((logoLinkClassName) => {
        return (_jsx("a", { href: logoHref, onClick: onLogoClick, className: logoLinkClassName, children: _jsx("img", { src: logoUrl, title: logoTitle, onLoad: measureChildren, onError: measureChildren, alt: "" }) }));
    }, [logoHref, onLogoClick, logoUrl, logoTitle, measureChildren]);
    const renderAccessibilityLogo = useCallback((logoLinkClassName) => {
        const logoHrefAccesibilityText = intl.formatMessage({
            id: "gs.header.href.accessibility",
        });
        const imageAltAccessibilityText = intl.formatMessage({
            id: "gs.header.logo.title.accessibility",
        });
        return (_jsx("a", { "aria-label": logoHrefAccesibilityText, title: logoHrefAccesibilityText, href: logoHref, onClick: onLogoClick, className: logoLinkClassName, children: _jsx("img", { src: logoUrl, title: logoTitle, onLoad: measureChildren, onError: measureChildren, alt: imageAltAccessibilityText }) }));
    }, [intl, logoHref, onLogoClick, logoUrl, logoTitle, measureChildren]);
    const renderSearchMenu = useCallback(() => {
        return (_jsxs("div", { className: "gd-header-menu-search", children: [_jsx(Typography, { tagName: "h3", className: "gd-header-menu-search-title", children: _jsx(FormattedMessage, { id: "gs.header.search" }) }), _jsx(HeaderSearchProvider, { isOpen: state.isSearchMenuOpen, toggleOpen: toggleSearchMenu, children: search })] }));
    }, [state.isSearchMenuOpen, toggleSearchMenu, search]);
    const renderNotificationsOverlay = useCallback(() => {
        if (!notificationsPanel) {
            return null;
        }
        return (_jsxs("div", { className: "gd-header-menu-notifications", children: [_jsx(Typography, { tagName: "h3", className: "gd-header-menu-notifications-title", children: _jsx(FormattedMessage, { id: "gs.header.notifications" }) }), notificationsPanel({
                    isMobile: true,
                    closeNotificationsOverlay: closeNotificationsMenu,
                })] }));
    }, [notificationsPanel, closeNotificationsMenu]);
    const renderTrialItems = useCallback(() => {
        if (expiredDate || showUpsellButton) {
            return (_jsxs("div", { className: "gd-header-menu-trial gd-header-measure", children: [expiredDate ? (_jsx("div", { className: "gd-header-expiration-date", children: getTrialCountdown(expiredDate) })) : null, showUpsellButton ? (_jsx(HeaderUpsellButton, { onUpsellButtonClick: onUpsellButtonClick })) : null] }));
        }
        return null;
    }, [expiredDate, showUpsellButton, getTrialCountdown, onUpsellButtonClick]);
    const renderLogoutButton = useCallback(() => {
        const [logoutMenuItem] = accountMenuItems.filter((item) => item.key === "gs.header.logout");
        const LogoutIcon = Icon["Logout"];
        return logoutMenuItem ? (_jsxs("button", { className: "logout-button gd-button s-logout", onClick: (e) => {
                onMenuItemClick(logoutMenuItem, e);
            }, children: [_jsx(LogoutIcon, { className: "gd-icon-logout", color: theme?.palette?.complementary?.c0 }), _jsx("span", { className: "gd-button-text", children: _jsx(FormattedMessage, { id: "gs.header.logout" }) })] })) : (false);
    }, [accountMenuItems, onMenuItemClick, theme?.palette?.complementary?.c0]);
    const renderVerticalMenu = useCallback(() => {
        const menuItemsGroupsToRender = state.isHelpMenuOpen
            ? getHelpMenu()
            : showStaticHelpMenu
                ? [[getHelpMenuLink()]]
                : addHelpItemGroup(addAdditionalItems(menuItemsGroups));
        return (_jsxs("div", { className: "gd-header-menu-vertical-wrapper", children: [_jsx("div", { className: "gd-header-menu-vertical-header", children: "Menu" }), _jsxs("div", { className: "gd-header-menu-vertical-content", children: [_jsx(HeaderMenu, { onMenuItemClick: handleMenuItemClick, sections: menuItemsGroupsToRender, className: "gd-header-menu-vertical" }), renderTrialItems()] }), _jsxs("div", { className: "gd-header-menu-vertical-footer", children: [!!badges && _jsx("div", { className: "gd-header-vertical-badges", children: badges }), _jsx("div", { className: "gd-header-menu-vertical-bottom-item", children: _jsx("span", { className: "gd-header-username gd-icon-user", children: userName }) }), _jsx("div", { children: renderLogoutButton() })] })] }, "overlay-menu"));
    }, [
        state.isHelpMenuOpen,
        showStaticHelpMenu,
        getHelpMenuLink,
        addHelpItemGroup,
        addAdditionalItems,
        menuItemsGroups,
        getHelpMenu,
        handleMenuItemClick,
        renderTrialItems,
        badges,
        userName,
        renderLogoutButton,
    ]);
    const renderOverlayMenu = useCallback(() => {
        let content = renderVerticalMenu();
        if (state.isSearchMenuOpen) {
            content = renderSearchMenu();
        }
        if (state.isNotificationsMenuOpen) {
            content = renderNotificationsOverlay();
        }
        return (_jsx(Overlay, { alignPoints: [
                {
                    align: state.isSearchMenuOpen || state.isNotificationsMenuOpen ? "tl tl" : "tr tr",
                },
            ], closeOnOutsideClick: state.isOverlayMenuOpen, isModal: state.isOverlayMenuOpen, positionType: "fixed", onClose: () => {
                setOverlayMenu(false);
            }, children: content }, "header-overlay-menu"));
    }, [
        renderVerticalMenu,
        state.isSearchMenuOpen,
        state.isNotificationsMenuOpen,
        renderSearchMenu,
        renderNotificationsOverlay,
        state.isOverlayMenuOpen,
        setOverlayMenu,
    ]);
    const renderMobileNav = useCallback(() => {
        const iconClasses = cx({
            "hamburger-icon": true,
            "is-open": state.isOverlayMenuOpen,
            "search-open": state.isSearchMenuOpen,
            "notifications-open": state.isNotificationsMenuOpen,
        });
        return (_jsxs(_Fragment, { children: [_jsx("div", { className: "hamburger-wrapper", children: _jsx("div", { className: iconClasses, onClick: () => {
                            setOverlayMenu(!state.isOverlayMenuOpen);
                        }, children: _jsx("i", {}) }, "hamburger-icon") }, "hamburger-wrapper"), state.isOverlayMenuOpen ? renderOverlayMenu() : null] }));
    }, [
        state.isOverlayMenuOpen,
        state.isSearchMenuOpen,
        state.isNotificationsMenuOpen,
        setOverlayMenu,
        renderOverlayMenu,
    ]);
    const renderStandardNav = useCallback(() => {
        return (_jsxs("div", { className: "gd-header-stretch gd-header-menu-wrapper", children: [_jsx(HeaderMenu, { onMenuItemClick: onMenuItemClick, sections: menuItemsGroups, className: "gd-header-menu-horizontal" }), renderTrialItems(), showChatItem ? (_jsx(HeaderChatButton, { title: intl.formatMessage({ id: "gs.header.ai" }), color: theme?.palette?.primary?.base, onClick: onChatItemClick })) : null, notificationsPanel
                    ? notificationsPanel({
                        isMobile: false,
                        closeNotificationsOverlay: closeNotificationsMenu,
                    })
                    : null, search ? (_jsx(HeaderSearchProvider, { isOpen: state.isSearchMenuOpen, toggleOpen: toggleSearchMenu, children: _jsx(HeaderSearchButton, { title: intl.formatMessage({ id: "gs.header.search" }), children: search }) })) : null, helpMenuItems.length ? (_jsx(HeaderHelp, { onMenuItemClick: onMenuItemClick, className: "gd-header-measure", helpMenuDropdownAlignPoints: helpDropdownAlign, items: helpMenuItems, disableDropdown: disableHelpDropdown, onHelpClicked: onHelpClick, helpRedirectUrl: helpRedirectUrl })) : null, _jsx(HeaderAccount, { userName: userName, onMenuItemClick: onMenuItemClick, className: "gd-header-measure", items: accountMenuItems }), badges ? _jsx("div", { className: "gd-header-badges gd-header-measure", children: badges }) : null] }));
    }, [
        onMenuItemClick,
        menuItemsGroups,
        renderTrialItems,
        showChatItem,
        intl,
        theme?.palette?.primary?.base,
        onChatItemClick,
        notificationsPanel,
        closeNotificationsMenu,
        search,
        state.isSearchMenuOpen,
        toggleSearchMenu,
        helpMenuItems,
        helpDropdownAlign,
        disableHelpDropdown,
        onHelpClick,
        helpRedirectUrl,
        userName,
        accountMenuItems,
        badges,
    ]);
    const renderNav = useCallback(() => {
        return state.responsiveMode ? renderMobileNav() : renderStandardNav();
    }, [state.responsiveMode, renderMobileNav, renderStandardNav]);
    useEffect(() => {
        createStyles();
    }, [createStyles]);
    const logoLinkClassName = useMemo(() => cx({
        "gd-header-logo": true,
        "gd-header-measure": true,
        "gd-header-shrink": state.responsiveMode,
    }), [state.responsiveMode]);
    const applicationHeaderAccessibilityLabel = useMemo(() => intl.formatMessage({
        id: "gs.header.accessibility.label",
    }), [intl]);
    return (_jsxs("header", { "aria-label": applicationHeaderAccessibilityLabel, className: getClassNames(), ref: nodeRef, children: [isAccessibilityCompliant
                ? renderAccessibilityLogo(logoLinkClassName)
                : renderLogo(logoLinkClassName), workspacePicker, renderNav()] }));
}
/**
 * @internal
 */
export const AppHeader = withTheme(injectIntl(AppHeaderCore));
//# sourceMappingURL=Header.js.map