import React, { useEffect, useMemo, useState } from "react";
import { createRoot } from "react-dom/client";
import { Player } from "@remotion/player";
import { FlexStory, calcFlexStoryMetadata, flexStoryDefaults } from "../src/compositions/FlexStory";

/**
 * Standalone, isolated client-side player (Approach A). Runs as its own React-19 app
 * so the React-Three-Fiber v9 templates render in the browser without touching the
 * React-18 Next host. The studio embeds this via an <iframe> and feeds it the
 * project's scene data (URL hash for the first paint, postMessage for live edits).
 *
 * Free tier shows a watermark overlay here (preview only). The clean, no-watermark
 * EXPORT is issued server-side — never trust the client to drop the watermark.
 */
const FPS = 30;
const ASPECTS: Record<string, [number, number]> = {
  "16:9": [1920, 1080],
  "1:1": [1080, 1080],
  "9:16": [1080, 1920],
};

interface PlayerInput {
  props?: typeof flexStoryDefaults;
  aspect?: keyof typeof ASPECTS;
  watermark?: boolean;
}

function decodeHash(): PlayerInput | null {
  try {
    const h = window.location.hash.replace(/^#/, "");
    if (!h) return null;
    return JSON.parse(decodeURIComponent(escape(window.atob(h))));
  } catch {
    return null;
  }
}

const Watermark: React.FC = () => (
  <div
    style={{
      position: "absolute",
      inset: 0,
      pointerEvents: "none",
      display: "flex",
      flexWrap: "wrap",
      alignContent: "center",
      justifyContent: "center",
      gap: "12vmin",
      transform: "rotate(-24deg) scale(1.4)",
      opacity: 0.16,
      mixBlendMode: "overlay",
    }}
  >
    {Array.from({ length: 24 }).map((_, i) => (
      <span key={i} style={{ color: "#fff", fontWeight: 800, fontSize: "5vmin", letterSpacing: 2, whiteSpace: "nowrap", fontFamily: "system-ui, sans-serif" }}>
        FlatRender • نسخهٔ پیش‌نمایش
      </span>
    ))}
  </div>
);

const App: React.FC = () => {
  const [input, setInput] = useState<PlayerInput | null>(() => decodeHash());

  useEffect(() => {
    const onMsg = (e: MessageEvent) => {
      if (e.data && e.data.type === "flatrender:props" && e.data.payload) {
        setInput(e.data.payload as PlayerInput);
      }
    };
    window.addEventListener("message", onMsg);
    // Announce readiness so the studio can push the current props.
    try {
      window.parent?.postMessage({ type: "flatrender:ready" }, "*");
    } catch {
      /* not embedded */
    }
    return () => window.removeEventListener("message", onMsg);
  }, []);

  const props = input?.props ?? flexStoryDefaults;
  const aspect = (input?.aspect ?? "9:16") as keyof typeof ASPECTS;
  const [w, h] = ASPECTS[aspect] ?? ASPECTS["9:16"];
  const watermark = input?.watermark ?? true;

  const durationInFrames = useMemo(() => {
    try {
      return Math.max(1, calcFlexStoryMetadata({ props }).durationInFrames);
    } catch {
      return FPS * 10;
    }
  }, [props]);

  return (
    <div style={{ position: "fixed", inset: 0, background: "#000", display: "flex", alignItems: "center", justifyContent: "center" }}>
      <div style={{ position: "relative", width: "100%", height: "100%" }}>
        <Player
          component={FlexStory}
          inputProps={props}
          durationInFrames={durationInFrames}
          fps={FPS}
          compositionWidth={w}
          compositionHeight={h}
          style={{ width: "100%", height: "100%" }}
          controls
          loop
          acknowledgeRemotionLicense
        />
        {watermark && <Watermark />}
      </div>
    </div>
  );
};

createRoot(document.getElementById("root")!).render(<App />);
