(function(){
  const THEME_KEY = 'force-monitor-theme';
  const FULLSCREEN_INTENT_KEY = 'force-monitor-fullscreen-intent';

  function byId(id){ return id ? document.getElementById(id) : null; }

  function getFullscreenIntent(){
    try { return sessionStorage.getItem(FULLSCREEN_INTENT_KEY) === '1'; } catch (_) { return false; }
  }

  function setFullscreenIntent(enabled){
    try { sessionStorage.setItem(FULLSCREEN_INTENT_KEY, enabled ? '1' : '0'); } catch (_) {}
  }

  function setTheme(theme, opts){
    opts = opts || {};
    const t = theme === 'light' ? 'light' : 'dark';
    document.body.setAttribute('data-theme', t);
    try { localStorage.setItem(THEME_KEY, t); } catch (_) {}
    const btn = byId(opts.buttonId || 'theme-toggle');
    if (btn) btn.textContent = t === 'light' ? 'Dark theme' : 'Light theme';
    if (typeof opts.onChange === 'function') opts.onChange(t);
    return t;
  }

  function initTheme(opts){
    opts = opts || {};
    let theme = 'dark';
    try {
      const stored = localStorage.getItem(THEME_KEY);
      if (stored === 'light' || stored === 'dark') theme = stored;
      else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) theme = 'light';
    } catch (_) {}
    setTheme(theme, opts);
    const btn = byId(opts.buttonId || 'theme-toggle');
    if (btn && !btn.dataset.themeBound) {
      btn.dataset.themeBound = '1';
      btn.addEventListener('click', function(){
        setTheme(document.body.getAttribute('data-theme') === 'light' ? 'dark' : 'light', opts);
      });
    }
    return theme;
  }

  function updateFullscreenButton(buttonId){
    const btn = byId(buttonId || 'fullscreen-toggle');
    if (!btn) return;
    if (document.fullscreenElement) {
      btn.textContent = 'Exit fullscreen';
      return;
    }
    btn.textContent = getFullscreenIntent() ? 'Restore fullscreen' : 'Enter fullscreen';
  }

  async function requestFullscreenSafe(){
    if (document.fullscreenElement) return true;
    if (!document.fullscreenEnabled) return false;
    try {
      await document.documentElement.requestFullscreen();
      setFullscreenIntent(true);
      return true;
    } catch (err) {
      console.warn('Fullscreen restore/request blocked:', err);
      return false;
    }
  }

  async function toggleFullscreen(buttonId){
    try {
      if (!document.fullscreenElement) {
        await requestFullscreenSafe();
      } else {
        setFullscreenIntent(false);
        await document.exitFullscreen();
      }
    } catch (err) {
      console.warn('Fullscreen error:', err);
    } finally {
      updateFullscreenButton(buttonId || 'fullscreen-toggle');
    }
  }

  function bindFullscreenNavPersistence(){
    if (document.documentElement.dataset.fsNavBound) return;
    document.documentElement.dataset.fsNavBound = '1';

    document.addEventListener('click', function(ev){
      const link = ev.target && ev.target.closest ? ev.target.closest('a[href]') : null;
      if (!link) return;
      const href = link.getAttribute('href') || '';
      const target = link.getAttribute('target') || '';
      if (!href || href.startsWith('#') || target === '_blank' || link.hasAttribute('download')) return;
      try {
        const url = new URL(link.href, window.location.href);
        if (url.origin !== window.location.origin) return;
      } catch (_) {
        return;
      }
      if (document.fullscreenElement || getFullscreenIntent()) {
        setFullscreenIntent(true);
      }
    }, true);

    window.addEventListener('pageshow', function(){
      document.querySelectorAll('#fullscreen-toggle, #fullscreen-btn').forEach(function(el){
        updateFullscreenButton(el.id);
      });
    });
  }

  async function initFullscreen(opts){
    opts = opts || {};
    const buttonId = opts.buttonId || 'fullscreen-toggle';
    const btn = byId(buttonId);
    if (btn && !btn.dataset.fsBound) {
      btn.dataset.fsBound = '1';
      btn.addEventListener('click', function(){ toggleFullscreen(buttonId); });
    }
    if (!document.documentElement.dataset.fsListenerBound) {
      document.documentElement.dataset.fsListenerBound = '1';
      document.addEventListener('fullscreenchange', function(){
        setFullscreenIntent(!!document.fullscreenElement);
        document.querySelectorAll('#fullscreen-toggle, #fullscreen-btn').forEach(function(el){
          updateFullscreenButton(el.id);
        });
      });
    }
    bindFullscreenNavPersistence();
    updateFullscreenButton(buttonId);

    if (getFullscreenIntent() && !document.fullscreenElement) {
      // Best effort only: some browsers require a fresh user gesture after navigation.
      requestAnimationFrame(function(){
        requestFullscreenSafe().finally(function(){ updateFullscreenButton(buttonId); });
      });
    }
  }

  async function fetchJson(url, opts){
    opts = opts || {};
    const controller = new AbortController();
    const timeoutMs = opts.timeoutMs || 8000;
    const timer = setTimeout(function(){ controller.abort(); }, timeoutMs);
    try {
      const res = await fetch(url, {
        method: opts.method || 'GET',
        headers: opts.headers || undefined,
        body: opts.body,
        cache: 'no-store',
        signal: controller.signal
      });
      let data = null;
      try { data = await res.json(); } catch (_) { data = null; }
      if (!res.ok) {
        const err = new Error(data && data.error ? data.error : ('HTTP ' + res.status));
        err.response = res;
        err.data = data;
        throw err;
      }
      return data;
    } finally {
      clearTimeout(timer);
    }
  }

  window.AppUI = {
    setTheme,
    initTheme,
    updateFullscreenButton,
    toggleFullscreen,
    initFullscreen,
    fetchJson,
    getFullscreenIntent,
    setFullscreenIntent
  };
})();
