import type { CreatePureScopedStylesheetCallbackArgs, PureScopedStyleSheetRules } from "@devowl-wp/web-scoped-css";

import type { BannerStyleSheetReturn } from "./banner.js";

const extendBannerBubbleStylesheet = [
    Symbol("extendBannerBubbleStylesheet"),
    (
        { rule, boolSwitch, boolIf, className }: CreatePureScopedStylesheetCallbackArgs,
        {
            boolLargeOrMobile,
            sticky: {
                animationsEnabled,
                alignment,
                bubbleBorderRadius,
                bubbleBg,
                bubbleMargin,
                bubblePadding,
                bubbleBorderWidth,
                bubbleBorderColor,
                iconColor,
                iconSize,
                boxShadowEnabled,
                boxShadowColor,
                boxShadowOffsetX,
                boxShadowOffsetY,
                boxShadowBlurRadius,
                boxShadowSpreadRadius,
                boxShadowColorAlpha,
                bubbleHoverBg,
                bubbleHoverBorderColor,
                hoverIconColor,
                menuBorderRadius,
                menuFontSize,
                menuItemSpacing,
                menuItemPadding,
            },
        }: BannerStyleSheetReturn,
    ) => {
        const zIndex = 999999;
        const [, stickyBar] = rule({
            classNames: "sticky",
            zIndex,
            pointerEvents: "none !important",
            position: "fixed",
            bottom: "0px",
            left: "0px",
            right: "0px",
            display: "flex",
            justifyContent: boolSwitch([
                [alignment("is-left"), "flex-start"],
                [alignment("is-center"), "center"],
                [alignment("is-right"), "flex-end"],
            ]),
            pseudos: {
                ">div": {
                    position: "relative",
                },
            },
        });

        const iconSizeWidth = boolLargeOrMobile(iconSize, boolIf);
        const commonBubbleAndLinkStyle: PureScopedStyleSheetRules = {
            cursor: "pointer",
            boxShadow: boolIf(
                boxShadowEnabled,
                `${boxShadowOffsetX()} ${boxShadowOffsetY()} ${boxShadowBlurRadius()} ${boxShadowSpreadRadius()} rgba(${boxShadowColor(
                    "r",
                )} ${boxShadowColor("g")} ${boxShadowColor("b")} / ${boxShadowColorAlpha()})`,
            ),
        };

        const bubbleActive = className();
        /**
         * Allows to skip `transition` on mount (e.g. bubble is first white and then gets transitioned to blue).
         *
         * @see https://www.thomasledoux.be/blog/avoid-flash-unwanted-animation-first-render-react
         */
        const bubbleMounted = className();
        const bubblePaddingUse = boolLargeOrMobile(bubblePadding, boolIf);
        const [, bubble] = rule({
            classNames: "bubble",
            ...commonBubbleAndLinkStyle,
            zIndex,
            display: "block",
            position: "relative",
            borderRadius: bubbleBorderRadius(),
            padding: bubblePaddingUse,
            backgroundColor: bubbleBg(),
            pointerEvents: "all !important",
            margin: boolLargeOrMobile(bubbleMargin, boolIf),
            color: iconColor(),
            fontSize: iconSizeWidth,
            border: `${bubbleBorderWidth()} solid ${bubbleBorderColor()}`,
            lineHeight: iconSizeWidth,
            width: iconSizeWidth,
            height: iconSizeWidth,
            boxSizing: "content-box",
            overflow: "hidden",
            pseudos: {
                ">svg": {
                    width: iconSizeWidth,
                    height: iconSizeWidth,
                    verticalAlign: "initial",
                },
                ">img": {
                    width: "auto",
                    height: iconSizeWidth,
                },
                [`:hover,:has(+div :focus-visible),<.${bubbleActive} `]: {
                    backgroundColor: `${bubbleHoverBg()} !important`,
                    borderColor: `${bubbleHoverBorderColor()} !important`,
                    color: `${hoverIconColor()} !important`,
                },
                [`<.${bubbleMounted} `]: {
                    transition: "background 250ms, border 250ms, color 250ms",
                },
            },
        });

        const [, menu] = rule({
            classNames: "sticky-menu",
            position: "absolute",
            bottom: "100%",
            left: boolIf(
                alignment("is-left"),
                boolLargeOrMobile(bubbleMargin, boolIf, 3),
                boolIf(alignment("is-center"), "0px"),
            ),
            right: boolIf(alignment("is-right"), boolLargeOrMobile(bubbleMargin, boolIf, 1)),
            textAlign: alignment("val"),
            width: "100vw",
            marginLeft: boolIf(
                alignment("is-center"),
                `calc(-50vw + ${bubblePaddingUse} + ${boolLargeOrMobile(
                    bubbleMargin,
                    boolIf,
                    1,
                )} + ${bubbleBorderWidth()} + (${iconSizeWidth} / 2))`,
            ),
            pointerEvents: "none !important",
            zIndex: zIndex - 1,
            pseudos: {
                ":has(:focus-visible)": {
                    display: "block !important",
                    opacity: "1 !important",
                    transform: "initial !important",
                },
                ">ul,>ul>li": {
                    all: "unset",
                    pointerEvents: "none",
                    display: "block",
                },
                ">ul>li:not(:last-of-type)": {
                    marginBottom: boolLargeOrMobile(menuItemSpacing, boolIf),
                },
                ">ul>li>a": {
                    all: "unset",
                    display: "inline-block",
                    textDecoration: "none",
                    backgroundColor: bubbleHoverBg(),
                    border: `${bubbleBorderWidth()} solid ${bubbleHoverBorderColor()}`,
                    color: hoverIconColor(),
                    pointerEvents: "all",
                    fontSize: boolLargeOrMobile(menuFontSize, boolIf),
                    transition: "margin 0.3s",
                    borderRadius: menuBorderRadius(),
                    padding: boolLargeOrMobile(menuItemPadding, boolIf),
                    ...commonBubbleAndLinkStyle,
                },
                ">ul>li>a:hover": {
                    textDecoration: "underline",
                    marginLeft: boolIf(animationsEnabled, "10px"),
                },
            },
        });

        rule({
            forceSelector: `:not(.${bubbleActive})>.${menu}>ul>li>a`,
            pointerEvents: "none !important",
        });

        return { stickyBar, bubble, bubbleActive, menu, bubbleMounted };
    },
] as const;

export { extendBannerBubbleStylesheet };
