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

import type { MainStyleSheetReturn } from "../main.js";

type BodyDesignStyle = "acceptAll" | "acceptEssentials" | "acceptIndividual";
type Style = BodyDesignStyle | "save";

const extendCommonButtonsStylesheet = [
    Symbol("extendCommonButtonsStylesheet"),
    (
        { className, jsx, boolIf, boolSwitch, boolOr }: CreatePureScopedStylesheetCallbackArgs,
        {
            screenReaderOnlyClass,
            isTcf,
            decision,
            layout,
            saveButton,
            bodyDesign,
            design,
            boolLargeOrMobile,
        }: MainStyleSheetReturn,
    ) => {
        const framed = className();
        const forceShowButton = className();
        const stickyButton = className();

        const [acceptAll, acceptEssentials, acceptIndividual, save] = (
            ["acceptAll", "acceptEssentials", "acceptIndividual", "save"] as Style[]
        ).map((style) => {
            const isSaveButton = style === "save";
            const type = isSaveButton ? saveButton["type"] : decision[style as BodyDesignStyle];
            const bg = isSaveButton ? saveButton["bg"] : bodyDesign[`${style as BodyDesignStyle}Bg` as const];
            const hoverBg = isSaveButton
                ? saveButton["hoverBg"]
                : bodyDesign[`${style as BodyDesignStyle}HoverBg` as const];
            const padding = isSaveButton
                ? saveButton["padding"]
                : bodyDesign[`${style as BodyDesignStyle}Padding` as const];
            const fontSize = isSaveButton
                ? saveButton["fontSize"]
                : bodyDesign[`${style as BodyDesignStyle}FontSize` as const];
            const textAlign = isSaveButton
                ? saveButton["textAlign"]
                : bodyDesign[`${style as BodyDesignStyle}TextAlign` as const];
            const fontWeight = isSaveButton
                ? saveButton["fontWeight"]
                : bodyDesign[`${style as BodyDesignStyle}FontWeight` as const];
            const fontColor = isSaveButton
                ? saveButton["fontColor"]
                : bodyDesign[`${style as BodyDesignStyle}FontColor` as const];
            const hoverFontColor = isSaveButton
                ? saveButton["hoverFontColor"]
                : bodyDesign[`${style as BodyDesignStyle}HoverFontColor` as const];
            const borderColor = isSaveButton
                ? saveButton["borderColor"]
                : bodyDesign[`${style as BodyDesignStyle}BorderColor` as const];
            const hoverBorderColor = isSaveButton
                ? saveButton["hoverBorderColor"]
                : bodyDesign[`${style as BodyDesignStyle}HoverBorderColor` as const];
            const borderWidth = isSaveButton
                ? saveButton["borderWidth"]
                : bodyDesign[`${style as BodyDesignStyle}BorderWidth` as const];

            const fontSizeBool = boolLargeOrMobile(fontSize, boolIf);
            const boolTcfOrOneRowLayout = boolOr([isTcf, bodyDesign.acceptAllOneRowLayout]);

            const [JsxButton] = jsx(
                "a",
                {
                    classNames: `btn-${style.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}`,
                    all: "unset",
                    display: "flex",
                    ...(isSaveButton ? {} : { display: boolIf(type("is-hide" as any), "none", "flex") }),
                    borderRadius: layout.borderRadius(),
                    overflow: "hidden",
                    textAlign: textAlign("val"),
                    color: fontColor(),
                    transition: "background-color 250ms, color 250ms, border-color 250ms",
                    cursor: boolIf(type("is-button"), "pointer"),
                    textDecoration: boolIf(type("is-link"), "underline"),
                    backgroundColor: boolIf(type("is-button"), bg()),
                    borderStyle: "solid",
                    borderColor: borderColor(),
                    borderWidth: boolIf(type("is-button"), boolLargeOrMobile(borderWidth, boolIf), "0px"),
                    flex: "1 1 100%",
                    alignItems: "center",
                    // text-align is not supported within a `display: flex`
                    justifyContent: boolSwitch(
                        [
                            [textAlign("is-right"), "flex-end"],
                            [textAlign("is-center"), "center"],
                        ],
                        "left",
                    ),
                    pointerEvents: boolIf(type("is-link"), "none"),
                    ...(["acceptEssentials", "save"].indexOf(style) > -1
                        ? {
                              // For two-button row layout and TCF use all dimensional properties from "Accept all"
                              fontSize: boolIf(
                                  boolTcfOrOneRowLayout,
                                  boolLargeOrMobile(bodyDesign.acceptAllFontSize, boolIf),
                                  fontSizeBool,
                              ),
                              fontWeight: boolIf(boolTcfOrOneRowLayout, bodyDesign.acceptAllFontWeight(), fontWeight()),
                              padding: boolIf(boolTcfOrOneRowLayout, bodyDesign.acceptAllPadding("l"), padding("l")),
                          }
                        : {
                              fontSize: fontSizeBool,
                              fontWeight: fontWeight(),
                              padding: padding("l"),
                          }),
                    pseudos: {
                        [`.${forceShowButton}`]: {
                            display: "block",
                        },
                        ">span": {
                            cursor: boolIf(type("is-link"), "pointer"),
                            pointerEvents: boolIf(type("is-link"), "all"),
                            // Some themes are overriding the styles of `<a` links
                            color: fontColor(),
                        },
                        ":hover>span": {
                            color: hoverFontColor(),
                        },
                        [`.${framed}`]: {
                            outline: "rgb(255, 94, 94) solid 5px",
                        },
                        [`.${stickyButton}`]: {
                            position: "sticky",
                            bottom: "6px",
                            boxShadow: `0px 10px 0px 0px ${design.bg()}, 0px -10px 0px ${design.bg()}`,
                        },
                        ":hover": {
                            color: hoverFontColor(),
                            backgroundColor: boolIf(type("is-button"), hoverBg()),
                            borderColor: hoverBorderColor(),
                            textDecoration: boolIf(type("is-link"), "none"),
                        },
                    },
                },
                {
                    href: "#",
                },
            );

            return JsxButton;
        });

        const [A11ySkipToLink] = jsx(
            "a",
            {
                classNames: ["skip-to", screenReaderOnlyClass],
                pseudos: {
                    ":focus-visible": {
                        clip: "initial",
                        width: "initial",
                        height: "initial",
                        zIndex: 10,
                        left: "10px",
                        top: "10px",
                        padding: "5px 10px",
                        background: "black",
                        color: "white",
                        fontSize: "14px",
                    },
                },
            },
            {
                onClick: (e) => {
                    e.preventDefault();
                    document.getElementById((e.target as HTMLAnchorElement).getAttribute("href").substr(1)).focus();
                },
            },
        );

        return {
            A11ySkipToLink,
            framed,
            stickyButton,
            forceShowButton,
            buttons: {
                acceptAll,
                acceptEssentials,
                acceptIndividual,
                save,
            },
        };
    },
] as const;

export { extendCommonButtonsStylesheet };
