import { useCallback } from "react";

import { yieldMainThread } from "@devowl-wp/react-utils";

import { useBanner } from "../../contexts/banner.js";

/**
 * Provide callbacks for all the available button types in our cookie banner:
 *
 * - Accept all
 * - Continue without consent (accept essentials)
 * - Save custom choices (no changes to the current selected groups and services)
 * - Change individual privacy preferences
 */
function useBannerButtonCallbacks() {
    const {
        individualPrivacyOpen,
        onSave,
        updateGroupChecked,
        updateCookieChecked,
        groups,
        activeAction,
        onClose,
        set,
    } = useBanner();
    const buttonClickedAll: "ind_all" | "main_all" = individualPrivacyOpen ? "ind_all" : "main_all";
    const buttonClickedEssentials: "ind_essential" | "main_essential" = individualPrivacyOpen
        ? "ind_essential"
        : "main_essential";
    const buttonClickedCloseIcon: "ind_close_icon" | "main_close_icon" = individualPrivacyOpen
        ? "ind_close_icon"
        : "main_close_icon";
    const buttonClickedCustom: "ind_custom" | "main_custom" = individualPrivacyOpen ? "ind_custom" : "main_custom";

    const result = {
        buttonClickedAll,
        buttonClickedEssentials,
        buttonClickedCloseIcon,
        buttonClickedCustom,
        acceptAll: useCallback(async () => {
            await yieldMainThread();
            set(({ updateGroupChecked }) => {
                groups.forEach((g) => updateGroupChecked(g.id, true));
            });
            await yieldMainThread();
            onSave(false, buttonClickedAll);
        }, [buttonClickedAll]),
        /**
         * This includes the complete "Essential" group + legal basis = legitimate interests.
         */
        acceptEssentials: useCallback(
            (isCloseIcon = false) => {
                groups.forEach(({ isEssential, id, items }) => {
                    if (isEssential) {
                        updateGroupChecked(id, true);
                    } else {
                        for (const { legalBasis, id: cookieId } of items) {
                            updateCookieChecked(id, cookieId, legalBasis === "legitimate-interest");
                        }
                    }
                });
                onSave(false, isCloseIcon === true ? buttonClickedCloseIcon : buttonClickedEssentials);
            },
            [buttonClickedEssentials],
        ),
        acceptIndividual: useCallback(() => onSave(false, buttonClickedCustom), [buttonClickedCustom]),
        openIndividualPrivacy: useCallback(() => set({ individualPrivacyOpen: true }), [set]),
    };

    return {
        ...result,
        closeIcon: useCallback(() => {
            if (!activeAction) {
                // If we do not have yet a consent and it shows the banner for the first time,
                // the close icon is equivalent to "Continue without consent"
                result.acceptEssentials(true);
            } else {
                onClose();
            }
        }, [activeAction, onClose, result.acceptEssentials]),
    };
}

export { useBannerButtonCallbacks };
