import {
    HTML_ATTRIBUTE_BLOCKER_CONNECTED,
    HTML_ATTRIBUTE_BLOCKER_CONNECTED_PRESERVED,
    HTML_ATTRIBUTE_BLOCKER_ID,
    HTML_ATTRIBUTE_BY,
    HTML_ATTRIBUTE_CONFIRM,
    HTML_ATTRIBUTE_COOKIE_IDS,
    HTML_ATTRIBUTE_THUMBNAIL,
    HTML_ATTRIBUTE_VISUAL_PARENT_HIDE,
    HTML_ATTRIBUTE_WAS_PREVIOUSLY_DISPLAY_STYLE,
    HTML_ATTRIBUTE_WAS_PREVIOUSLY_STRICT_HIDDEN,
} from "../dom/htmlAttributes.js";

import type { VisualThumbnail } from "./createVisual.js";
import type { findVisualParent } from "./findVisualParent.js";

/**
 * Memoize the "!important" state so we can correctly reset it in `probablyResetParentContainerForVisual`.
 */
function hideVisualContainerAndMemoizeDisplayState(node: HTMLElement) {
    const { style } = node;
    const previousDisplayStyle = style.getPropertyValue("display");

    // Only do this calculation once
    if (!node.hasAttribute(HTML_ATTRIBUTE_WAS_PREVIOUSLY_STRICT_HIDDEN)) {
        node.setAttribute(HTML_ATTRIBUTE_WAS_PREVIOUSLY_DISPLAY_STYLE, previousDisplayStyle);
        if (previousDisplayStyle === "none" && style.getPropertyPriority("display") === "important") {
            node.setAttribute(HTML_ATTRIBUTE_WAS_PREVIOUSLY_STRICT_HIDDEN, "1");
        } else {
            node.setAttribute(HTML_ATTRIBUTE_WAS_PREVIOUSLY_STRICT_HIDDEN, "0");
            style.setProperty("display", "none", "important");
        }
    }
}

/**
 * Create visual content blocker container for a given node.
 */
function createVisualContainer(
    node: HTMLElement,
    createBefore: HTMLElement,
    visualParentMode: ReturnType<typeof findVisualParent>[1],
    isVisualParentFound: ReturnType<typeof findVisualParent>[2],
) {
    const container = document.createElement("div");
    const isClickGateway = node.hasAttribute(HTML_ATTRIBUTE_CONFIRM);
    const { style } = container;
    const connectedCounter = node.getAttribute(HTML_ATTRIBUTE_BLOCKER_CONNECTED_PRESERVED);

    // Connect blocker with blocked node
    container.setAttribute(HTML_ATTRIBUTE_BLOCKER_CONNECTED, connectedCounter);
    container.className = "rcb-content-blocker";
    if (isClickGateway) {
        style.setProperty("display", "none");
    } else {
        style.setProperty("max-height", "initial");
        style.setProperty("pointer-events", "all");
        style.setProperty("flex-grow", "1");
        style.setProperty("position", "initial", "important");
        style.setProperty("opacity", "1");
        style.setProperty("line-height", "initial");

        // e.g. `<iframe width="640"` (Youtube-Embeds)
        const nodeWidth = node.getAttribute("width");
        if (nodeWidth && !isNaN(+nodeWidth) && node.clientWidth === +nodeWidth) {
            style.setProperty("width", `${nodeWidth}px`);
            style.setProperty("max-width", `100%`);
        }
    }
    node.setAttribute(HTML_ATTRIBUTE_BLOCKER_CONNECTED, connectedCounter);
    createBefore.parentNode.insertBefore(container, createBefore);

    // Copy consent attributes so they are found via `findBlockedNodes`, too
    [HTML_ATTRIBUTE_BY, HTML_ATTRIBUTE_BLOCKER_ID, HTML_ATTRIBUTE_COOKIE_IDS].forEach((a) => {
        if (node.hasAttribute(a)) {
            container.setAttribute(a, node.getAttribute(a));
        }
    });

    // Connect a children selector with the content blocker above
    if (visualParentMode === "childrenSelector") {
        createBefore.setAttribute(HTML_ATTRIBUTE_BLOCKER_CONNECTED, connectedCounter);

        if (!isVisualParentFound) {
            createBefore.classList.add("rcb-content-blocker-children-fallback");
        }
    }

    // Find configured visual thumbnail
    let thumbnail: VisualThumbnail;
    if (node.hasAttribute(HTML_ATTRIBUTE_THUMBNAIL)) {
        thumbnail = JSON.parse(node.getAttribute(HTML_ATTRIBUTE_THUMBNAIL));
    } else {
        const nestedThumbnailNode = node.querySelectorAll(`[${HTML_ATTRIBUTE_THUMBNAIL}`);
        if (nestedThumbnailNode.length > 0) {
            thumbnail = JSON.parse(nestedThumbnailNode[0].getAttribute(HTML_ATTRIBUTE_THUMBNAIL));
        }
    }

    // Hide our element and render content blocker
    if (!isClickGateway) {
        hideVisualContainerAndMemoizeDisplayState(
            visualParentMode === "childrenSelector" || node.hasAttribute(HTML_ATTRIBUTE_VISUAL_PARENT_HIDE)
                ? createBefore
                : node,
        );
    }

    return {
        container,
        thumbnail,
    };
}

export { createVisualContainer, hideVisualContainerAndMemoizeDisplayState };
