import { observer } from "mobx-react";
import { useEffect, useLayoutEffect, useRef } from "react";

import type { BlockerContext } from "@devowl-wp/react-cookie-banner";
import { Blocker, useBlockerProvider, useStateContextCallbacks } from "@devowl-wp/react-cookie-banner";
import { Player, RECORD_ITEM_TYPE_PAUSE } from "@devowl-wp/web-html-element-interaction-recorder";

import { useStores } from "../../../../store/stores.js";
import { BannerProductionNotice } from "../../../bannerProductionNotice.js";

import type { Consent } from "../../../../models/consent.js";
import type { FC } from "react";

/**
 * Show a blocker from a given record in "Consent" table.
 */
const ConsentRecordBlocker: FC<{
    record: Consent;
    replayBlockerRecord?: boolean;
    replayFinished: () => void;
}> = observer(({ record, replayBlockerRecord, replayFinished }) => {
    /* onlypro:start */
    const ref = useRef<HTMLDivElement>();
    const {
        optionStore: {
            others: { bannerI18n, iso3166OneAlpha2 },
        },
    } = useStores();
    const {
        blocker_thumbnail,
        design_version,
        revision: {
            data: { groups, options, websiteOperator, predefinedDataProcessingInSafeCountriesLists },
        },
        blocker,
        recorder,
        revision_independent: {
            data: {
                banner: { customizeValuesBanner },
                blocker: allBlocker,
                links,
                consentForwardingExternalHosts,
                isPro,
                isLicensed,
                isDevLicense,
            },
        },
    } = record;

    const modifiers = useStateContextCallbacks<BlockerContext>();

    const [blockerDef] = allBlocker.filter(({ id }) => id === blocker);
    if (blocker_thumbnail) {
        blockerDef.visualThumbnail = blocker_thumbnail;
    }

    // Replay recorder
    useEffect(() => {
        if (replayBlockerRecord && recorder) {
            const player = new Player(JSON.parse(recorder), ref.current);
            player.reflowFirstRealInteraction();
            const [, dispatch] = player.start({
                afterReplayItem: async ([type]) => {
                    if (type === RECORD_ITEM_TYPE_PAUSE) {
                        replayFinished();
                    }
                },
            });
            return dispatch;
        }

        return () => {
            // Silence is golden.
        };
    }, [replayBlockerRecord, replayFinished]);

    // Context values preparation
    const [BlockerContextProvider, blockerContextValue] = useBlockerProvider(
        {
            container: ref.current,
            ...customizeValuesBanner,
            ...options,
            consentForwardingExternalHosts,
            groups,
            links,
            websiteOperator,
            designVersion: design_version,
            gcmConsent: [],
            i18n: bannerI18n,
            consent: record.previous_decision,
            productionNotice: (
                <BannerProductionNotice
                    isPro={isPro}
                    isLicensed={isLicensed}
                    isDevLicense={isDevLicense}
                    i18n={bannerI18n}
                />
            ),
            iso3166OneAlpha2,
            predefinedDataProcessingInSafeCountriesLists,
            isConsentRecord: true,
            blocker: blockerDef,
            onPersistConsent: async () => {},
            onApplyConsent: async () => {},
        },
        { ...modifiers, onUnblock: () => {} },
    );

    // Use `useLayoutEffect` to set the gcmConsent synchronous as the content blocker is not opened through a
    // modal like the cookie banner so we need to manage the consent state correctly. This is used in combination
    // with `skipInitialConsent` and `useLayoutEffect` makes sure that this callback is set **before**
    // the content blocker prefills the GCM consent through `useEffect`.
    useLayoutEffect(() => {
        blockerContextValue.set({ gcmConsent: replayBlockerRecord ? [] : record.gcm_consent });
    }, [replayBlockerRecord]);

    return (
        <div className="rcb-transparent-bg" ref={ref}>
            <BlockerContextProvider value={blockerContextValue}>
                <Blocker skipInitialConsent={!replayBlockerRecord} />
            </BlockerContextProvider>
        </div>
    );
    /* onlypro:end */
});

export { ConsentRecordBlocker };
