/**
 * Bridge theme CSS and decorative images into PAGE JavaScript context.
 */

import patchScript from "@/seqta/utils/themeImagePagePatch.js?script&iife";
import { extensionPageScriptUrl } from "@/lib/extensionPageScriptUrl";
import { blobToBase64Data } from "@/plugins/built-in/themes/themeImageUrl";

const PAGE_PATCH_LOADER_ID = "bsplus-theme-image-page-patch-loader";
const BRIDGE_ID = "bsplus-theme-image-bridge";
const PAYLOAD_ID = "bsplus-theme-image-payload";

export type ThemePageSyncInput = {
  images?: Array<{ variableName: string; blob: Blob }>;
  customCss?: string;
  previewCss?: string;
  clear?: boolean;
  clearPreview?: boolean;
};

export function installThemeImagePagePatch(): void {
  if (document.getElementById(PAGE_PATCH_LOADER_ID)) return;

  const script = document.createElement("script");
  script.id = PAGE_PATCH_LOADER_ID;
  script.src = extensionPageScriptUrl(patchScript);
  script.addEventListener("load", () => script.remove());
  (document.documentElement || document.head).appendChild(script);
}

function ensureBridgeElements(): void {
  if (!document.getElementById(PAYLOAD_ID)) {
    const payload = document.createElement("textarea");
    payload.id = PAYLOAD_ID;
    payload.hidden = true;
    payload.setAttribute("aria-hidden", "true");
    payload.tabIndex = -1;
    document.documentElement.appendChild(payload);
  }
  if (!document.getElementById(BRIDGE_ID)) {
    const bridge = document.createElement("div");
    bridge.id = BRIDGE_ID;
    bridge.hidden = true;
    bridge.setAttribute("aria-hidden", "true");
    document.documentElement.appendChild(bridge);
  }
}

function sendPayload(payload: Record<string, unknown>): void {
  installThemeImagePagePatch();
  ensureBridgeElements();
  const payloadEl = document.getElementById(PAYLOAD_ID) as HTMLTextAreaElement;
  payloadEl.value = JSON.stringify(payload);
  const bridge = document.getElementById(BRIDGE_ID)!;
  bridge.setAttribute("data-rev", String(Number(bridge.getAttribute("data-rev") || "0") + 1));
}

export async function syncThemeToPage(input: ThemePageSyncInput): Promise<void> {
  if (input.clear) {
    sendPayload({ clear: true });
    return;
  }

  const payload: Record<string, unknown> = {};
  if (input.clearPreview) payload.clearPreview = true;
  if (input.customCss !== undefined) payload.customCss = input.customCss;
  if (input.previewCss !== undefined) payload.previewCss = input.previewCss;
  if (input.images !== undefined) {
    payload.images = await Promise.all(
      input.images.map(async (image) => ({
        variableName: image.variableName,
        data: await blobToBase64Data(image.blob),
        mime: image.blob.type || "image/png",
      })),
    );
  }

  if (Object.keys(payload).length === 0) return;
  sendPayload(payload);
}

export function clearThemeInPage(): void {
  sendPayload({ clear: true });
}
