import { HTML_ATTRIBUTE_BLOCKER_ID } from "@devowl-wp/headless-content-unblocker";
import { idx } from "@devowl-wp/react-utils";

const APIS = ["youtube", "vimeo"];

/**
 * Overwrite the video API of elementor to make it GDPR compliant.
 *
 * @see https://github.com/elementor/elementor/pull/12567
 */
function overwriteElementorVideoApi() {
    const { wrapFn, unblock } = window.consentApi;
    wrapFn(
        {
            // See https://github.com/elementor/elementor/blob/2ee675caf03908f8c66e16298e923a24b206df54/assets/dev/js/frontend/frontend.js#L180-L183
            object: () => idx(window as any, (window) => window.elementorFrontend),
            key: "initOnReadyComponents",
        },
        ({ callOriginal, objectResolved }) => {
            // Overwrite onDocumentLoaded to wait for our overwriting mechanism to avoid background videos be loaded before overwriting
            // See https://github.com/elementor/elementor/blob/2ee675caf03908f8c66e16298e923a24b206df54/assets/dev/js/frontend/frontend.js#L208
            let promiseOverwrittenResolve: (value: void | PromiseLike<void>) => void;
            const promiseOverwritten = new Promise<void>((resolve) => {
                promiseOverwrittenResolve = resolve;
            });
            wrapFn(
                {
                    object: objectResolved,
                    key: "onDocumentLoaded",
                },
                promiseOverwritten,
            );

            // Call original function to feed `elementorFrontend` with `.utils`
            callOriginal();

            // Overwrite the `getDefaultSettings` function to select the correct `<script` as first tag (scenario: first tag
            // is a blocked element and the reference gets invalid as our unblocking mechanism removes the blocked element).
            const firstScript = jQuery(`script:not([${HTML_ATTRIBUTE_BLOCKER_ID}]):first`);

            // Overwrite the API functions
            wrapFn(
                // See https://github.com/elementor/elementor/tree/2cd3d50d8d87edde9cd3c820f5a0f8b1f2c4f24f/assets/dev/js/frontend/utils/video-api
                APIS.map((api) => ({
                    object: objectResolved.utils[api],
                    key: "insertAPI",
                })),
                ({ objectResolved, that }) => {
                    that.setSettings("isInserted", true);
                    that.elements.$firstScript = firstScript;
                    return unblock(objectResolved.getApiURL());
                },
            );
            promiseOverwrittenResolve();

            // We do no longer need to execute the function as we already called it with `callOriginal`
            return false;
        },
    );
}

export { overwriteElementorVideoApi };
