// runtime.jsx — shared helpers + top-level page composer for the Kolaymarin Ekosistemi SPA.
// Loaded BEFORE the views-*.jsx section files and app.jsx so `css`, `ImageSlot`, `EKO` are global.
(function(){
  const el = React.createElement;

  // Inline CSS string ("a:b;c-d:e") -> React style object ({a:'b', cD:'e'}).
  // Custom properties (--km-*) are preserved verbatim.
  window.css = function(str){
    var out = {};
    if(!str) return out;
    String(str).split(';').forEach(function(decl){
      decl = decl.trim();
      if(!decl) return;
      var i = decl.indexOf(':');
      if(i < 0) return;
      var prop = decl.slice(0, i).trim();
      var val = decl.slice(i + 1).trim();
      if(!prop) return;
      var key = (prop.charAt(0) === '-' && prop.charAt(1) === '-')
        ? prop
        : prop.replace(/-([a-z])/g, function(m, c){ return c.toUpperCase(); });
      out[key] = val;
    });
    return out;
  };

  // Replaces the design-tool <image-slot>. Shows the cover image when present,
  // otherwise a hatched placeholder box (.km-ph) with the placeholder label.
  window.ImageSlot = function(props){
    var style = props.style || {};
    if(props.src){
      return el('img', {
        src: props.src,
        alt: '',
        loading: 'lazy',
        style: Object.assign({ objectFit: props.fit || 'cover', display: 'block', width: '100%', height: '100%' }, style)
      });
    }
    return el('div', { className: 'km-ph', style: style }, props.placeholder || '');
  };

  window.EKO = window.EKO || {};

  // Hero/stat count-up — animates 0 → target when first scrolled into view.
  // Usage: <CountUp to={31000} suffix="+" /> → "31.000+"
  window.CountUp = function(props){
    var to = Number(props.to) || 0;
    var suffix = props.suffix || '';
    var duration = props.duration != null ? props.duration : 1400;
    var delay = props.delay || 0;
    var style = props.style || {};
    var className = props.className || 'km-num';
    var _s = React.useState(0);
    var n = _s[0], setN = _s[1];
    var ref = React.useRef(null);
    var started = React.useRef(false);

    React.useEffect(function(){
      var node = ref.current;
      if(!node || typeof IntersectionObserver === 'undefined'){
        setN(to);
        return;
      }
      var obs = new IntersectionObserver(function(entries){
        if(!entries[0] || !entries[0].isIntersecting || started.current) return;
        started.current = true;
        var t0 = null;
        var startAt = performance.now() + delay;
        function tick(now){
          if(now < startAt){ requestAnimationFrame(tick); return; }
          if(t0 == null) t0 = now;
          var p = Math.min(1, (now - t0) / duration);
          var eased = 1 - Math.pow(1 - p, 3);
          setN(Math.round(to * eased));
          if(p < 1) requestAnimationFrame(tick);
        }
        requestAnimationFrame(tick);
        obs.disconnect();
      }, { threshold: 0.35 });
      obs.observe(node);
      return function(){ obs.disconnect(); };
    }, [to, duration, delay]);

    return el('b', { ref: ref, className: className, style: style },
      n.toLocaleString('tr-TR') + suffix
    );
  };

  // Safely invoke a section renderer; missing/broken sections render nothing
  // instead of blowing up the whole page.
  function call(name, V){
    var f = window.EKO[name];
    if(typeof f !== 'function') return null;
    try { return f(V); }
    catch(e){ if(window.console) console.error('[EKO] ' + name + ' render error:', e); return null; }
  }

  // Top-level page composer — mirrors the .dc.html document body:
  // skip link + flex column (header, main view-router, footer, bottom nav) + overlays.
  window.EKO.page = function(V){
    return el(React.Fragment, null,
      el('a', { href: '#km-main', className: 'km-skip' }, 'İçeriğe geç'),
      el('div', { style: window.css('min-height:100vh;display:flex;flex-direction:column;--km-mod:' + V.modAccent) },
        call('header', V),
        V.menuOpen ? call('menuDrawer', V) : null,
        el('main', { id: 'km-main', style: window.css('flex:1;width:100%') },
          V.isHome    ? call('home', V)    : null,
          V.isBayrak  ? call('bayrak', V)  : null,
          V.isLanding ? call('landing', V) : null,
          V.isList    ? call('list', V)    : null,
          V.isAdmin   ? call('admin', V)   : null,
          V.isDetail  ? call('detail', V)  : null,
          V.isBooking ? call('booking', V) : null,
          V.isPanel   ? call('panel', V)   : null
        ),
        call('footer', V),
        call('bottomNav', V),
        call('modals', V)
      )
    );
  };
})();
