import Echo from "laravel-echo";
import Pusher from "pusher-js";

/** 需在浏览器挂载 Pusher（Reverb 走 pusher-js 协议） */
function ensurePusherOnWindow(): void {
  if (typeof window === "undefined") return;
  (
    window as unknown as {
      Pusher: typeof Pusher;
    }
  ).Pusher = Pusher;
}

let echoSingleton: Echo<"reverb"> | null = null;
let loggedRemoteReverbSkip = false;

function isLocalDevHostname(hostname: string): boolean {
  return (
    hostname === "localhost"
    || hostname === "127.0.0.1"
    || hostname.endsWith(".local")
  );
}

function isLocalReverbHost(host: string): boolean {
  const h = host.trim().toLowerCase();
  return h === "localhost" || h === "127.0.0.1" || h.startsWith("127.");
}

/**
 * 本地 Next + 本地 Laravel，但 Reverb 指向线上时，WS 会把「线上期号」盖到界面上，
 * 下注仍走本地 API → 期号在库中不存在（业务码 2006）。代理账号常走 /login 久留大厅，更易踩中。
 */
function shouldSkipReverbForLocalApiMismatch(): boolean {
  if (typeof window === "undefined") {
    return false;
  }
  if (!isLocalDevHostname(window.location.hostname)) {
    return false;
  }
  const reverbHost = process.env.NEXT_PUBLIC_REVERB_HOST?.trim() ?? "";
  if (reverbHost === "" || isLocalReverbHost(reverbHost)) {
    return false;
  }
  if (!loggedRemoteReverbSkip) {
    loggedRemoteReverbSkip = true;
    console.warn(
      "[lottery-echo] 本地开发已跳过远程 Reverb：请把 NEXT_PUBLIC_REVERB_* 指到本机，"
        + "或设 NEXT_PUBLIC_REVERB_ENABLED=false，以免大厅期号与 LOTTERY_API_UPSTREAM 不一致。",
    );
  }
  return true;
}

/**
 * 是否配置了可用的 Reverb（用于区分「故意 HTTP 轮询」与「WS 断线降级」）。
 */
export function isLotteryReverbConfigured(): boolean {
  if (process.env.NEXT_PUBLIC_REVERB_ENABLED === "false") {
    return false;
  }
  const key = process.env.NEXT_PUBLIC_REVERB_APP_KEY?.trim() ?? "";
  const host = process.env.NEXT_PUBLIC_REVERB_HOST?.trim() ?? "";
  if (key === "" || host === "") {
    return false;
  }
  if (shouldSkipReverbForLocalApiMismatch()) {
    return false;
  }
  return true;
}

/**
 * NEXT_PUBLIC_REVERB_* 须与当前 Reverb 服务一致，并 `php artisan reverb:start`。
 * 未配置时默认不连接 Reverb（大厅会走轮询降级）。
 */
export function getLotteryEcho(): Echo<"reverb"> | null {
  if (typeof window === "undefined") return null;

  if (process.env.NEXT_PUBLIC_REVERB_ENABLED === "false") {
    return null;
  }

  if (shouldSkipReverbForLocalApiMismatch()) {
    return null;
  }

  const key = process.env.NEXT_PUBLIC_REVERB_APP_KEY;
  const host = process.env.NEXT_PUBLIC_REVERB_HOST;
  if (!key?.length || !host?.length) {
    return null;
  }

  if (!echoSingleton) {
    ensurePusherOnWindow();
    const port = Number(process.env.NEXT_PUBLIC_REVERB_PORT ?? 8080);
    const scheme = process.env.NEXT_PUBLIC_REVERB_SCHEME ?? "http";
    const forceTLS = scheme === "https";

    echoSingleton = new Echo({
      broadcaster: "reverb",
      key,
      wsHost: host,
      wsPort: port,
      wssPort: port,
      forceTLS,
      enabledTransports: forceTLS ? ["ws", "wss"] : ["ws"],
      disableStats: true,
    });
  }

  return echoSingleton;
}

export function disconnectLotteryEcho(): void {
  if (echoSingleton) {
    echoSingleton.disconnect();
    echoSingleton = null;
  }
}
