// Drop-in copy of the playmez-embed package. Prefer the package: npm install playmez-embed
/**
 * Playmez game for React (Next.js, Vite, Remix, CRA). No script tag: it renders the iframe and
 * listens for the game's messages itself.
 *
 *   import { PlaymezGame } from "./PlaymezGame";
 *   <PlaymezGame launchUrl={launchUrl} height={640} onEvent={(e) => ...} onClose={() => setOpen(false)} />
 *
 * `launchUrl` comes from YOUR server, which calls POST /partner/launch with the API key.
 */
import { useEffect, useRef, type CSSProperties } from "react";

/** Every message the game posts to the page or app that hosts it. */
export type PlaymezEvent =
  | { source: "spinline"; type: "ready"; game: string }
  | { source: "spinline"; type: "result"; game: string; won: boolean; net: number }
  | { source: "spinline"; type: "close" }
  | { source: "spinline"; type: "error"; code: string; message: string }
  | { source: "spinline"; type: "resize"; height: number };

/** True for a message object shaped like a Playmez event. Does not check the sender; `mount` does that. */
export function isPlaymezEvent(data: unknown): data is PlaymezEvent {
  if (!data || typeof data !== "object") return false;
  const d = data as { source?: unknown; type?: unknown };
  return d.source === "spinline" && typeof d.type === "string";
}

export interface PlaymezGameProps {
  launchUrl: string;
  /** Pixels or any CSS height such as "100%". Default 640. */
  height?: number | string;
  title?: string;
  className?: string;
  style?: CSSProperties;
  onEvent?: (event: PlaymezEvent) => void;
  /** The player tapped Leave or Close: hide or unmount this component. */
  onClose?: () => void;
}

export function PlaymezGame({ launchUrl, height = 640, title = "Game", className, style, onEvent, onClose }: PlaymezGameProps) {
  const frameRef = useRef<HTMLIFrameElement>(null);
  const handlers = useRef({ onEvent, onClose });

  useEffect(() => {
    handlers.current = { onEvent, onClose };
  }, [onEvent, onClose]);

  useEffect(() => {
    const origin = new URL(launchUrl, window.location.href).origin;
    const onMessage = (event: MessageEvent) => {
      if (event.origin !== origin || event.source !== frameRef.current?.contentWindow) return;
      const data: unknown = event.data;
      if (!isPlaymezEvent(data)) return;
      handlers.current.onEvent?.(data);
      if (data.type === "close") handlers.current.onClose?.();
    };
    window.addEventListener("message", onMessage);
    return () => window.removeEventListener("message", onMessage);
  }, [launchUrl]);

  return (
    <iframe
      ref={frameRef}
      src={launchUrl}
      title={title}
      allow="autoplay; fullscreen; microphone; clipboard-write"
      allowFullScreen
      referrerPolicy="strict-origin-when-cross-origin"
      className={className}
      style={{
        display: "block",
        width: "100%",
        height: typeof height === "number" ? `${height}px` : height,
        border: 0,
        background: "#0b0f1a",
        borderRadius: 16,
        ...style,
      }}
    />
  );
}
