/* EireneEduCloud — subject.js (data-driven lesson viewer, enriched dual-mode)
   Eirene Technologies Limited
   Renders: outcomes, discoverable media badges, video (YouTube online / local MP4 offline),
   on-device audio narration, timestamped transcript, reading, key terms, interactive widget,
   virtual lab (PhET), Wikipedia enrichment, AI tutor, and quiz.
   Online vs offline-package behaviour: set window.EE_PACKAGE = true in a packaged build to
   force fully-offline rendering (local media, no external embeds). */
(function (w, d) {
  function param(name) {
    var m = new RegExp('[?&]' + name + '=([^&]+)').exec(w.location.search);
    return m ? decodeURIComponent(m[1]) : null;
  }
  function esc(s) { return (s == null ? '' : String(s)).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); }
  function stripHtml(s) { return String(s || '').replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim(); }
  function online() { return !w.EE_PACKAGE && !w.EE_OFFLINE && (!w.navigator || w.navigator.onLine !== false); }
  function vid(l) { var v = l.video; if (!v) return null; return (typeof v === 'string') ? { id: v } : v; }

  var SubjectView = {
    subject: null, flat: [], idx: 0, _ctx: null,

    start: function () {
      if (!w.CURRICULUM) return;
      var lot = parseInt(param('lot'), 10) || (w.CURRICULUM.subjects[0] && w.CURRICULUM.subjects[0].lot) || 1;
      this.subject = w.CURRICULUM.subjects.filter(function (s) { return s.lot === lot; })[0]
                   || w.CURRICULUM.subjects[0];
      d.body.classList.add('accent-' + this.subject.color);

      var self = this;
      this.flat = [];
      this.subject.units.forEach(function (u, ui) {
        u.lessons.forEach(function (l) { self.flat.push({ lesson: l, unitTitle: u.title, ui: ui }); });
      });

      d.getElementById('sb-title').textContent = this.subject.icon + '  ' + this.subject.name;
      d.getElementById('sb-blurb').textContent = this.subject.blurb || '';
      d.title = 'EireneEduCloud — ' + this.subject.name;

      var startIdx = 0;
      for (var i = 0; i < this.flat.length; i++) {
        if (!(w.ProgressTracker && w.ProgressTracker.isLessonDone(this.flat[i].lesson.id))) { startIdx = i; break; }
      }
      this.renderSidebar();
      this.go(startIdx);
      this.updateBar();
    },

    renderSidebar: function () {
      var side = d.getElementById('v-side');
      var pt = w.ProgressTracker;
      var html = '<div class="side-h">Course content</div>';
      var counter = 0;
      this.subject.units.forEach(function (u) {
        html += '<div class="unit"><div class="unit-t">' + esc(u.title) + '</div><ul>';
        u.lessons.forEach(function (l) {
          var done = pt && pt.isLessonDone(l.id);
          var qz = pt && pt.getQuiz(l.id);
          html += '<li><a href="#" class="lesson-link" data-i="' + counter + '">' +
            '<span class="tick ' + (done ? 'on' : '') + '">' + (done ? '✓' : '') + '</span>' +
            '<span class="ll-title">' + esc(l.title) + '</span>' +
            (qz ? '<span class="ll-score">' + qz.pct + '%</span>' : '') +
            '</a></li>';
          counter++;
        });
        html += '</ul></div>';
      });
      side.innerHTML = html;
      var self = this;
      side.querySelectorAll('.lesson-link').forEach(function (a) {
        a.addEventListener('click', function (e) { e.preventDefault(); self.go(parseInt(a.dataset.i, 10)); side.classList.remove('open'); });
      });
    },

    go: function (i) {
      if (i < 0 || i >= this.flat.length) return;
      if (w.EireneAudio) w.EireneAudio.stop();
      var oldAnim = d.getElementById('sec-anim'); if (oldAnim && oldAnim._stop) oldAnim._stop();
      this.idx = i;
      var item = this.flat[i], l = item.lesson;
      if (w.ProgressTracker) w.ProgressTracker.markLesson(l.id);
      this.renderLesson(item);
      this.markActive();
      this.updateBar();
      w.scrollTo(0, 0);
    },

    markActive: function () {
      var links = d.querySelectorAll('.lesson-link');
      for (var i = 0; i < links.length; i++) links[i].classList.toggle('active', parseInt(links[i].dataset.i, 10) === this.idx);
    },

    renderLesson: function (item) {
      var l = item.lesson, main = d.getElementById('v-main');
      var v = vid(l);
      var lang = (this.subject && this.subject.slug === 'kiswahili') ? 'sw' : 'en';
      var hasVideo = !!v, hasAudio = true, hasRead = !!l.reading,
          hasTerms = l.keyTerms && l.keyTerms.length, hasInter = !!l.interactive,
          hasLab = !!l.virtualLab, hasWiki = l.wikipedia && l.wikipedia.length,
          hasAnim = !!l.animation, hasGame = !!(l.game && l.game.type),
          hasQuiz = l.quiz && l.quiz.questions && l.quiz.questions.length;

      // ---- head ----
      var html = '<div class="lesson-head"><div class="crumbs">' + esc(item.unitTitle) + '</div>' +
        '<h2>' + esc(l.title) + '</h2>' +
        '<div class="lesson-tags"><span class="time">⏱ ' + esc(l.time || '15 min') + '</span></div></div>';

      // ---- learning outcomes ----
      if (l.outcomes && l.outcomes.length) {
        html += '<div class="outcomes"><h4>Learning outcomes</h4><ul>' +
          l.outcomes.map(function (o) { return '<li>' + esc(o) + '</li>'; }).join('') + '</ul></div>';
      }

      // ---- discoverable media badges ----
      var badges = [];
      if (hasVideo) badges.push(['sec-video', '🎬 Video']);
      if (hasAudio) badges.push(['sec-audio', '🎧 Listen']);
      if (hasRead) badges.push(['sec-read', '📖 Read']);
      if (hasAnim) badges.push(['sec-anim', '✨ Animation']);
      if (hasGame) badges.push(['sec-game', '🎮 Game']);
      if (hasLab) badges.push(['sec-lab', '🧪 Virtual lab']);
      if (hasWiki) badges.push(['sec-wiki', '🌐 Learn more']);
      badges.push(['sec-ai', '🤖 Ask AI']);
      if (hasQuiz) badges.push(['sec-quiz', '✅ Quiz']);
      html += '<div class="media-badges">' + badges.map(function (b) {
        return '<span class="mb" data-go="' + b[0] + '">' + b[1] + '</span>';
      }).join('') + '</div>';

      // ---- video ----
      if (hasVideo) {
        html += '<div id="sec-video">';
        var note;
        if (online() && v.id) {
          html += '<div class="video-wrap"><iframe loading="lazy" src="' +
            encodeURIComponent(v.id) + '?cc_load_policy=1&cc_lang_pref=' + lang + '&hl=' + lang + '&rel=0&modestbranding=1" title="' + esc(v.title || l.title) + '" allow="accelerometer; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>';
          note = (v.channel ? 'Source: ' + esc(v.channel) + '. ' : '');
          if (v.query) note += '<a href="' + encodeURIComponent(v.query) + '" target="_blank" rel="noopener">More videos ↗</a> · ';
          note += 'Offline packages play the bundled MP4 — no internet required.';
        } else if (v.localFile && w.EE_HAS_MP4) {
          html += '<div class="video-wrap"><video controls preload="none" poster="assets/media/sample-poster.jpg" src="assets/media/' + esc(v.localFile) + '"></video></div>';
          note = 'Bundled offline video — no internet required.';
        } else {
          // offline package without a bundled MP4 for this lesson: branded poster + listen prompt
          html += '<div class="video-wrap"><img src="assets/media/sample-poster.jpg" alt="' + esc(v.title || l.title) + '" style="width:100%;height:100%;object-fit:cover"></div>';
          note = '🎬 ' + esc(v.title || l.title) + ' — the full video is included in the production master. Meanwhile, press <strong>🎧 Listen</strong> below for on-device narration of this lesson.';
        }
        html += '<p class="video-note muted">' + note + '</p></div>';
      }

      // ---- audio narration ("Listen to this lesson") ----
      html += '<div id="sec-audio" class="audio-bar">' +
        '<button class="ab-btn" id="ab-play" title="Play">▶</button>' +
        '<button class="ab-btn" id="ab-stop" title="Stop">■</button>' +
        '<span class="ab-label">🎧 Listen to this lesson</span>' +
        '<span class="ab-status" id="ab-status">On-device narration — works offline.</span>' +
        '<label>Speed <select id="ab-rate"><option value="0.85">0.85×</option><option value="1" selected>1×</option><option value="1.15">1.15×</option><option value="1.3">1.3×</option></select></label>' +
        '</div>';
      // optional podcast / audio file
      if (l.audio && l.audio.mode === 'podcast' && l.audio.url && online()) {
        html += '<div class="podcast-card"><h4>🎙 Related podcast: ' + esc(l.audio.title || '') + '</h4>' +
          '<p class="muted">' + esc(l.audio.note || '') + '</p><div class="pod-embed">' + podEmbed(l.audio) + '</div></div>';
      } else if (l.audio && l.audio.mode === 'file' && l.audio.localFile) {
        html += '<audio controls preload="none" style="width:100%;margin:8px 0" src="assets/media/' + esc(l.audio.localFile) + '"></audio>';
      }

      // ---- transcript ----
      if (l.transcript && l.transcript.length) {
        html += '<div class="transcript-box"><div class="tr-bar">' +
          '<span class="tr-title">📝 Subtitles / transcript</span>' +
          '<button class="btn btn-ghost btn-sm" type="button" id="tr-toggle">Hide</button>' +
          '<input type="search" id="tr-search" class="tr-search" placeholder="Search transcript…"></div>' +
          '<div class="transcript" id="transcript">';
        l.transcript.forEach(function (line) {
          html += '<p class="tr-line"><span class="t">' + esc(line.t) + '</span><span class="s">' + esc(line.s) + '</span></p>';
        });
        html += '</div></div>';
      }

      // ---- reading ----
      if (hasRead) html += '<div id="sec-read" class="reading">' + l.reading + '</div>';

      // ---- key terms ----
      if (hasTerms) {
        html += '<div class="keyterms"><h4>📌 Key terms</h4>' +
          l.keyTerms.map(function (k) { return '<div class="kt"><b>' + esc(k.term) + '</b><span>' + esc(k.definition || k.def || '') + '</span></div>'; }).join('') +
          '</div>';
      }

      // ---- interactive ----
      if (hasInter) html += '<div id="sec-interactive">' + this.interactiveHtml(l.interactive) + '</div>';

      // ---- animation ----
      if (hasAnim) html += '<div id="sec-anim" class="animation"></div>';

      // ---- game ----
      if (hasGame) html += '<div id="sec-game" class="game"></div>';

      // ---- virtual lab ----
      if (hasLab) html += '<div id="sec-lab" class="lab"><div id="lab-mount"></div></div>';

      // ---- wikipedia enrichment ----
      if (hasWiki) {
        html += '<div id="sec-wiki" class="wiki-panel"><h4>🌐 Learn more</h4>' +
          '<div class="wiki-terms">' + l.wikipedia.map(function (wk, i) {
            return '<button data-title="' + esc(wk.title) + '" data-url="' + esc(wk.url) + '">' + esc(wk.title) + '</button>';
          }).join('') + '</div><div id="wiki-out"></div></div>';
      }

      // ---- AI tutor ----
      html += '<div id="sec-ai" class="ai-panel"><div class="ai-head"><span class="ai-ic">AI</span>' +
        '<strong>Ask Eirene AI</strong><span class="ai-mode" id="ai-mode">offline</span></div>' +
        '<div class="ai-actions">' +
          '<span class="mb" data-ai="explain">Explain simply</span>' +
          '<span class="mb" data-ai="summarize">Summarise</span>' +
          '<span class="mb" data-ai="hint">Give a hint</span>' +
          '<span class="mb" data-ai="practice">More practice</span>' +
        '</div><div class="ai-log" id="ai-log"></div>' +
        '<div class="ai-inrow"><input id="ai-input" placeholder="Ask about this lesson…"><button class="btn btn-primary btn-sm" id="ai-send">Ask</button></div></div>';

      // ---- quiz ----
      if (hasQuiz) html += '<div id="sec-quiz" class="quiz-section"><div id="quiz-mount-' + esc(l.id) + '"></div></div>';

      // ---- nav ----
      var prev = this.flat[this.idx - 1], next = this.flat[this.idx + 1];
      html += '<div class="lesson-nav">' +
        (prev ? '<button class="btn btn-ghost" type="button" id="nav-prev">‹ ' + esc(prev.lesson.title) + '</button>' : '<span></span>') +
        (next ? '<button class="btn btn-primary" type="button" id="nav-next">' + esc(next.lesson.title) + ' ›</button>'
              : '<button class="btn btn-gold" type="button" id="nav-done">Finish subject ✓</button>') +
        '</div>';

      main.innerHTML = html;
      this._ctx = {
        title: l.title, subject: this.subject.name,
        reading: stripHtml(l.reading) + ' ' + (l.transcript || []).map(function (x) { return x.s; }).join(' '),
        keyTerms: l.keyTerms || [], quiz: l.quiz || null, outcomes: l.outcomes || []
      };
      this.wire(l);
    },

    interactiveHtml: function (it) {
      if (it.type === 'expr' && it.parts) {
        var parts = it.parts.map(function (p) { return '<button class="expr-part" type="button" data-r="' + esc(p.r) + '">' + esc(p.t) + '</button>'; }).join(' ');
        return '<div class="interactive"><h4>🎮 Interactive</h4><p class="muted">' + esc(it.prompt || '') + '</p><div class="expr">' + parts + '</div><div class="expr-out" id="expr-out">Tap a part above…</div></div>';
      }
      return '<div class="interactive"><h4>🎮 Try it</h4><div>' + (it.html || esc(it.prompt || '')) + '</div></div>';
    },

    wire: function (l) {
      var self = this, ctx = this._ctx;

      // media badges -> smooth scroll
      d.querySelectorAll('.media-badges .mb').forEach(function (b) {
        b.addEventListener('click', function () {
          var t = d.getElementById(b.dataset.go);
          if (t) t.scrollIntoView({ behavior: 'smooth', block: 'start' });
        });
      });

      // transcript
      var tg = d.getElementById('tr-toggle');
      if (tg) tg.addEventListener('click', function () {
        var t = d.getElementById('transcript'), s = d.getElementById('tr-search');
        if (t.hasAttribute('hidden')) { t.removeAttribute('hidden'); s.removeAttribute('hidden'); tg.textContent = 'Hide'; }
        else { t.setAttribute('hidden', ''); s.setAttribute('hidden', ''); tg.textContent = 'Show'; }
      });
      var ts = d.getElementById('tr-search');
      if (ts) ts.addEventListener('input', function () {
        var q = ts.value.toLowerCase();
        d.querySelectorAll('#transcript .tr-line').forEach(function (line) {
          var hit = !q || line.textContent.toLowerCase().indexOf(q) >= 0;
          line.style.display = hit ? '' : 'none'; line.classList.toggle('hl', q && hit);
        });
      });

      // audio narration
      this.wireAudio(l, ctx);

      // interactive expr
      var out = d.getElementById('expr-out');
      if (out) d.querySelectorAll('.expr-part').forEach(function (b) {
        b.addEventListener('click', function () {
          d.querySelectorAll('.expr-part').forEach(function (x) { x.classList.remove('sel'); });
          b.classList.add('sel'); out.innerHTML = '<strong>' + b.textContent + '</strong> — ' + b.dataset.r;
        });
      });

      // virtual lab — online: live PhET; offline replica: bundled local PhET html; package: note
      if (l.virtualLab && w.EireneLabs) {
        var lm = d.getElementById('lab-mount');
        if (lm) {
          if (online()) w.EireneLabs.embed(lm, l.virtualLab);
          else if (w.EE_OFFLINE && w.EireneLabs.embedLocal) w.EireneLabs.embedLocal(lm, l.virtualLab);
          else lm.innerHTML = '<div class="lab-head"><span class="lab-ic">🧪</span><strong>Virtual Lab: ' + esc(l.virtualLab.title || '') + '</strong></div><p class="muted">' + esc(l.virtualLab.note || 'This interactive simulation runs when online.') + '</p>';
        }
      }

      // animation
      if (l.animation && w.EireneAnim) {
        var ae = d.getElementById('sec-anim'); if (ae) w.EireneAnim.mount(ae, l.animation);
      }

      // game
      if (l.game && l.game.type && w.EireneGames) {
        var ge = d.getElementById('sec-game'); if (ge) w.EireneGames.mount(ge, l.game);
      }

      // wikipedia
      d.querySelectorAll('.wiki-terms button').forEach(function (b) {
        b.addEventListener('click', function () {
          d.querySelectorAll('.wiki-terms button').forEach(function (x) { x.classList.remove('on'); });
          b.classList.add('on');
          var outEl = d.getElementById('wiki-out');
          if (w.EireneWiki) w.EireneWiki.render(outEl, b.dataset.title);
          else outEl.innerHTML = '<a href="' + b.dataset.url + '" target="_blank" rel="noopener">Open on Wikipedia ↗</a>';
        });
      });

      // AI tutor
      this.wireAI(ctx);

      // quiz
      if (l.quiz && l.quiz.questions && l.quiz.questions.length && w.QuizEngine) {
        var qe = new w.QuizEngine('quiz-mount-' + l.id, l.quiz, l.id, function (score, total) {
          self.renderSidebar(); self.markActive(); self.updateBar();
          if (w.EE) w.EE.toast('Saved: ' + score + '/' + total + ' on ' + l.title);
        });
        qe.render();
      }

      // nav
      var p = d.getElementById('nav-prev'); if (p) p.addEventListener('click', function () { self.go(self.idx - 1); });
      var n = d.getElementById('nav-next'); if (n) n.addEventListener('click', function () { self.go(self.idx + 1); });
      var f = d.getElementById('nav-done'); if (f) f.addEventListener('click', function () {
        if (w.EireneAudio) w.EireneAudio.stop();
        if (w.EE) w.EE.toast('🎉 Subject complete — well done!');
        w.location.href = 'index.html#subjects';
      });
    },

    wireAudio: function (l, ctx) {
      var play = d.getElementById('ab-play'), stop = d.getElementById('ab-stop'),
          rate = d.getElementById('ab-rate'), status = d.getElementById('ab-status');
      if (!play) return;
      var A = w.EireneAudio;
      if (!A || !A.supported()) { status.textContent = 'Audio narration not supported on this browser.'; play.disabled = true; return; }
      var text = (l.outcomes && l.outcomes.length ? 'Lesson: ' + l.title + '. ' : '') + ctx.reading;
      function setPlaying(on) { play.textContent = on ? '❚❚' : '▶'; play.title = on ? 'Pause' : 'Play'; }
      play.addEventListener('click', function () {
        if (A.isPlaying()) { A.pause(); setPlaying(false); status.textContent = 'Paused.'; return; }
        if (A._paused) { A.resume(); setPlaying(true); status.textContent = 'Narrating…'; return; }
        setPlaying(true); status.textContent = 'Narrating…';
        A.speak(text, {
          rate: parseFloat(rate.value),
          onsentence: function (i, total) { status.textContent = 'Narrating… (' + (i + 1) + '/' + total + ')'; },
          ondone: function () { setPlaying(false); status.textContent = 'Finished. ▶ to replay.'; }
        });
      });
      stop.addEventListener('click', function () { A.stop(); setPlaying(false); status.textContent = 'Stopped.'; });
      rate.addEventListener('change', function () { A.setRate(parseFloat(rate.value)); });
    },

    wireAI: function (ctx) {
      var log = d.getElementById('ai-log'), input = d.getElementById('ai-input'),
          send = d.getElementById('ai-send'), modeEl = d.getElementById('ai-mode');
      if (!log || !w.EireneAI) return;
      var mode = w.EireneAI.mode();
      modeEl.textContent = mode === 'live' ? 'live AI' : 'offline';
      modeEl.className = 'ai-mode ' + (mode === 'live' ? 'live' : '');
      function add(cls, text) {
        var m = d.createElement('div'); m.className = 'ai-msg ' + cls; m.textContent = text;
        log.appendChild(m); log.scrollTop = log.scrollHeight; return m;
      }
      function ask(action, userText) {
        if (userText) add('user', userText);
        var thinking = add('ai', '…');
        w.EireneAI.respond(action, ctx, userText).then(function (r) { thinking.textContent = r || '(no response)'; });
      }
      d.querySelectorAll('.ai-actions .mb').forEach(function (b) {
        b.addEventListener('click', function () { ask(b.dataset.ai, null); });
      });
      function sendInput() { var t = input.value.trim(); if (!t) return; input.value = ''; ask('ask', t); }
      if (send) send.addEventListener('click', sendInput);
      if (input) input.addEventListener('keydown', function (e) { if (e.key === 'Enter') sendInput(); });
    },

    updateBar: function () {
      if (!w.ProgressTracker) return;
      var ids = this.flat.map(function (x) { return x.lesson.id; });
      var p = w.ProgressTracker.subjectProgress(ids);
      var bar = d.getElementById('sb-prog'); if (bar) bar.style.width = p.pct + '%';
    }
  };

  function podEmbed(a) {
    if (a.embedType === 'apple' || /podcasts\.apple\.com/.test(a.url || '')) {
      var src = (a.url || '').replace('podcasts.apple.com', 'embed.podcasts.apple.com');
      return '<iframe height="175" style="width:100%" frameborder="0" loading="lazy" allow="encrypted-media" src="' + src + '"></iframe>';
    }
    if (a.embedType === 'spotify' || /spotify\.com/.test(a.url || '')) {
      var s = (a.url || '').replace('open.spotify.com/', 'open.spotify.com/embed/');
      return '<iframe style="width:100%" height="232" frameborder="0" loading="lazy" allow="encrypted-media" src="' + s + '"></iframe>';
    }
    if (/youtube\.com|youtu\.be/.test(a.url || '')) {
      var id = (a.url.match(/[?&]v=([^&]+)/) || a.url.match(/youtu\.be\/([^?]+)/) || [])[1];
      if (id) return '<div class="video-wrap"><iframe loading="lazy" src="' + id + '" allowfullscreen></iframe></div>';
    }
    return '<a href="' + (a.url || '#') + '" target="_blank" rel="noopener">Open podcast ↗</a>';
  }

  d.addEventListener('keydown', function (e) {
    var tag = (e.target && e.target.tagName) || '';
    if (tag === 'INPUT' || tag === 'TEXTAREA') return;
    if (e.key === 'ArrowRight') SubjectView.go(SubjectView.idx + 1);
    if (e.key === 'ArrowLeft') SubjectView.go(SubjectView.idx - 1);
  });

  function boot() { SubjectView.start(); }
  if (d.readyState === 'loading') d.addEventListener('DOMContentLoaded', boot); else boot();
  w.SubjectView = SubjectView;
})(window, document);
