(function () {
  var API = null, initialized = false, finished = false, completed = false;
  var startTime = Date.now();
  // Localized UI strings are injected as window.SCORM_STR by the exporter; fall back to English.
  var S = window.SCORM_STR || {};
  function tr(k, d) { return S[k] != null ? S[k] : d; }
  // Player config (contents drawer on/off and depth) injected as window.SCORM_CFG.
  var CFG = window.SCORM_CFG || {};

  function findAPI(win) {
    var tries = 0;
    while (win && !win.API && win.parent && win.parent !== win && tries < 20) {
      tries++; win = win.parent;
    }
    return win && win.API ? win.API : null;
  }
  function getAPI() {
    if (API) return API;
    try {
      API = findAPI(window);
      if (!API && window.opener) API = findAPI(window.opener);
    } catch (e) { API = null; }
    return API;
  }
  function init() {
    var api = getAPI();
    if (!api) return false;
    var ok = api.LMSInitialize('');
    initialized = ok === 'true' || ok === true;
    if (initialized) {
      var status = api.LMSGetValue('cmi.core.lesson_status');
      if (status === 'completed' || status === 'passed') completed = true;
      else api.LMSSetValue('cmi.core.lesson_status', 'incomplete');
      api.LMSCommit('');
    }
    return initialized;
  }
  function sessionTime() {
    var t = Math.floor((Date.now() - startTime) / 1000);
    function pad(n) { return (n < 10 ? '0' : '') + n; }
    return pad(Math.floor(t / 3600)) + ':' + pad(Math.floor((t % 3600) / 60)) + ':' + pad(t % 60);
  }
  function markComplete() {
    if (completed) return;
    var api = getAPI();
    if (!api || !initialized) return;
    completed = true;
    api.LMSSetValue('cmi.core.lesson_status', 'completed');
    api.LMSCommit('');
  }
  function terminate() {
    if (finished) return;
    var api = getAPI();
    if (!api || !initialized) return;
    finished = true;
    api.LMSSetValue('cmi.core.session_time', sessionTime());
    api.LMSCommit('');
    api.LMSFinish('');
  }

  function el(tag, className, html) {
    var e = document.createElement(tag);
    if (className) e.className = className;
    if (html != null) e.innerHTML = html;
    return e;
  }

  function buildPlayer() {
    var guideTitle = (document.title || 'Guide');
    var SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">';
    var ICON_LEFT = SVG + '<path d="M15 18l-6-6 6-6"/></svg>';
    var ICON_RIGHT = SVG + '<path d="M9 18l6-6-6-6"/></svg>';
    var ICON_CHECK = SVG + '<path d="M20 6L9 17l-5-5"/></svg>';
    var ICON_MENU = SVG + '<path d="M4 6h16M4 12h16M4 18h16"/></svg>';
    var ICON_X = SVG + '<path d="M18 6L6 18M6 6l12 12"/></svg>';

    // Gather slides: intro section + every step card (in document order).
    var nodes = [];
    var intro = document.querySelector('.topSection');
    if (intro) nodes.push(intro);
    Array.prototype.forEach.call(document.querySelectorAll('.stepCard'), function (card) {
      nodes.push(card.closest('.columns') || card);
    });
    if (nodes.length === 0) return; // Nothing to play; leave page as-is.

    var player = el('div', 'scormPlayer');

    var tocEnabled = CFG.toc !== false;
    var tocDepth = CFG.tocDepth || 0; // 0 = all levels, N = show up to N levels.

    // Header: contents button + title + counter + progress bar.
    var bar = el('div', 'scormBar');
    var titleEl = el('div', 'scormBar__title', guideTitle);
    var count = el('div', 'scormBar__count');
    var menuBtn = null;
    if (tocEnabled) {
      menuBtn = el('button', 'scormMenuBtn', ICON_MENU);
      menuBtn.setAttribute('aria-label', tr('contents', 'Contents'));
      bar.appendChild(menuBtn);
    }
    // Brand the player header with the guide's export logo, when one is set.
    var logoSrc = document.querySelector('.headerLogo img');
    if (logoSrc) {
      var logo = el('img', 'scormBar__logo');
      logo.src = logoSrc.getAttribute('src');
      logo.alt = '';
      bar.appendChild(logo);
    }
    bar.appendChild(titleEl);
    bar.appendChild(el('div', 'scormBar__spacer'));
    bar.appendChild(count);
    var progress = el('div', 'scormProgress');
    var fill = el('div', 'scormProgress__fill');
    progress.appendChild(fill);

    // Viewport with the moved step nodes, each wrapped as a slide.
    var viewport = el('div', 'scormViewport');
    var slides = [];
    nodes.forEach(function (node) {
      var slide = el('div', 'scormSlide');
      // The intro/cover slide is centered like a title card; steps flow from the top.
      if (node === intro) slide.setAttribute('data-center', '1');
      slide.appendChild(node);
      viewport.appendChild(slide);
      slides.push(slide);
    });
    // Final completion slide (vertically centered via the --center marker).
    var done = el('div', 'scormSlide');
    done.setAttribute('data-center', '1');
    done.appendChild(el('div', 'scormComplete',
      '<div class="scormComplete__check">' + ICON_CHECK + '</div>' +
      '<h2 class="scormComplete__title"></h2>' +
      '<p class="scormComplete__sub"></p>'));
    done.querySelector('.scormComplete__title').textContent = tr('completeTitle', 'Course complete');
    done.querySelector('.scormComplete__sub').textContent = tr('completeSub', 'You’ve finished this guide.');
    viewport.appendChild(done);
    slides.push(done);

    // Footer navigation.
    var footer = el('div', 'scormFooter');
    var back = el('button', 'scormBtn scormBtn--ghost', ICON_LEFT + '<span></span>');
    back.querySelector('span').textContent = tr('back', 'Back');
    var next = el('button', 'scormBtn scormBtn--primary', ''); // label set in render()
    footer.appendChild(back);
    footer.appendChild(next);

    // Contents drawer (jump to any step), only when the Table of Contents setting is on.
    // One entry per content slide (not the completion screen); the intro is "Overview".
    // The depth setting limits how deep substeps are listed (0 = all levels).
    var tocItems = [];
    var backdrop, drawer;
    var closeDrawer = function () {};
    if (tocEnabled) {
      backdrop = el('div', 'scormBackdrop');
      drawer = el('div', 'scormDrawer');
      var drawerHead = el('div', 'scormDrawer__head');
      var drawerTitle = el('div', 'scormDrawer__title');
      drawerTitle.textContent = tr('contents', 'Contents');
      drawerHead.appendChild(drawerTitle);
      var closeBtn = el('button', 'scormDrawer__close', ICON_X);
      closeBtn.setAttribute('aria-label', tr('close', 'Close'));
      drawerHead.appendChild(closeBtn);
      var tocList = el('div', 'scormTocList');
      slides.forEach(function (slide, i) {
        if (slide === done) return; // Skip the completion screen.
        var meta;
        if (nodes[i] === intro) {
          meta = { num: '', label: tr('overview', 'Overview') };
        } else {
          var nlEl = slide.querySelector('[data-nested-level]');
          var level = nlEl ? (parseInt(nlEl.getAttribute('data-nested-level'), 10) || 0) : 0;
          if (tocDepth > 0 && level >= tocDepth) return; // Beyond the chosen depth.
          var titleNode = slide.querySelector('.stepTitle');
          var textEl = slide.querySelector('.stepTitleText');
          var numEl = slide.querySelector('.stepTitleNumber') || (titleNode && titleNode.querySelector('b'));
          var num = numEl ? numEl.textContent.trim() : '';
          // Current template fills .stepTitleText; older exports leave it empty and put
          // the title as a bare text node in .stepTitle, so fall back to that (minus the number).
          var label = textEl && textEl.textContent.trim();
          if (!label && titleNode) {
            label = titleNode.textContent.trim();
            if (num && label.indexOf(num) === 0) label = label.slice(num.length).trim();
          }
          meta = { num: num, label: label || ('Step ' + i) };
        }
        var item = el('button', 'scormTocItem');
        item.appendChild(el('span', 'scormTocNum', meta.num || '&bull;'));
        var labelEl = el('span', 'scormTocLabel');
        labelEl.textContent = meta.label;
        item.appendChild(labelEl);
        item.addEventListener('click', function () { goTo(i); closeDrawer(); });
        tocList.appendChild(item);
        tocItems[i] = item;
      });
      drawer.appendChild(drawerHead);
      drawer.appendChild(tocList);

      closeDrawer = function () { backdrop.className = 'scormBackdrop'; drawer.className = 'scormDrawer'; };
      var openDrawer = function () { backdrop.className = 'scormBackdrop open'; drawer.className = 'scormDrawer open'; };
      menuBtn.addEventListener('click', openDrawer);
      closeBtn.addEventListener('click', closeDrawer);
      backdrop.addEventListener('click', closeDrawer);
    }

    player.appendChild(bar);
    player.appendChild(progress);
    player.appendChild(viewport);
    player.appendChild(footer);
    if (tocEnabled) {
      player.appendChild(backdrop);
      player.appendChild(drawer);
    }
    document.body.appendChild(player);

    var idx = 0, total = slides.length, lastIdx = total - 1;
    function render() {
      slides.forEach(function (s, i) {
        var cls = 'scormSlide';
        if (s.getAttribute('data-center')) cls += ' scormSlide--center';
        if (i === idx) cls += ' scormSlide--active';
        s.className = cls;
      });
      fill.style.width = (total > 1 ? (idx / lastIdx) * 100 : 100) + '%';
      count.textContent = idx >= lastIdx
        ? tr('complete', 'Complete')
        : tr('stepOf', 'Step {current} of {total}')
            .replace('{current}', idx + 1).replace('{total}', total - 1);
      back.disabled = idx === 0;
      var nextLabel = document.createElement('span');
      nextLabel.textContent = idx === lastIdx - 1 ? tr('finish', 'Finish') : tr('next', 'Next');
      next.innerHTML = '';
      if (idx === lastIdx - 1) {
        next.appendChild(nextLabel); next.insertAdjacentHTML('beforeend', ICON_CHECK);
      } else {
        next.appendChild(nextLabel); next.insertAdjacentHTML('beforeend', ICON_RIGHT);
      }
      next.style.visibility = idx === lastIdx ? 'hidden' : 'visible';
      tocItems.forEach(function (it, i) {
        if (it) it.className = 'scormTocItem' + (i === idx ? ' active' : '');
      });
      if (idx === lastIdx) markComplete();
      viewport.scrollTop = 0;
    }
    function go(delta) {
      var n = idx + delta;
      if (n < 0 || n > lastIdx) return;
      idx = n; render();
    }
    function goTo(n) {
      if (n < 0 || n > lastIdx) return;
      idx = n; render();
    }
    back.addEventListener('click', function () { go(-1); });
    next.addEventListener('click', function () { go(1); });
    document.addEventListener('keydown', function (e) {
      if (e.key === 'Escape') closeDrawer();
      else if (e.key === 'ArrowRight' || e.key === 'PageDown') go(1);
      else if (e.key === 'ArrowLeft' || e.key === 'PageUp') go(-1);
    });
    render();
  }

  function boot() {
    init(); // No LMS -> still plays as a standalone page.
    buildPlayer();
    window.addEventListener('beforeunload', terminate);
    window.addEventListener('pagehide', terminate);
    window.addEventListener('unload', terminate);
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', boot);
  } else {
    boot();
  }
})();
