export type PopupBounds = {
  left: number;
  top: number;
  width: number;
  height: number;
};

export const WORLDSHAPER_STUDIO_WINDOW_NAME = "worldshaper-studio";
export const WORLDSHAPER_STUDIO_BOUNDS_STORAGE_KEY = "worldshaper:studio-window-bounds";
export const WORLDSHAPER_HEIGHT_VIEWER_WINDOW_NAME = "worldshaper-height-viewer";
export const WORLDSHAPER_HEIGHT_VIEWER_BOUNDS_STORAGE_KEY = "worldshaper:height-viewer-window-bounds";

export function buildWorldshaperStudioUrl(mapId: string, hostWindow: Window = window, options?: { worldId?: string }): string {
  const popupUrl = new URL(`${import.meta.env.BASE_URL}worldshaper-studio.html`, hostWindow.location.origin);
  const normalizedMapId = String(mapId || "").trim();
  const normalizedWorldId = String(options?.worldId || "").trim();
  if (normalizedMapId) {
    popupUrl.searchParams.set("mapId", normalizedMapId);
  }
  if (normalizedWorldId) {
    popupUrl.searchParams.set("worldId", normalizedWorldId);
  }
  return popupUrl.toString();
}

export function buildWorldshaperHeightViewerUrl(mapId: string, token = "", hostWindow: Window = window): string {
  const popupUrl = new URL(`${import.meta.env.BASE_URL}worldshaper-height-viewer.html`, hostWindow.location.origin);
  const normalizedMapId = String(mapId || "").trim();
  const normalizedToken = String(token || "").trim();
  if (normalizedMapId) {
    popupUrl.searchParams.set("mapId", normalizedMapId);
  }
  if (normalizedToken) {
    popupUrl.searchParams.set("token", normalizedToken);
  }
  return popupUrl.toString();
}

export function getCenteredWorldshaperStudioBounds(hostWindow: Window = window): PopupBounds {
  const width = 1360;
  const height = 900;
  const hostScreenX = Number.isFinite(hostWindow.screenX) ? hostWindow.screenX : 0;
  const hostScreenY = Number.isFinite(hostWindow.screenY) ? hostWindow.screenY : 0;
  const hostOuterWidth = Number.isFinite(hostWindow.outerWidth) && hostWindow.outerWidth > 0
    ? hostWindow.outerWidth
    : hostWindow.innerWidth;
  const hostOuterHeight = Number.isFinite(hostWindow.outerHeight) && hostWindow.outerHeight > 0
    ? hostWindow.outerHeight
    : hostWindow.innerHeight;
  const left = Math.max(0, Math.round(hostScreenX + (hostOuterWidth - width) / 2));
  const top = Math.max(0, Math.round(hostScreenY + (hostOuterHeight - height) / 2));
  return { left, top, width, height };
}

export function getCenteredWorldshaperHeightViewerBounds(hostWindow: Window = window): PopupBounds {
  const width = 1280;
  const height = 820;
  const hostScreenX = Number.isFinite(hostWindow.screenX) ? hostWindow.screenX : 0;
  const hostScreenY = Number.isFinite(hostWindow.screenY) ? hostWindow.screenY : 0;
  const hostOuterWidth = Number.isFinite(hostWindow.outerWidth) && hostWindow.outerWidth > 0
    ? hostWindow.outerWidth
    : hostWindow.innerWidth;
  const hostOuterHeight = Number.isFinite(hostWindow.outerHeight) && hostWindow.outerHeight > 0
    ? hostWindow.outerHeight
    : hostWindow.innerHeight;
  const left = Math.max(0, Math.round(hostScreenX + (hostOuterWidth - width) / 2));
  const top = Math.max(0, Math.round(hostScreenY + (hostOuterHeight - height) / 2));
  return { left, top, width, height };
}

export function readWorldshaperStudioBounds(hostWindow: Window = window): PopupBounds {
  try {
    const raw = hostWindow.localStorage.getItem(WORLDSHAPER_STUDIO_BOUNDS_STORAGE_KEY);
    if (!raw) {
      return getCenteredWorldshaperStudioBounds(hostWindow);
    }
    const parsed = JSON.parse(raw) as Partial<PopupBounds>;
    const width = Math.max(640, Number(parsed.width) || 0);
    const height = Math.max(480, Number(parsed.height) || 0);
    const left = Math.max(0, Number(parsed.left) || 0);
    const top = Math.max(0, Number(parsed.top) || 0);
    if (!Number.isFinite(width) || !Number.isFinite(height) || !Number.isFinite(left) || !Number.isFinite(top)) {
      return getCenteredWorldshaperStudioBounds(hostWindow);
    }
    return { left, top, width, height };
  } catch {
    return getCenteredWorldshaperStudioBounds(hostWindow);
  }
}

export function readWorldshaperHeightViewerBounds(hostWindow: Window = window): PopupBounds {
  try {
    const raw = hostWindow.localStorage.getItem(WORLDSHAPER_HEIGHT_VIEWER_BOUNDS_STORAGE_KEY);
    if (!raw) {
      return getCenteredWorldshaperHeightViewerBounds(hostWindow);
    }
    const parsed = JSON.parse(raw) as Partial<PopupBounds>;
    const width = Math.max(640, Number(parsed.width) || 0);
    const height = Math.max(480, Number(parsed.height) || 0);
    const left = Math.max(0, Number(parsed.left) || 0);
    const top = Math.max(0, Number(parsed.top) || 0);
    if (!Number.isFinite(width) || !Number.isFinite(height) || !Number.isFinite(left) || !Number.isFinite(top)) {
      return getCenteredWorldshaperHeightViewerBounds(hostWindow);
    }
    return { left, top, width, height };
  } catch {
    return getCenteredWorldshaperHeightViewerBounds(hostWindow);
  }
}

export function persistWorldshaperStudioBounds(sourceWindow: Window = window): void {
  if (sourceWindow.closed) {
    return;
  }
  try {
    const width = Math.max(640, Math.round(Number(sourceWindow.outerWidth) || 0));
    const height = Math.max(480, Math.round(Number(sourceWindow.outerHeight) || 0));
    const left = Math.max(0, Math.round(Number(sourceWindow.screenX) || 0));
    const top = Math.max(0, Math.round(Number(sourceWindow.screenY) || 0));
    sourceWindow.localStorage.setItem(
      WORLDSHAPER_STUDIO_BOUNDS_STORAGE_KEY,
      JSON.stringify({ left, top, width, height }),
    );
  } catch {
    // Ignore storage and same-origin failures.
  }
}

export function persistWorldshaperHeightViewerBounds(sourceWindow: Window = window): void {
  if (sourceWindow.closed) {
    return;
  }
  try {
    const width = Math.max(640, Math.round(Number(sourceWindow.outerWidth) || 0));
    const height = Math.max(480, Math.round(Number(sourceWindow.outerHeight) || 0));
    const left = Math.max(0, Math.round(Number(sourceWindow.screenX) || 0));
    const top = Math.max(0, Math.round(Number(sourceWindow.screenY) || 0));
    sourceWindow.localStorage.setItem(
      WORLDSHAPER_HEIGHT_VIEWER_BOUNDS_STORAGE_KEY,
      JSON.stringify({ left, top, width, height }),
    );
  } catch {
    // Ignore storage and same-origin failures.
  }
}

export function openWorldshaperStudioWindow(
  mapId: string,
  hostWindow: Window = window,
  options?: { worldId?: string },
): Window | null {
  const popupUrl = buildWorldshaperStudioUrl(mapId, hostWindow, options);
  const initialBounds = readWorldshaperStudioBounds(hostWindow);
  const popupFeatures = [
    "popup=yes",
    "resizable=yes",
    "scrollbars=no",
    "width=" + initialBounds.width,
    "height=" + initialBounds.height,
    "left=" + initialBounds.left,
    "top=" + initialBounds.top,
  ].join(",");

  const popup = hostWindow.open(popupUrl, WORLDSHAPER_STUDIO_WINDOW_NAME, popupFeatures);
  if (!popup) {
    return null;
  }

  try {
    popup.moveTo(initialBounds.left, initialBounds.top);
    popup.resizeTo(initialBounds.width, initialBounds.height);
  } catch {
    // Ignore browser restrictions.
  }

  popup.location.href = popupUrl;
  popup.focus();
  return popup;
}

export function openWorldshaperHeightViewerWindow(mapId: string, token = "", hostWindow: Window = window): Window | null {
  const popupUrl = buildWorldshaperHeightViewerUrl(mapId, token, hostWindow);
  const initialBounds = readWorldshaperHeightViewerBounds(hostWindow);
  const popupFeatures = [
    "popup=yes",
    "resizable=yes",
    "scrollbars=no",
    "width=" + initialBounds.width,
    "height=" + initialBounds.height,
    "left=" + initialBounds.left,
    "top=" + initialBounds.top,
  ].join(",");

  const popup = hostWindow.open(popupUrl, WORLDSHAPER_HEIGHT_VIEWER_WINDOW_NAME, popupFeatures);
  if (!popup) {
    return null;
  }

  try {
    popup.moveTo(initialBounds.left, initialBounds.top);
    popup.resizeTo(initialBounds.width, initialBounds.height);
  } catch {
    // Ignore browser restrictions.
  }

  popup.location.href = popupUrl;
  popup.focus();
  return popup;
}

