import { normalizeCameraPreset } from '../shared/cameraPresetIds.js';

/**
 * Liest aus dem Scene-Erweiterungs-Registry, ob ein Layout 2D/Pseudo-Ortho unterstuetzt.
 * Add-on-Plugins koennen via `__CE_PD_SCENE_EXT__.layoutSupportsOrthographic(layout)`
 * Layouts ausschliessen (z. B. Arc, Surface — perspektivisch only).
 * Free's Default: alle eigenen Layouts duerfen 2D.
 */
export function layoutSupportsOrthographic(layout) {
  const ext = (typeof window !== 'undefined' && window.__CE_PD_SCENE_EXT__) || null;
  const fn = ext && ext.layoutSupportsOrthographic;
  if (typeof fn === 'function') {
    const r = fn(layout);
    if (typeof r === 'boolean') return r;
  }
  return true;
}

export function createState(opts) {
  const layout = opts.defaultLayout || 'straight';
  const isOrtho = opts.defaultProjection === '2d' && layoutSupportsOrthographic(layout);
  /* Konfigurierter Start-Zoom (userZoomFactorPersp-Semantik: kleiner = näher).
   * Dient als Initialwert UND als „Default-Zoom", auf den ein Layout-/Refit-Reset
   * zurückfällt. Der 2D/3D-Toggle setzt NICHT hierauf zurück (merkt sich den Zoom). */
  const defaultZoom = (() => {
    const n = Number(opts.startZoom);
    if (!Number.isFinite(n) || n <= 0) return 1;
    return Math.max(0.5, Math.min(2, n));
  })();
  return {
    layout,
    isOrthographic: isOrtho,
    cameraPreset: normalizeCameraPreset(opts.cameraPreset),
    defaultZoom,
    hovered: null,
    /** Per-Session via Legenden-Klick versteckte DATA-Indizes. Wird beim
     *  Re-Init zur\u00fcckgesetzt (createState l\u00e4uft pro initScene neu). */
    hiddenDataIndices: new Set(),
    /** Während Pointer auf dem Diagramm gedrückt (Touch-Drag, Maus-Orbit, Stift): kein Hover-Tooltip bis Loslassen. */
    diagramHoldSuppressesTooltip: false,
    mouseOverContainer: false,
    isInteracting: false,
    userHasOrbited: false,
    blockVisible: true,
    /** Letzter IntersectionObserver-ratio (0–1); für Off-Screen-Priorität bei globalem Scene-Budget. */
    intersectionRatio: 0,
    /** IO `isIntersecting` — bei ratio 0 noch true möglich (verzögertes Update); für Tap-Pill / Wake-Gate. */
    intersectionIsIntersecting: false,
    contextLost: false,
    disposed: false,
    hibernated: false,
    hibernateTimer: null,
    wakeTimer: null,
    /** Wenn gesetzt: Wake wartet auf globalen Scroll-Unfreeze (kein eigenes setInterval pro Chart). */
    wakeScrollUnfreezeCb: null,
    deepDisposeTimer: null,
    wasFullscreen: false,
    width: 0,
    height: 0,

    stageAspectMin: null,
    lastStageMinHeight: null,

    animId: null,
    /** Advances only while the diagram is visible in animate(); used by wave trim timing. */
    sceneClockMs: 0,
    cameraCenterTarget: { position: null, lookAt: null },
    /** Perspective: auto-fit distance (padding); user zoom is separate factor. */
    layoutDistancePersp: 1,
    layoutDistanceRefPersp: 1,
    userZoomFactorPersp: defaultZoom,
    lastTimestamp: 0,
  };
}
