/* assets/js/ua_app_shell_contract.js
   Shared viewport measurement and overflow state for the desktop shell.
   Pages keep their visual design; this module owns responsive geometry only. */
(function(){
  'use strict';

  var d = document;
  var body = d.body;
  if (!body) return;

  var root = d.documentElement;
  var inFrame = false;
  try { inFrame = window.self !== window.top; } catch(e) { inFrame = true; }

  var refs = {
    root: d.getElementById('uaShellRoot'),
    stats: d.getElementById('uaShellStatsBar'),
    goldLine: d.getElementById('uaShellGoldLine'),
    windowbar: d.getElementById('uaShellWindowBar'),
    main: d.getElementById('uaShellMain'),
    workspace: d.getElementById('uaWorkspaceHost'),
    sidebar: d.querySelector('.ua-sb3')
  };

  var isChrome = body.classList.contains('ua-shell-chrome')
    && !body.classList.contains('ua-page-dashboard')
    && !inFrame;

  function mark(name, el){
    if (el && !el.getAttribute('data-ua-shell-region')) {
      el.setAttribute('data-ua-shell-region', name);
    }
  }

  mark('root', refs.root);
  mark('stats', refs.stats);
  mark('gold-line', refs.goldLine);
  mark('windowbar', refs.windowbar);
  mark('main', refs.main);
  mark('workspace', refs.workspace);
  mark('sidebar', refs.sidebar);
  if (refs.workspace) refs.workspace.setAttribute('data-ua-workspace-host', '1');

  var warnings = [];
  if (isChrome) {
    ['sidebar','stats','windowbar','main','workspace'].forEach(function(key){
      if (!refs[key]) warnings.push(key);
    });
  }

  var resizeFrame = 0;
  var resizeObserver = null;

  function viewportBox(){
    var vv = window.visualViewport;
    return {
      width: Math.max(1, Math.round(vv && vv.width ? vv.width : window.innerWidth || root.clientWidth || 1)),
      height: Math.max(1, Math.round(vv && vv.height ? vv.height : window.innerHeight || root.clientHeight || 1))
    };
  }

  function px(value){
    return Math.max(0, Math.round(Number(value) || 0)) + 'px';
  }

  function visibleTop(el){
    if (!el || !el.getBoundingClientRect) return 0;
    var rect = el.getBoundingClientRect();
    return Math.max(0, rect.top || 0);
  }

  function updateScrollRegion(el){
    if (!el || !el.classList) return;
    var needsX = (el.scrollWidth - el.clientWidth) > 2;
    var needsY = (el.scrollHeight - el.clientHeight) > 2;
    el.classList.toggle('ua-scroll-x-needed', needsX);
    el.classList.toggle('ua-scroll-y-needed', needsY);
    el.setAttribute('data-ua-overflow-x', needsX ? '1' : '0');
    el.setAttribute('data-ua-overflow-y', needsY ? '1' : '0');
  }

  function scanScrollRegions(){
    d.querySelectorAll('[data-ua-scroll-region]').forEach(function(el){
      updateScrollRegion(el);
      if (!resizeObserver) return;
      try { resizeObserver.observe(el); } catch(e) {}
      Array.prototype.forEach.call(el.children || [], function(child){
        try { resizeObserver.observe(child); } catch(e) {}
      });
    });
  }

  function measure(){
    resizeFrame = 0;
    var viewport = viewportBox();
    var workspace = refs.workspace || refs.main || d.querySelector('.ua-page') || body;
    var workspaceRect = workspace && workspace.getBoundingClientRect
      ? workspace.getBoundingClientRect()
      : null;
    var workspaceTop = visibleTop(workspace);
    var workspaceHeight = Math.max(280, viewport.height - workspaceTop);
    var workspaceWidth = Math.max(
      1,
      Math.round(workspaceRect && workspaceRect.width ? workspaceRect.width : viewport.width)
    );

    root.style.setProperty('--ua-contract-viewport-w', px(viewport.width));
    root.style.setProperty('--ua-contract-viewport-h', px(viewport.height));
    root.style.setProperty('--ua-contract-workspace-w', px(workspaceWidth));
    root.style.setProperty('--ua-contract-workspace-top', px(workspaceTop));
    root.style.setProperty('--ua-contract-workspace-h', px(workspaceHeight));
    root.setAttribute('data-ua-viewport-width', String(viewport.width));
    root.setAttribute('data-ua-viewport-height', String(viewport.height));
    root.setAttribute('data-ua-workspace-width', String(workspaceWidth));
    root.setAttribute('data-ua-workspace-height', String(workspaceHeight));

    body.classList.toggle('ua-viewport-short', viewport.height < 720);
    body.classList.toggle('ua-viewport-narrow', viewport.width < 1100);
    body.classList.toggle('ua-viewport-compact', viewport.width < 900 || viewport.height < 640);
    body.classList.toggle('ua-workspace-narrow', workspaceWidth < 980);
    body.classList.toggle('ua-workspace-compact', workspaceWidth < 760);

    d.querySelectorAll('[data-ua-viewport-fill]').forEach(function(el){
      var bottomGap = parseFloat(el.getAttribute('data-ua-viewport-bottom-gap') || '8');
      var available = Math.max(240, viewport.height - visibleTop(el) - Math.max(0, bottomGap || 0));
      el.style.setProperty('--ua-fill-available-h', px(available));
    });

    scanScrollRegions();
    try {
      window.dispatchEvent(new CustomEvent('ua:layout', {detail:viewport}));
    } catch(e) {}
  }

  function scheduleMeasure(){
    if (resizeFrame) cancelAnimationFrame(resizeFrame);
    resizeFrame = requestAnimationFrame(measure);
  }

  if (window.ResizeObserver) {
    resizeObserver = new ResizeObserver(function(entries){
      entries.forEach(function(entry){
        var region = entry.target.closest
          ? entry.target.closest('[data-ua-scroll-region]')
          : null;
        if (region) updateScrollRegion(region);
      });
    });
    [refs.stats, refs.windowbar, refs.main, refs.workspace].forEach(function(el){
      if (!el) return;
      try { resizeObserver.observe(el); } catch(e) {}
    });
  }

  if (window.MutationObserver) {
    try {
      new MutationObserver(scheduleMeasure).observe(refs.workspace || body, {
        childList:true,
        subtree:true,
        attributes:true,
        attributeFilter:['class','hidden']
      });
    } catch(e) {}
  }

  window.addEventListener('resize', scheduleMeasure, {passive:true});
  window.addEventListener('orientationchange', scheduleMeasure, {passive:true});
  window.addEventListener('pageshow', scheduleMeasure, {passive:true});
  if (window.visualViewport) {
    window.visualViewport.addEventListener('resize', scheduleMeasure, {passive:true});
    window.visualViewport.addEventListener('scroll', scheduleMeasure, {passive:true});
  }

  body.classList.add('ua-shell-contract-ready');

  window.UAAppShellContract = {
    version: '2026-07-25-responsive-workspace',
    locked: true,
    inFrame: inFrame,
    isChrome: isChrome,
    regions: refs,
    warnings: warnings.slice(),
    measure: scheduleMeasure,
    updateScrollRegion: updateScrollRegion
  };

  if (warnings.length && window.console && console.warn) {
    console.warn('[UA Shell Contract] Missing shell regions:', warnings.join(', '));
  }

  scheduleMeasure();
  setTimeout(scheduleMeasure, 80);
  setTimeout(scheduleMeasure, 500);
})();
