import { useEffect, useState } from "react";
import {
  buildWorldshaperStudioUrl,
  openWorldshaperStudioWindow,
} from "./worldshaperStudio/windowing";

type WorldDefaultPayload = {
  worldId?: string;
  world?: {
    id?: string;
  };
};

type LaunchState = "resolving" | "opening" | "opened" | "blocked" | "error";

const DEFAULT_EDITOR_WORLD_ID_FALLBACK = "overworld";

let didAttemptInitialLaunch = false;
let rememberedLaunchState: LaunchState | "" = "";
let rememberedStatus = "";
let rememberedError = "";
let rememberedWorldId = "";

async function resolveDefaultWorldId(): Promise<string> {
  const response = await fetch("/api/world-default");
  if (!response.ok) {
    throw new Error(`Failed to load default world (${response.status}).`);
  }
  const payload = await response.json() as WorldDefaultPayload;
  const resolvedWorldId = String(payload.worldId || payload.world?.id || "").trim();
  return resolvedWorldId || DEFAULT_EDITOR_WORLD_ID_FALLBACK;
}

function openStudioPopup(worldId: string): boolean {
  const popup = openWorldshaperStudioWindow(worldId, window, { worldId });
  return Boolean(popup);
}

function openStudioInCurrentTab(worldId: string): void {
  window.location.assign(buildWorldshaperStudioUrl(worldId, window, { worldId }));
}

function WorldshaperLauncher() {
  const [launchState, setLaunchState] = useState<LaunchState>("resolving");
  const [status, setStatus] = useState("Preparing Worldshaper Studio...");
  const [error, setError] = useState("");
  const [worldId, setWorldId] = useState("");

  useEffect(() => {
    let cancelled = false;

    async function attemptInitialLaunch() {
      if (didAttemptInitialLaunch) {
        setWorldId(rememberedWorldId);
        setLaunchState(rememberedLaunchState || "blocked");
        setStatus(rememberedStatus || "Open Worldshaper Studio.");
        setError(rememberedError);
        return;
      }

      didAttemptInitialLaunch = true;
      setLaunchState("resolving");
      setError("");
      setStatus("Preparing Worldshaper Studio...");

      try {
        const resolvedWorldId = await resolveDefaultWorldId().catch(() => DEFAULT_EDITOR_WORLD_ID_FALLBACK);
        if (cancelled) {
          return;
        }
        setWorldId(resolvedWorldId);
        rememberedWorldId = resolvedWorldId;
        setLaunchState("opening");
        setStatus(`Opening Worldshaper Studio for ${resolvedWorldId}...`);
        if (openStudioPopup(resolvedWorldId)) {
          setLaunchState("opened");
          setStatus("Worldshaper Studio opened in a separate window.");
          rememberedLaunchState = "opened";
          rememberedStatus = "Worldshaper Studio opened in a separate window.";
          rememberedError = "";
          return;
        }
        setLaunchState("blocked");
        setStatus("Your browser blocked the studio window.");
        rememberedLaunchState = "blocked";
        rememberedStatus = "Your browser blocked the studio window.";
        rememberedError = "";
      } catch (nextError: unknown) {
        if (cancelled) {
          return;
        }
        const nextErrorText = String(nextError || "Failed to prepare Worldshaper Studio.");
        setLaunchState("error");
        setError(nextErrorText);
        setStatus("Worldshaper Studio unavailable.");
        rememberedLaunchState = "error";
        rememberedStatus = "Worldshaper Studio unavailable.";
        rememberedError = nextErrorText;
      }
    }

    void attemptInitialLaunch();

    return () => {
      cancelled = true;
    };
  }, []);

  useEffect(() => {
    if (launchState !== "blocked" || !worldId) {
      return;
    }

    function retryLaunch() {
      if (!worldId) {
        return;
      }
      setLaunchState("opening");
      setStatus(`Opening Worldshaper Studio for ${worldId}...`);
      if (openStudioPopup(worldId)) {
        setLaunchState("opened");
        setStatus("Worldshaper Studio opened in a separate window.");
        rememberedLaunchState = "opened";
        rememberedStatus = "Worldshaper Studio opened in a separate window.";
        rememberedError = "";
        return;
      }
      setLaunchState("blocked");
      setStatus("Your browser blocked the studio window.");
      rememberedLaunchState = "blocked";
      rememberedStatus = "Your browser blocked the studio window.";
      rememberedError = "";
    }

    function handlePointerDown() {
      retryLaunch();
    }

    function handleKeyDown() {
      retryLaunch();
    }

    window.addEventListener("pointerdown", handlePointerDown, { once: true });
    window.addEventListener("keydown", handleKeyDown, { once: true });
    return () => {
      window.removeEventListener("pointerdown", handlePointerDown);
      window.removeEventListener("keydown", handleKeyDown);
    };
  }, [launchState, worldId]);

  async function handleRetry(): Promise<void> {
    setError("");
    setLaunchState("resolving");
    setStatus("Preparing Worldshaper Studio...");
    try {
      const resolvedWorldId = worldId || await resolveDefaultWorldId().catch(() => DEFAULT_EDITOR_WORLD_ID_FALLBACK);
      setWorldId(resolvedWorldId);
      rememberedWorldId = resolvedWorldId;
      setLaunchState("opening");
      setStatus(`Opening Worldshaper Studio for ${resolvedWorldId}...`);
      if (openStudioPopup(resolvedWorldId)) {
        setLaunchState("opened");
        setStatus("Worldshaper Studio opened in a separate window.");
        rememberedLaunchState = "opened";
        rememberedStatus = "Worldshaper Studio opened in a separate window.";
        rememberedError = "";
        return;
      }
      setLaunchState("blocked");
      setStatus("Your browser blocked the studio window.");
      rememberedLaunchState = "blocked";
      rememberedStatus = "Your browser blocked the studio window.";
      rememberedError = "";
    } catch (nextError: unknown) {
      const nextErrorText = String(nextError || "Failed to prepare Worldshaper Studio.");
      setLaunchState("error");
      setError(nextErrorText);
      setStatus("Worldshaper Studio unavailable.");
      rememberedLaunchState = "error";
      rememberedStatus = "Worldshaper Studio unavailable.";
      rememberedError = nextErrorText;
    }
  }

  function handleOpenHere(): void {
    const nextWorldId = worldId || DEFAULT_EDITOR_WORLD_ID_FALLBACK;
    openStudioInCurrentTab(nextWorldId);
  }

  const isBusy = launchState === "resolving" || launchState === "opening";
  const showFallbackActions = launchState === "blocked" || launchState === "opened" || launchState === "error";

  return (
    <main className="launcher-shell">
      <section className="launcher-card">
        <p className="launcher-eyebrow">New RPG</p>
        <h1 className="launcher-title">Worldshaper Studio</h1>
        <p className="launcher-status">{status}</p>
        {launchState === "blocked" ? (
          <p className="launcher-hint">
            Click anywhere or use the button below if your browser asks for permission to open the studio window.
          </p>
        ) : null}
        {launchState === "opened" ? (
          <p className="launcher-hint">
            The editor is running in its own window. You can leave this tab open as a quick relaunch point, or close it.
          </p>
        ) : null}
        {error ? <p className="launcher-error">{error}</p> : null}
        {showFallbackActions ? (
          <div className="launcher-actions">
            <button type="button" className="launcher-primary-btn" onClick={() => void handleRetry()} disabled={isBusy}>
              Open Floating Studio
            </button>
            <button type="button" className="launcher-secondary-btn" onClick={handleOpenHere} disabled={isBusy}>
              Open In This Tab
            </button>
          </div>
        ) : null}
      </section>
    </main>
  );
}

export default WorldshaperLauncher;
