import type { EServiceTemplateGoogleConsentModeTypes } from "@devowl-wp/api-real-cookie-banner";
import type { CookieConsentManagerOptions, DecisionConsentGroups } from "@devowl-wp/cookie-consent-web-client";
import { Cookie, getUserDecision, getUserGcmDecision } from "@devowl-wp/cookie-consent-web-client";

import type { BlockerContext } from "../../contexts/blocker.js";

function useBlockerStateContextCallbacks(
    opts: Pick<CookieConsentManagerOptions, "decisionCookieName" | "tcfCookieName" | "gcmCookieName">,
): Pick<BlockerContext["provider"]["modifiers"], "onUnblock"> {
    return {
        onUnblock: (
            { onPersistConsent, onApplyConsent, groups, blocker, recorder, isGcm, gcmConsent: blockerGcmConsent },
            event,
        ) => {
            const { decisionCookieName, tcfCookieName, gcmCookieName } = opts;
            const { services, visualThumbnail, id: blockerId } = blocker;
            const currentDecision = getUserDecision(decisionCookieName);
            const essentialGroupObj = groups.find(({ isEssential }) => isEssential);

            // Prepare new consent
            const newConsent: DecisionConsentGroups =
                currentDecision === false
                    ? // The website owner uses a banner without overlay and content gets unblocked
                      // We need to make sure, that also essential cookies got accepted
                      {
                          [essentialGroupObj.id]: essentialGroupObj.items.map(({ id }) => id),
                      }
                    : currentDecision.consent;

            for (const { id: groupId, items } of groups) {
                for (const { id: cookieId } of items) {
                    if (services.indexOf(cookieId) > -1) {
                        // Avoid duplicates
                        if (newConsent[groupId]?.indexOf(cookieId) > -1) {
                            continue;
                        }

                        newConsent[groupId] = newConsent[groupId] || [];
                        newConsent[groupId].push(cookieId);
                    }
                }
            }

            // Create modified GCM consent and keep previous consents intact and add new consent types
            let gcmConsent: EServiceTemplateGoogleConsentModeTypes[];
            /* onlypro:start */
            if (process.env.PLUGIN_CTX === "pro" && isGcm) {
                gcmConsent = getUserGcmDecision(
                    gcmCookieName,
                    currentDecision === false ? undefined : currentDecision.buttonClicked,
                );
                gcmConsent.push(...blockerGcmConsent.filter((type) => gcmConsent.indexOf(type) === -1));
            }
            /* onlypro:end */

            onPersistConsent({
                consent: newConsent,
                gcmConsent,
                buttonClicked: "unblock",
                blocker: blockerId,
                blockerThumbnail: visualThumbnail?.embedId
                    ? `${visualThumbnail.embedId}-${visualThumbnail.fileMd5}`
                    : undefined,
                // Keep TCF string as it is not touched for a content blocker
                tcfString: () => Cookie.get(tcfCookieName),
                recorderJsonString: recorder ? JSON.stringify(recorder.createReplay()) : undefined,
                uiView: "initial",
                event,
            }).then(() => onApplyConsent());
        },
    };
}

export { useBlockerStateContextCallbacks };
