import { putHtmlCodeToDom } from "@devowl-wp/headless-content-unblocker";

import { deleteCookiesLocally } from "./deleteCookiesLocally.js";
import { getServiceSelection } from "../decision/getServiceSelection.js";
import { OPT_OUT_EVENT } from "../events/optOut.js";

import type { GetServiceSelectionOptions } from "../decision/getServiceSelection.js";
import type { OptOutEvent } from "../events/optOut.js";
import type { OptOutAllEvent } from "../events/optOutAll.js";

/**
 * Opt-in to a set of services for a given data manager like GTM / MTM.
 */
async function applyOptOut(options: GetServiceSelectionOptions, isManagerOptOut: boolean) {
    const allOptOutServices: OptOutAllEvent["services"] = [];
    const { isManagerActive, iterateServices } = getServiceSelection(options);
    const waitPromises: Promise<void>[] = [];

    // Handle opt-outs sequentially
    const deleteHttpCookies: number[] = [];
    await iterateServices(async (group, service, isOptIn) => {
        const {
            id,
            codeDynamics,
            codeOptOut,
            deleteTechnicalDefinitionsAfterOptOut,
            isEmbeddingOnlyExternalResources,
            technicalDefinitions,
            executeCodeOptOutWhenNoTagManagerConsentIsGiven,
        } = service;
        if (!isOptIn) {
            // Check if the script should explicitly only be loaded if no consent is given to the manager
            const isOnlyWhenNoConsentToManager = isManagerActive && executeCodeOptOutWhenNoTagManagerConsentIsGiven;

            if ((isOnlyWhenNoConsentToManager && isManagerOptOut) || !isOnlyWhenNoConsentToManager) {
                waitPromises.push(putHtmlCodeToDom(codeOptOut, codeDynamics));
            }

            if (deleteTechnicalDefinitionsAfterOptOut && !isEmbeddingOnlyExternalResources) {
                deleteCookiesLocally(technicalDefinitions, codeDynamics);

                // Mark deletable server-side services
                if (technicalDefinitions.some(({ type }) => type === "http")) {
                    deleteHttpCookies.push(id);
                }
            }

            const summary = { group, service };
            document.dispatchEvent(
                new CustomEvent<OptOutEvent>(OPT_OUT_EVENT, {
                    detail: summary,
                }),
            );

            allOptOutServices.push(summary);
        }
    });

    return { services: allOptOutServices, ready: Promise.all(waitPromises), deleteHttpCookies };
}

export { applyOptOut };
