import { Suspense, useMemo } from "react";

import type { BlockerMountPaintMode, SetVisualAsLastClickedVisual } from "@devowl-wp/headless-content-unblocker";
import type { BlockerContext, CommonContextProps } from "@devowl-wp/react-cookie-banner";
import {
    Blocker,
    useBlockerProvider,
    useBlockerStateContextCallbacks,
    useStateContextCallbacks,
} from "@devowl-wp/react-cookie-banner";
import { yieldLazyLoad } from "@devowl-wp/react-utils";
import { Recorder } from "@devowl-wp/web-html-element-interaction-recorder";

import { BannerProductionNotice } from "./bannerProductionNotice.js";
import { getCookieConsentManager } from "../others/getCookieConsentManager.js";
import { persistConsent } from "../others/persistConsent.js";
import { getOtherOptionsFromWindow } from "../utils/getOtherOptionsFromWindow.js";

import type { BlockerDefinition } from "../types/blocker.js";
import type { FC } from "react";

const YieldBlocker = yieldLazyLoad(Promise.resolve(Blocker));

/**
 * Simply connects a context store to the blocker itself. On the website itself
 * it should not rely
 */
const WebsiteBlocker: FC<{
    container: HTMLElement;
    blockedNode: HTMLElement;
    createBefore: HTMLElement;
    poweredLink?: CommonContextProps["poweredLink"];
    blocker: BlockerDefinition;
    paintMode?: BlockerMountPaintMode;
    /**
     * The connected counter, dispatched to the unblock event.
     */
    setVisualAsLastClickedVisual: SetVisualAsLastClickedVisual;
}> = ({ container, blockedNode, createBefore, poweredLink, blocker, paintMode, setVisualAsLastClickedVisual }) => {
    const {
        frontend,
        customizeValuesBanner,
        iso3166OneAlpha2,
        bannerDesignVersion,
        bannerI18n,
        isPro,
        isLicensed,
        isDevLicense,
        affiliate,
        isCurrentlyInTranslationEditorPreview,
    } = useMemo(() => getOtherOptionsFromWindow(), []);
    const manager = getCookieConsentManager();
    const userDecision = manager.getUserDecision(true);
    const recorder = useMemo(() => new Recorder(container), []);

    const modifiers = useStateContextCallbacks<BlockerContext>();
    const { onUnblock } = useBlockerStateContextCallbacks(manager.getOptions());

    // Context values preparation
    const [BlockerContextProvider, blockerContextValue] = useBlockerProvider(
        {
            recorder,
            container,
            blockedNode,
            createBefore,
            ...customizeValuesBanner,
            ...frontend,
            productionNotice: (
                <BannerProductionNotice
                    isPro={isPro}
                    isLicensed={isLicensed}
                    isDevLicense={isDevLicense}
                    i18n={bannerI18n}
                />
            ),
            paintMode,
            poweredLink,
            iso3166OneAlpha2,
            gcmConsent: [],
            blocker,
            designVersion: bannerDesignVersion,
            i18n: bannerI18n,
            keepVariablesInTexts: isCurrentlyInTranslationEditorPreview,
            affiliate,
            consent: {
                ...(userDecision === false ? {} : userDecision.consent),
            },
            onPersistConsent: persistConsent,
            onApplyConsent: () => getCookieConsentManager().applyCookies({ type: "consent" }),
        },
        {
            ...modifiers,
            onUnblock: (contextValue, event) => {
                onUnblock(contextValue, event);
                setVisualAsLastClickedVisual(event);
            },
        },
    );

    return (
        <BlockerContextProvider value={blockerContextValue}>
            <Suspense fallback={null}>
                <YieldBlocker />
            </Suspense>
        </BlockerContextProvider>
    );
};

export { WebsiteBlocker };
