/*
 * Native Fullscreen-API für den Diagram-Wrapper:
 * Button-Toggle, UI-Sync (aria, Label, Hintergrund), Scroll-Position-Restore,
 * und Kamera-Refit-Skip während des Fullscreen-Transit (settleLayout-Callback).
 * Auf iOS Safari (iPhone) fehlt die API für Non-Video-Elemente → Button wird entfernt.
 */

import { i18nStr } from '../../shared/config.js';
import { bindNativeTitleDismissOnTouch } from './nativeTitleTouchDismiss.js';

export function isDiagramFullscreen(ownerDoc, wrapper) {
  const fs = ownerDoc.fullscreenElement || ownerDoc.webkitFullscreenElement || ownerDoc.mozFullScreenElement || ownerDoc.msFullscreenElement;
  return fs === wrapper;
}

/** iOS Safari (iPhone) liefert weder `fullscreenEnabled` noch `webkitFullscreenEnabled` — dort gibt es keine Fullscreen-API für Nicht-Video-Elemente. */
export function canUseNativeFullscreen(ownerDoc) {
  return !!(ownerDoc.fullscreenEnabled || ownerDoc.webkitFullscreenEnabled);
}

export function createFullscreen({
  wrapper,
  ownerDoc,
  state,
  ownCanvas,
  opts,
  backgroundTransparent,
  fullscreenTransparentBackdrop,
  isMobile,
  mountTooltipsForFullscreenState,
  settleLayout,
  wake,
  setFullscreenSkipCameraRefit,
}) {
  const i18nFsEnter = i18nStr(opts.i18nFullscreenEnter, 'Enter fullscreen');
  const i18nFsExit = i18nStr(opts.i18nFullscreenExit, 'Exit fullscreen');
  const fullscreenBtn = wrapper.querySelector('.ce-diagram-fullscreen-btn');

  function syncFullscreenUi() {
    const fs = isDiagramFullscreen(ownerDoc, wrapper);
    wrapper.classList.toggle('ce-diagram-wrapper--fullscreen', fs);
    /* Nach WP-Reflow (Theme/Spalten) oft erst verzögert stabile Breite/Höhe — Exit: Cache leeren, siehe onFullscreenChange. */
    if (!fs) state.lastStageMinHeight = null;
    if (backgroundTransparent) {
      if (fs) wrapper.style.backgroundColor = fullscreenTransparentBackdrop;
      else wrapper.style.backgroundColor = '';
    }
    if (fullscreenBtn) {
      fullscreenBtn.setAttribute('aria-pressed', fs ? 'true' : 'false');
      const label = fs ? i18nFsExit : i18nFsEnter;
      fullscreenBtn.setAttribute('aria-label', label);
      fullscreenBtn.title = label;
      const fsHint = fullscreenBtn.querySelector('.ce-diagram-expand-btn__label');
      if (fsHint) fsHint.textContent = label;
    }
    mountTooltipsForFullscreenState();
  }

  function requestDiagramFullscreen() {
    const req = wrapper.requestFullscreen || wrapper.webkitRequestFullscreen || wrapper.mozRequestFullScreen || wrapper.msRequestFullscreen;
    if (req) {
      const p = req.call(wrapper);
      if (p && typeof p.catch === 'function') p.catch(() => {});
    }
  }

  function exitDiagramFullscreen() {
    const ex = ownerDoc.exitFullscreen || ownerDoc.webkitExitFullscreen || ownerDoc.mozCancelFullScreen || ownerDoc.msExitFullscreen;
    if (ex) {
      const p = ex.call(ownerDoc);
      if (p && typeof p.catch === 'function') p.catch(() => {});
    }
  }

  let scrollYBeforeFullscreen = null;
  function restorePageScroll() {
    if (scrollYBeforeFullscreen == null) return;
    const y = scrollYBeforeFullscreen;
    scrollYBeforeFullscreen = null;
    if (!Number.isFinite(y)) return;
    const win = ownerDoc.defaultView;
    if (!win) return;
    if (fullscreenBtn) fullscreenBtn.blur();
    let tries = 0;
    (function attempt() {
      try { win.scrollTo({ left: 0, top: y, behavior: 'instant' }); } catch (_) {
        try { win.scrollTo(0, y); } catch (_) { /* ignore */ }
      }
      if (isMobile) {
        try { if (ownerDoc.documentElement) ownerDoc.documentElement.scrollTop = y; } catch (_) { /* ignore */ }
        try { if (ownerDoc.body) ownerDoc.body.scrollTop = y; } catch (_) { /* ignore */ }
      }
      if (++tries < 4) requestAnimationFrame(attempt);
    })();
  }

  function onFullscreenChange() {
    const fs = isDiagramFullscreen(ownerDoc, wrapper);
    if (fs) {
      state.wasFullscreen = true;
      syncFullscreenUi();
      ownCanvas.style.visibility = 'hidden';
      setFullscreenSkipCameraRefit(true);
      settleLayout(() => { setFullscreenSkipCameraRefit(false); ownCanvas.style.visibility = ''; });
    } else if (state.wasFullscreen) {
      state.wasFullscreen = false;
      syncFullscreenUi();
      ownCanvas.style.visibility = 'hidden';
      restorePageScroll();
      state.lastStageMinHeight = null;
      setFullscreenSkipCameraRefit(true);
      settleLayout(() => { setFullscreenSkipCameraRefit(false); ownCanvas.style.visibility = ''; });
    }
  }

  let onBtnClick = null;
  if (fullscreenBtn && !canUseNativeFullscreen(ownerDoc)) {
    /** iOS Safari iPhone: Fullscreen-API fehlt für Nicht-Video-Elemente → Button komplett entfernen. */
    if (fullscreenBtn.parentNode) fullscreenBtn.parentNode.removeChild(fullscreenBtn);
  } else if (fullscreenBtn) {
    onBtnClick = () => {
      if (isDiagramFullscreen(ownerDoc, wrapper)) {
        exitDiagramFullscreen();
      } else {
        if (state.hibernated) wake();
        const w = ownerDoc.defaultView;
        if (w) scrollYBeforeFullscreen = w.pageYOffset ?? w.scrollY ?? 0;
        requestDiagramFullscreen();
      }
    };
    fullscreenBtn.addEventListener('click', onBtnClick);
    bindNativeTitleDismissOnTouch(fullscreenBtn);
    ownerDoc.addEventListener('fullscreenchange', onFullscreenChange);
    ownerDoc.addEventListener('webkitfullscreenchange', onFullscreenChange);
    ownerDoc.addEventListener('mozfullscreenchange', onFullscreenChange);
    ownerDoc.addEventListener('MSFullscreenChange', onFullscreenChange);
  }

  return {
    fullscreenBtn,
    syncFullscreenUi,
    unbind() {
      if (fullscreenBtn) {
        if (onBtnClick) fullscreenBtn.removeEventListener('click', onBtnClick);
        ownerDoc.removeEventListener('fullscreenchange', onFullscreenChange);
        ownerDoc.removeEventListener('webkitfullscreenchange', onFullscreenChange);
        ownerDoc.removeEventListener('mozfullscreenchange', onFullscreenChange);
        ownerDoc.removeEventListener('MSFullscreenChange', onFullscreenChange);
      }
    },
  };
}
