"use client";

import { lotteryHttp, unwrapData } from "@/lib/lottery-http";

type RuntimeOriginsResponse = {
  iframe_allowed_origins: string[];
};

/** 后台白名单缓存 TTL，与 LotterySettings 默认 60s 同量级 */
const RUNTIME_ORIGINS_TTL_MS = 60_000;

let runtimeOrigins: string[] | null = null;
let runtimeFetchedAt = 0;
let pendingOrigins: Promise<string[]> | null = null;

function normalizeOrigin(value: string | undefined): string | null {
  const trimmed = value?.trim();
  if (!trimmed) return null;

  try {
    return new URL(trimmed).origin;
  } catch {
    return null;
  }
}

function staticAllowedOrigins(): string[] {
  const fromEnv = [
    process.env.NEXT_PUBLIC_MAIN_SITE_URL,
    process.env.NEXT_PUBLIC_PARENT_ORIGIN,
  ]
    .map(normalizeOrigin)
    .filter((origin): origin is string => origin !== null);

  if (process.env.NODE_ENV === "development") {
    return uniqueOrigins([
      ...fromEnv,
      "http://localhost:3800",
      "http://127.0.0.1:3800",
    ]);
  }

  return uniqueOrigins(fromEnv);
}

function uniqueOrigins(origins: string[]): string[] {
  return Array.from(new Set(origins));
}

export function getKnownIframeAllowedOrigins(): string[] {
  return uniqueOrigins([
    ...staticAllowedOrigins(),
    ...(runtimeOrigins ?? []),
  ]);
}

function isRuntimeCacheFresh(): boolean {
  return (
    runtimeOrigins !== null &&
    Date.now() - runtimeFetchedAt < RUNTIME_ORIGINS_TTL_MS
  );
}

export function invalidateIframeAllowedOrigins(): void {
  runtimeOrigins = null;
  runtimeFetchedAt = 0;
  pendingOrigins = null;
}

export async function loadIframeAllowedOrigins(
  force = false,
): Promise<string[]> {
  if (!force && isRuntimeCacheFresh()) {
    return getKnownIframeAllowedOrigins();
  }

  pendingOrigins ??= lotteryHttp
    .get("/integration/runtime-origins", { skipGlobalServerError: true })
    .then((response) => {
      const data = unwrapData<RuntimeOriginsResponse>(response.data);
      runtimeOrigins = data.iframe_allowed_origins
        .map(normalizeOrigin)
        .filter((origin): origin is string => origin !== null);
      runtimeFetchedAt = Date.now();

      return getKnownIframeAllowedOrigins();
    })
    .catch((error: unknown) => {
      pendingOrigins = null;
      console.warn("[IframeOrigins] Failed to load runtime origins:", error);
      return getKnownIframeAllowedOrigins();
    })
    .finally(() => {
      pendingOrigins = null;
    });

  return pendingOrigins;
}

/**
 * 未配置任何来源时默认拒绝（不再放行全部 origin）。
 * 开发环境仍可使用 env / localhost 静态来源。
 */
export function isIframeOriginAllowed(origin: string): boolean {
  const normalized = normalizeOrigin(origin);
  if (normalized === null) return false;

  const allowedOrigins = getKnownIframeAllowedOrigins();
  if (allowedOrigins.length === 0) return false;

  return allowedOrigins.includes(normalized);
}

/** postMessage 目标：优先 referrer 对应白名单，否则取首个白名单 origin；无白名单时拒绝发送 */
export function resolvePostMessageTargetOrigin(): string | null {
  const allowedOrigins = getKnownIframeAllowedOrigins();
  if (allowedOrigins.length === 0) {
    return null;
  }

  if (typeof document !== "undefined" && document.referrer) {
    try {
      const referrerOrigin = new URL(document.referrer).origin;
      if (allowedOrigins.includes(referrerOrigin)) {
        return referrerOrigin;
      }
    } catch {
      // ignore invalid referrer
    }
  }

  return allowedOrigins[0];
}
