import type { CSSProperties } from "react";
import { useEffect, useState } from "react";
import { openWorldshaperStudioWindow } from "./worldshaperStudio/windowing";
import {
  CHANGELOG_SECTIONS,
  CHANGELOG_SPLASH_FOOTNOTE,
  CHANGELOG_SPLASH_KICKER,
  CHANGELOG_SPLASH_TITLE,
  CHANGELOG_SPLASH_VERSION,
} from "./worldshaperStudio/changelogData";
import type { ChangelogItem } from "./worldshaperStudio/changelogData";
import launcherBackground from "../background.png";

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

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

const DEFAULT_EDITOR_WORLD_ID_FALLBACK = "overworld";

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 openRepo(): void {
  window.location.assign("https://repo.andraxion.net/");
}

function WorldshaperLauncher() {
  const [launchState, setLaunchState] = useState<LaunchState>("ready");
  const [status, setStatus] = useState("Launch Worldshaper Studio in its floating window.");
  const [error, setError] = useState("");
  const [worldId, setWorldId] = useState(DEFAULT_EDITOR_WORLD_ID_FALLBACK);

  useEffect(() => {
    let cancelled = false;
    void resolveDefaultWorldId()
      .then((resolvedWorldId) => {
        if (cancelled) {
          return;
        }
        setWorldId(resolvedWorldId);
      })
      .catch(() => {
        if (cancelled) {
          return;
        }
        setWorldId(DEFAULT_EDITOR_WORLD_ID_FALLBACK);
      });

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

  async function handleLaunch(): Promise<void> {
    setError("");
    const nextWorldId = worldId || DEFAULT_EDITOR_WORLD_ID_FALLBACK;
    setLaunchState("opening");
    setStatus(`Opening Worldshaper Studio for ${nextWorldId}...`);
    try {
      const resolvedWorldId = nextWorldId || await resolveDefaultWorldId().catch(() => DEFAULT_EDITOR_WORLD_ID_FALLBACK);
      setWorldId(resolvedWorldId);
      setStatus(`Opening Worldshaper Studio for ${resolvedWorldId}...`);
      if (openStudioPopup(resolvedWorldId)) {
        setLaunchState("opened");
        setStatus("Worldshaper Studio opened in a separate window.");
        return;
      }
      setLaunchState("blocked");
      setStatus("Your browser blocked the studio window. Use the launch button again after allowing popups.");
    } catch (nextError: unknown) {
      const nextErrorText = String(nextError || "Failed to prepare Worldshaper Studio.");
      setLaunchState("error");
      setError(nextErrorText);
      setStatus("Worldshaper Studio unavailable.");
    }
  }

  const isBusy = launchState === "opening";

  return (
    <main
      className="launcher-shell"
      style={{ "--launcher-background-image": `url(${launcherBackground})` } as CSSProperties}
    >
      <div className="launcher-stack">
        <section className="launcher-hero-window" aria-labelledby="launcher-studio-title">
          <div className="launcher-changelog-titlebar">
            <div className="launcher-changelog-title">Worldshaper Studio</div>
            <div className="launcher-changelog-hint">Floating editor launch</div>
          </div>
          <div className="launcher-hero-body">
            <div className="launcher-hero-card">
              <div className="changelog-splash-hero launcher-hero-banner">
                <p className="launcher-eyebrow">New RPG</p>
                <h1 className="launcher-title" id="launcher-studio-title">Worldshaper Studio</h1>
                <p className="launcher-status">{status}</p>
              </div>
              <div className="launcher-hero-support">
                {launchState === "blocked" ? (
                  <p className="launcher-hint">
                    Allow the popup, then use the studio button again to launch the floating editor window.
                  </p>
                ) : null}
                {launchState === "opened" ? (
                  <p className="launcher-hint">
                    The studio is open in its own slim window. This page stays behind as your release board and relaunch point.
                  </p>
                ) : null}
                {launchState === "ready" ? (
                  <p className="launcher-hint">
                    The editor is designed to live in its own floating window, so the launcher keeps the first step clean.
                  </p>
                ) : null}
                {error ? <p className="launcher-error">{error}</p> : null}
                <div className="launcher-actions">
                  <button type="button" className="launcher-primary-btn" onClick={() => void handleLaunch()} disabled={isBusy}>
                    Open Floating Studio
                  </button>
                  <button type="button" className="launcher-secondary-btn" onClick={openRepo} disabled={isBusy}>
                    Open Repo
                  </button>
                </div>
              </div>
            </div>
          </div>
        </section>
        <section className="launcher-changelog-window" aria-labelledby="launcher-whats-new-title">
          <div className="launcher-changelog-titlebar">
            <div className="launcher-changelog-title">What&apos;s New</div>
            <div className="launcher-changelog-hint">Current release highlights</div>
          </div>
          <div className="launcher-changelog-body">
            <div className="changelog-splash-card">
              <div className="changelog-splash-hero">
                <div className="changelog-splash-kicker">{CHANGELOG_SPLASH_KICKER}</div>
                <div className="changelog-splash-title" id="launcher-whats-new-title">{CHANGELOG_SPLASH_TITLE}</div>
                <div className="changelog-splash-meta">Release {CHANGELOG_SPLASH_VERSION}</div>
              </div>
              <div className="changelog-splash-list">
                {CHANGELOG_SECTIONS.map((section) => (
                  <section key={section.title} className="changelog-splash-section">
                    <h3 className="changelog-splash-section-title">{section.title}</h3>
                    <ul className="changelog-splash-bullets">
                      {section.items.map((item, index) => {
                        const key = `${section.title}-${index}`;
                        const normalizedItem: ChangelogItem = item;
                        if (typeof normalizedItem === "string") {
                          return <li key={key}>{normalizedItem}</li>;
                        }
                        return (
                          <li key={key}>
                            <div>{normalizedItem.text}</div>
                            {normalizedItem.note ? <div className="changelog-splash-bullet-note">{normalizedItem.note}</div> : null}
                          </li>
                        );
                      })}
                    </ul>
                  </section>
                ))}
              </div>
              <div className="changelog-splash-footer">
                <div className="changelog-splash-footnote">{CHANGELOG_SPLASH_FOOTNOTE}</div>
              </div>
            </div>
          </div>
        </section>
      </div>
    </main>
  );
}

export default WorldshaperLauncher;
