// ─────────────────────────────────────────────────────────
// ChefVerse · LessonViewer (V3.2) — renders IN-SHELL (topbar + sidebar stay)
//
//   • VIDEO lessons → delegate to the real <Player> via lessonMode, so the
//     working chapters, scrubber ticks, on-video animation, resources, notes,
//     and auto-completion all behave exactly as before.
//   • WRITTEN / GRAPHIC / CAROUSEL → an in-shell page reusing the player's
//     two-column layout (.player-grid): content stage + title/intro + Save on
//     the left; a side card (Notes only — NO chapters) + Resources on the right.
//
//   Completion: written = scroll-to-bottom, graphic = view, carousel = all cards.
// ─────────────────────────────────────────────────────────

const { useState: useStateLv, useEffect: useEffectLv, useRef: useRefLv } = React;

function lvFmt(sec) {
  const m = Math.floor(sec / 60), s = Math.round(sec % 60);
  return m + ":" + String(s).padStart(2, "0");
}

function _lvWritten(lesson, locale) {
  const t = (lesson.title[locale] || lesson.title.en);
  const sets = {
    en: [
      `${t}. The strongest captions do one job: they make a scrolling viewer stop and read. This lesson breaks down how to write for the kitchen — fast, clear, and in your own voice.`,
      "Start with the verb. \u201CSear the scallops\u201D beats \u201CToday we are going to sear some scallops.\u201D Every wasted word is a chance to scroll on. Lead with the action, then explain.",
      "Write the way you talk on the pass. If you would not say it to a commis mid-service, do not type it. The caption is an extension of your voice, not a press release.",
      "Localise, do not translate. A phrase that lands in English may fall flat in German or Bahasa. Rework the idea for each market rather than running it through a translator word-for-word.",
      "Close with one clear next step: a question, a tip, or an invitation to try it. The comment section is where the algorithm decides whether your content travels.",
    ],
    de: [
      `${t}. Die st\u00E4rksten Bildunterschriften haben eine Aufgabe: einen scrollenden Betrachter zum Anhalten zu bringen. Diese Lektion zeigt, wie du f\u00FCr die K\u00FCche schreibst \u2014 schnell, klar, in deiner Stimme.`,
      "Beginne mit dem Verb. \u201EJakobsmuscheln anbraten\u201C schl\u00E4gt \u201EHeute braten wir Jakobsmuscheln an.\u201C Jedes \u00FCberfl\u00FCssige Wort ist eine Gelegenheit zum Weiterscrollen.",
      "Schreibe, wie du am Pass sprichst. Was du einem Commis nicht sagen w\u00FCrdest, tippst du auch nicht.",
      "Lokalisieren statt \u00FCbersetzen. Eine Formulierung, die auf Englisch funktioniert, kann auf Deutsch verpuffen. \u00DCberarbeite die Idee f\u00FCr jeden Markt.",
      "Schlie\u00DFe mit einem klaren n\u00E4chsten Schritt: eine Frage, ein Tipp oder eine Einladung zum Ausprobieren.",
    ],
    id: [
      `${t}. Caption terkuat punya satu tugas: membuat penonton yang scroll berhenti dan membaca. Pelajaran ini membahas cara menulis untuk dapur \u2014 cepat, jelas, dengan suaramu sendiri.`,
      "Mulai dengan kata kerja. \u201CSear scallop\u201D mengalahkan \u201CHari ini kita akan menyear scallop.\u201D Setiap kata sia-sia adalah peluang untuk scroll.",
      "Tulis seperti kamu bicara di pass. Kalau tidak akan kamu ucapkan ke commis saat service, jangan ketik.",
      "Lokalkan, jangan terjemahkan. Frasa yang pas di English bisa hambar di German atau Bahasa. Olah ulang idenya untuk tiap pasar.",
      "Tutup dengan satu langkah jelas: pertanyaan, tip, atau ajakan mencoba.",
    ],
  };
  return sets[locale] || sets.en;
}

function _lvCards(lesson, locale) {
  const sets = {
    en: [
      { h: "1 \u00B7 Camera", b: "A phone on a stable mount beats an expensive camera held by hand. Lock it down before you cook." },
      { h: "2 \u00B7 Mic", b: "A clip-on lav mic cuts kitchen noise. Keep it 15\u201320cm from your mouth, slightly off to the side." },
      { h: "3 \u00B7 Tripod", b: "Anything that holds the phone steady at counter height works \u2014 a stack of boards, a sheet pan, a wall." },
      { h: "4 \u00B7 Light", b: "One window plus one warm bulb gives you a clean key light. Avoid overhead fluorescents alone." },
      { h: "5 \u00B7 Backup", b: "Charge to 100%, clear storage, and shoot a 10-second test before the real take. Reshoots cost service time." },
    ],
    de: [
      { h: "1 \u00B7 Kamera", b: "Ein Handy auf stabiler Halterung schl\u00E4gt eine teure Kamera in der Hand. Fixiere es, bevor du kochst." },
      { h: "2 \u00B7 Mikro", b: "Ein Ansteck-Mikro reduziert K\u00FCchenl\u00E4rm. Halte es 15\u201320 cm vom Mund, leicht seitlich." },
      { h: "3 \u00B7 Stativ", b: "Alles, was das Handy auf Thekenh\u00F6he ruhig h\u00E4lt, funktioniert \u2014 Brettstapel, Backblech, Wand." },
      { h: "4 \u00B7 Licht", b: "Ein Fenster plus eine warme Gl\u00FChbirne gibt ein sauberes Schl\u00FCssellicht." },
      { h: "5 \u00B7 Backup", b: "Auf 100% laden, Speicher leeren, 10-Sekunden-Test vor dem echten Take." },
    ],
    id: [
      { h: "1 \u00B7 Kamera", b: "HP di mount stabil mengalahkan kamera mahal yang dipegang tangan. Kunci dulu sebelum memasak." },
      { h: "2 \u00B7 Mic", b: "Mic clip-on memotong noise dapur. Jaga 15\u201320cm dari mulut, sedikit ke samping." },
      { h: "3 \u00B7 Tripod", b: "Apa pun yang menahan HP stabil setinggi counter berhasil \u2014 tumpukan talenan, loyang, dinding." },
      { h: "4 \u00B7 Cahaya", b: "Satu jendela plus satu lampu hangat memberi key light bersih." },
      { h: "5 \u00B7 Backup", b: "Isi 100%, kosongkan storage, rekam tes 10-detik sebelum take asli." },
    ],
  };
  const cards = sets[locale] || sets.en;
  return cards.slice(0, lesson.cards || 5);
}

function LessonViewer({ entry, mod, locale, profile, nextInfo, onClose, onAdvance }) {
  const lesson = entry.lesson;
  const type = lesson.type;

  // Back label = the lesson's immediate parent: its sub-module if it has one,
  // otherwise its module. So a lesson in 2.1 shows "Filming setup", not the module.
  const parentBackLabel = entry.subModule
    ? (entry.subModule.title[locale] || entry.subModule.title.en)
    : (mod ? (mod.title[locale] || mod.title.en) : (locale === "de" ? "Modul" : locale === "id" ? "Modul" : "Modules"));

  // Label for the advance button, based on what comes next.
  const _nextLabel = (() => {
    const ni = nextInfo || { kind: "lesson" };
    if (ni.kind === "module") {
      const modWord = locale === "de" ? "Modul" : locale === "id" ? "Modul" : "Module";
      return locale === "de" ? `Weiter zu ${modWord} ${ni.label}` : locale === "id" ? `Lanjut ke ${modWord} ${ni.label}` : `Continue to ${modWord} ${ni.label}`;
    }
    if (ni.kind === "submodule") {
      return locale === "de" ? `Weiter zu ${ni.label}` : locale === "id" ? `Lanjut ke ${ni.label}` : `Continue to ${ni.label}`;
    }
    if (ni.kind === "back") {
      return locale === "de" ? "Zur\u00FCck zum Modul" : locale === "id" ? "Kembali ke modul" : "Back to module";
    }
    return locale === "de" ? "N\u00E4chste Lektion" : locale === "id" ? "Pelajaran berikutnya" : "Next lesson";
  })();

  // ── VIDEO → reuse the real Player, driven in lessonMode ──
  if (type === "video") {
    const vmeta = (window.LESSON_TYPE_META || {}).video || {};
    const typeLab = (vmeta.label && (vmeta.label[locale] || vmeta.label.en)) || "Video";
    const partWord = locale === "de" ? "TEIL" : locale === "id" ? "BAGIAN" : "PART";
    const eyebrow = entry.subModule
      ? `${partWord} ${entry.subModule.num} · ${typeLab.toUpperCase()}`
      : typeLab.toUpperCase();
    return (
      <window.Player
        locale={locale}
        courseId="fundamentals"
        moduleIdx={4}
        profile={profile}
        lessonMode={{
          title: lesson.title,
          intro: mod ? mod.intro : null,
          backLabel: parentBackLabel,
          eyebrow: eyebrow,
          onComplete: () => { if (!window.useLessonProgress) return; window.markLessonDone(lesson.id); },
          onNext: () => { window.markLessonDone(lesson.id); onAdvance(entry, mod); },
          nextLabel: _nextLabel,
        }}
        onBack={onClose}
        onOpenBriefs={() => {}}
        onOpenModule={() => {}}
      />
    );
  }

  // ── NON-VIDEO → in-shell page reusing the player two-column layout ──
  return <NonVideoLesson entry={entry} mod={mod} locale={locale} profile={profile} nextLabel={_nextLabel} backLabel={parentBackLabel} onClose={onClose} onAdvance={onAdvance} />;
}

function NonVideoLesson({ entry, mod, locale, profile, nextLabel, backLabel, onClose, onAdvance }) {
  const lp = window.useLessonProgress();
  const lesson = entry.lesson;
  const type = lesson.type;
  const meta = (window.LESSON_TYPE_META || {})[type] || {};
  const alreadyDone = lp.isDone(lesson.id);
  const [completed, setCompleted] = useStateLv(alreadyDone);
  const [notes, setNotes] = useStateLv([]);
  const [noteDraft, setNoteDraft] = useStateLv("");
  const [confirmDel, setConfirmDel] = useStateLv(null); // index of note pending delete-confirmation

  const markDone = () => {
    if (!lp.isDone(lesson.id)) window.markLessonDone(lesson.id);
    setCompleted(true);
  };
  const addNote = () => { if (!noteDraft.trim()) return; setNotes(p => [...p, { text: noteDraft.trim() }]); setNoteDraft(""); };
  const removeNote = (i) => setNotes(p => p.filter((_, ix) => ix !== i));

  const s = {
    backTo: backLabel || (mod ? (mod.title[locale] || mod.title.en) : (locale === "de" ? "Modul" : locale === "id" ? "Modul" : "Module")),
    notes: locale === "de" ? "Notizen" : locale === "id" ? "Catatan" : "Notes",
    resources: locale === "de" ? "RESSOURCEN" : locale === "id" ? "SUMBER" : "RESOURCES",
    savedNotes: locale === "de" ? "GESPEICHERTE NOTIZEN" : locale === "id" ? "CATATAN TERSIMPAN" : "SAVED NOTES",
    addNote: locale === "de" ? "Notiz hinzuf\u00FCgen" : locale === "id" ? "Tambah catatan" : "Add a note",
    save: locale === "de" ? "Speichern" : locale === "id" ? "Simpan" : "Save",
    saved: locale === "de" ? "Gespeichert" : locale === "id" ? "Tersimpan" : "Saved",
    doneMsg: locale === "de" ? "Lektion abgeschlossen" : locale === "id" ? "Pelajaran selesai" : "Lesson complete",
    next: locale === "de" ? "N\u00E4chste Lektion" : locale === "id" ? "Pelajaran berikutnya" : "Next lesson",
    delTitle: locale === "de" ? "Notiz l\u00F6schen?" : locale === "id" ? "Hapus catatan?" : "Delete this note?",
    delBody: locale === "de" ? "Diese Aktion kann nicht r\u00FCckg\u00E4ngig gemacht werden." : locale === "id" ? "Tindakan ini tidak dapat dibatalkan." : "This can't be undone.",
    delConfirm: locale === "de" ? "L\u00F6schen" : locale === "id" ? "Hapus" : "Delete",
    delCancel: locale === "de" ? "Abbrechen" : locale === "id" ? "Batal" : "Cancel",
    eyebrow: (() => {
      const typeLab = (meta.label && (meta.label[locale] || meta.label.en)) || "";
      const partWord = locale === "de" ? "Teil" : locale === "id" ? "Bagian" : "Part";
      return entry.subModule ? `${partWord} ${entry.subModule.num} · ${typeLab}` : typeLab;
    })(),
  };

  return (
    <div className="page">
      {/* Breadcrumb (same as player) */}
      <div className="player-crumbs">
        <button className="link-btn" onClick={onClose}><Icon name="chevron-left" size={12} /> {s.backTo}</button>
      </div>

      <div className="player-grid">
        {/* LEFT — stage + meta + completion */}
        <div className="player-main">
          {type === "written" && <LvWrittenStage lesson={lesson} locale={locale} completed={completed} onComplete={markDone} />}
          {type === "graphic" && <LvGraphicStage lesson={lesson} locale={locale} completed={completed} onComplete={markDone} />}
          {type === "carousel" && <LvCarouselStage lesson={lesson} locale={locale} completed={completed} onComplete={markDone} />}

          {/* Title + intro + Save — same meta block as the video player */}
          <div className="player-meta">
            <span className="eyebrow player-meta-eyebrow">
              <Icon name={meta.icon} size={12} style={{ marginRight: 4, verticalAlign: "-1px" }} /> {s.eyebrow}
            </span>
            <div className="player-meta-title-row">
              <h2 className="player-title">{lesson.title[locale] || lesson.title.en}</h2>
              <div className="player-meta-actions">
                <window.SaveBtn kind="lesson" id={lesson.id} label={s.save} savedLabel={s.saved} />
              </div>
            </div>
            {mod && mod.intro && <p className="player-intro">{mod.intro[locale] || mod.intro.en}</p>}
          </div>

          {/* Completion bar */}
          <div className={"lv-complete-bar" + (completed ? " is-complete" : "")}>
            {completed ? (
              <>
                <span className="lv-complete-status"><Icon name="check" size={15} /> {s.doneMsg}</span>
                <button className="btn btn-primary" onClick={() => onAdvance(entry, mod)}>
                  {nextLabel || s.next} <Icon name="arrow-right" size={14} />
                </button>
              </>
            ) : (
              <span className="lv-complete-hint">
                {type === "written" && (locale === "de" ? "Bis zum Ende scrollen, um abzuschlie\u00DFen" : locale === "id" ? "Scroll ke bawah untuk menyelesaikan" : "Scroll to the end to complete")}
                {type === "carousel" && (locale === "de" ? "Alle Karten ansehen, um abzuschlie\u00DFen" : locale === "id" ? "Lihat semua kartu untuk menyelesaikan" : "View all cards to complete")}
                {type === "graphic" && (locale === "de" ? "Wird beim Ansehen abgeschlossen" : locale === "id" ? "Selesai saat dilihat" : "Completes on view")}
              </span>
            )}
          </div>
        </div>

        {/* RIGHT — Notes (NO chapters) + Resources, same structure as player */}
        <div className="player-side">
          <div className="player-side-card">
            <div className="cv-notes-head">
              <Icon name="edit-3" size={14} /> <span>{s.notes}</span>
            </div>
            <div className="side-content">
              <div className="notes-panel">
                <div className="note-input">
                  <Icon name="edit-3" size={13} style={{ color: "var(--smoke)", flexShrink: 0 }} />
                  <textarea value={noteDraft} onChange={e => setNoteDraft(e.target.value)} placeholder={s.addNote} rows={2} />
                  <button className="btn btn-primary btn-sm" onClick={addNote} disabled={!noteDraft.trim()}>
                    <Icon name="plus" size={12} /> {s.save}
                  </button>
                </div>
                <div className="note-saved-h">
                  <span className="eyebrow">{s.savedNotes}</span>
                  <span className="subtle">{notes.length}</span>
                </div>
                <div className="notes-list">
                  {notes.map((n, i) => (
                    <div key={i} className="note cv-note">
                      <div className="note-text">{n.text}</div>
                      <button className="note-x" onClick={() => setConfirmDel(i)} aria-label="Delete note"><Icon name="x" size={12} /></button>
                    </div>
                  ))}
                </div>
              </div>
            </div>
          </div>

          {/* Resources — same as the video player */}
          <div className="player-resources">
            <div className="player-resources-head">
              <span className="eyebrow">{s.resources}</span>
            </div>
            <div className="res-list">
              <ResRow icon="file-text" name={(lesson.title[locale] || lesson.title.en) + " \u2014 recap.pdf"} sub={locale === "de" ? "2 Seiten \u00B7 320 KB" : locale === "id" ? "2 halaman \u00B7 320 KB" : "2 pages \u00B7 320 KB"} />
              <ResRow icon="file-text" name={locale === "de" ? "Spickzettel.pdf" : locale === "id" ? "Contekan.pdf" : "Cheat-sheet.pdf"} sub={locale === "de" ? "1 Seite \u00B7 180 KB" : locale === "id" ? "1 halaman \u00B7 180 KB" : "1 page \u00B7 180 KB"} />
              <ResRow icon="external-link" name="UFS Future Menus 2026" sub={locale === "de" ? "Auszug" : locale === "id" ? "Cuplikan" : "Extract"} cta={locale === "de" ? "\u00D6ffnen" : locale === "id" ? "Buka" : "Open"} />
            </div>
          </div>
        </div>
      </div>

      {/* Delete-note confirmation */}
      {confirmDel !== null && (
        <div className="cv-confirm-overlay" onClick={() => setConfirmDel(null)}>
          <div className="cv-confirm" onClick={e => e.stopPropagation()} role="dialog" aria-modal="true">
            <div className="cv-confirm-ic"><Icon name="trash-2" size={20} /></div>
            <h3 className="cv-confirm-title">{s.delTitle}</h3>
            <p className="cv-confirm-body">{s.delBody}</p>
            <div className="cv-confirm-actions">
              <button className="btn btn-outline" onClick={() => setConfirmDel(null)}>{s.delCancel}</button>
              <button className="btn cv-confirm-del" onClick={() => { removeNote(confirmDel); setConfirmDel(null); }}>{s.delConfirm}</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ── WRITTEN STAGE — completes on scroll-to-bottom ──
function LvWrittenStage({ lesson, locale, completed, onComplete }) {
  const sentinel = useRefLv(null);
  useEffectLv(() => {
    if (completed) return;
    const el = sentinel.current;
    if (!el || !("IntersectionObserver" in window)) { onComplete(); return; }
    const io = new IntersectionObserver((entries) => {
      if (entries.some(e => e.isIntersecting)) { onComplete(); io.disconnect(); }
    }, { threshold: 1.0 });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  const paras = _lvWritten(lesson, locale);
  return (
    <div className="lv-stage lv-stage-written">
      <article className="lv-article">
        {paras.map((p, i) => <p key={i}>{p}</p>)}
        <div ref={sentinel} className="lv-article-sentinel" aria-hidden="true" />
      </article>
    </div>
  );
}

// ── GRAPHIC STAGE — completes on view ──
function LvGraphicStage({ lesson, locale, completed, onComplete }) {
  useEffectLv(() => {
    if (completed) return;
    const id = setTimeout(onComplete, 1200);
    return () => clearTimeout(id);
  }, []);
  return (
    <div className="lv-stage lv-stage-graphic">
      <div className="lv-graphic-frame">
        <Icon name="image" size={44} />
        <div className="lv-graphic-cap">{lesson.title[locale] || lesson.title.en}</div>
        <div className="lv-graphic-note">{locale === "de" ? "Infografik" : locale === "id" ? "Infografik" : "Infographic"}</div>
      </div>
    </div>
  );
}

// ── CAROUSEL STAGE — completes when all cards seen ──
function LvCarouselStage({ lesson, locale, completed, onComplete }) {
  const cards = _lvCards(lesson, locale);
  const [idx, setIdx] = useStateLv(0);
  const [seen, setSeen] = useStateLv(() => new Set(completed ? cards.map((_, i) => i) : [0]));
  useEffectLv(() => {
    setSeen(prev => {
      if (prev.has(idx)) return prev;
      const nx = new Set(prev); nx.add(idx);
      if (nx.size === cards.length && !completed) onComplete();
      return nx;
    });
  }, [idx]);
  const atStart = idx === 0, atEnd = idx === cards.length - 1;
  return (
    <div className="lv-stage lv-stage-carousel">
      <div className="lv-carousel-card">
        <div className="lv-carousel-card-h">{cards[idx].h}</div>
        <div className="lv-carousel-card-b">{cards[idx].b}</div>
      </div>
      <div className="lv-carousel-controls">
        <button className="lv-carousel-arrow" disabled={atStart} onClick={() => setIdx(i => Math.max(0, i - 1))} aria-label="Previous"><Icon name="chevron-left" size={18} /></button>
        <div className="lv-carousel-dots">
          {cards.map((_, i) => (
            <button key={i} className={"lv-carousel-dot" + (i === idx ? " active" : "") + (seen.has(i) ? " seen" : "")} onClick={() => setIdx(i)} aria-label={`Card ${i + 1}`} />
          ))}
        </div>
        <button className="lv-carousel-arrow" disabled={atEnd} onClick={() => setIdx(i => Math.min(cards.length - 1, i + 1))} aria-label="Next"><Icon name="chevron-right" size={18} /></button>
      </div>
      <div className="lv-carousel-count">{locale === "de" ? `Karte ${idx + 1} von ${cards.length}` : locale === "id" ? `Kartu ${idx + 1} dari ${cards.length}` : `Card ${idx + 1} of ${cards.length}`}</div>
    </div>
  );
}

window.LessonViewer = LessonViewer;
