import { PluginBridge } from "@nikolasp98/plugin-ui-bridge";
import { attachBridge } from "./rpc";

// Order of preference for discovering the host's window origin:
//   1. URL hash hint set by the host iframe (`#hostOrigin=https://...`) —
//      authoritative when the host opts in.
//   2. document.referrer — works under default Referrer-Policy.
//   3. "*" wildcard — last resort when both are unavailable (strict
//      Referrer-Policy on a cross-origin iframe strips the referrer). The
//      bridge treats "*" as "accept any origin"; if you need strict origin
//      pinning, ship the hash hint.
const EXPECTED_HOST_ORIGIN = (() => {
  try {
    const hash = new URLSearchParams(window.location.hash.replace(/^#/, ""));
    const fromHash = hash.get("hostOrigin");
    if (fromHash) return new URL(fromHash).origin;
  } catch {
    /* fall through */
  }
  try {
    const ref = document.referrer ? new URL(document.referrer) : null;
    return ref?.origin ?? "*";
  } catch {
    return "*";
  }
})();

const bridge = new PluginBridge({
  self: window,
  parent: window.parent,
  expectedHostOrigin: EXPECTED_HOST_ORIGIN,
});
attachBridge(bridge);

export const bridgeState = $state<{
  theme: "light" | "dark";
  gatewayUrl: string;
  authToken: string;
  ready: boolean;
}>({
  theme: "light",
  gatewayUrl: "",
  authToken: "",
  ready: false,
});

function applyTokens(tokens: Record<string, string>): void {
  const root = document.documentElement;
  for (const [k, v] of Object.entries(tokens)) {
    if (!k.startsWith("--")) continue;
    // Re-namespace the hub's `--color-*` / `--theme-*` tokens under `--hub-*`
    // so Tailwind v4 @theme can read them without creating a CSS variable
    // self-reference cycle. See app.css for the lookup chain.
    root.style.setProperty(`--hub-${k.slice(2)}`, v);
  }
}

function applyTheme(theme: "light" | "dark"): void {
  const root = document.documentElement;
  root.classList.toggle("dark", theme === "dark");
  root.style.colorScheme = theme;
}

bridge.onHello((msg) => {
  bridgeState.theme = msg.theme;
  bridgeState.gatewayUrl = msg.gatewayUrl;
  bridgeState.authToken = msg.authToken;
  applyTheme(msg.theme);
  applyTokens(msg.tokens);
  bridgeState.ready = true;
});

bridge.onThemeChange((msg) => {
  bridgeState.theme = msg.theme;
  applyTheme(msg.theme);
  applyTokens(msg.tokens);
});

bridge.notifyReady();

export function notifyResize(height: number): void {
  bridge.notifyResize(height);
}
