/* ============================================================
   Learn.jsx — личный кабинет обучения (плеер курса)
   · дерево программы (модули → уроки) с отметками пройденного
   · видео-плеер (файл/MP4 или встраиваемый YouTube/Vimeo)
   · прогресс и «Продолжить обучение» с места остановки
   ============================================================ */

function LearnGate() {
  const { t } = useT();
  const [open, setOpen] = React.useState(false);
  return (
    <React.Fragment>
      <div style={{ minHeight: "70vh", display: "grid", placeItems: "center", padding: "120px 24px 60px" }}>
        <div style={{ textAlign: "center", maxWidth: 440 }}>
          <div style={{ width: 56, height: 56, borderRadius: 999, border: "1px solid var(--hairline-2)",
            display: "grid", placeItems: "center", margin: "0 auto 24px" }}>
            <Icon name="lock" style={{ width: 22, height: 22, strokeWidth: 1.6, color: "var(--ink)" }} />
          </div>
          <h1 style={{ fontFamily: "var(--font-display)", fontWeight: 300, fontSize: "clamp(26px,3.4vw,36px)",
            letterSpacing: "-0.01em", color: "var(--ink)", margin: "0 0 24px" }}>{t("learn.gate")}</h1>
          <Pill variant="primary" icon="arrow" onClick={() => setOpen(true)}>{t("learn.gateBtn")}</Pill>
        </div>
      </div>
      <AuthModal open={open} onClose={() => setOpen(false)} initialMode="login" onAuthed={() => setOpen(false)} />
    </React.Fragment>
  );
}

function LessonRow({ lesson, active, done, onClick }) {
  return (
    <button onClick={onClick} style={{ width: "100%", display: "grid", gridTemplateColumns: "22px 1fr",
      gap: 12, alignItems: "start", textAlign: "left", padding: "12px 12px", borderRadius: 8, cursor: "pointer",
      border: "none", background: active ? "var(--surface-2)" : "transparent",
      transition: "background var(--dur) var(--ease)" }}>
      <span style={{ width: 20, height: 20, marginTop: 1, borderRadius: 999, flexShrink: 0, display: "grid",
        placeItems: "center", background: done ? "var(--ink)" : "transparent",
        border: `1px solid ${done ? "var(--ink)" : "var(--hairline-2)"}` }}>
        {done && <Icon name="check" style={{ width: 12, height: 12, strokeWidth: 2.4, color: "var(--paper-on-ink)" }} />}
      </span>
      <span style={{ fontFamily: "var(--font-sans)", fontSize: 14, lineHeight: 1.4,
        color: active ? "var(--ink)" : "var(--ink-2)", fontWeight: active ? 600 : 400 }}>{lesson.title}</span>
    </button>
  );
}

function VideoPane({ lesson, phone, onCompleted }) {
  const { t } = useT();
  const vidRef = React.useRef(null);
  const lastSave = React.useRef(0);
  const v = parseVideo(lesson.video);

  // при смене урока — восстановить позицию для файла-видео
  React.useEffect(() => {
    if (v.type !== "file") return;
    const el = vidRef.current; if (!el) return;
    const saved = (userProgress(phone)[lesson.id] || {}).t || 0;
    const onMeta = () => { if (saved > 0 && saved < (el.duration || 1e9)) { try { el.currentTime = saved; } catch (e) {} } };
    el.addEventListener("loadedmetadata", onMeta);
    return () => el.removeEventListener("loadedmetadata", onMeta);
  }, [lesson.id, v.type, phone]);

  const onTime = () => {
    const el = vidRef.current; if (!el) return;
    const now = Date.now();
    if (now - lastSave.current > 4000) {          // сохраняем позицию не чаще раза в 4с
      lastSave.current = now;
      setLessonProgress(phone, lesson.id, { t: Math.floor(el.currentTime) });
    }
  };
  const onEnded = () => { setLessonProgress(phone, lesson.id, { completed: true, t: 0 }); onCompleted(); };

  if (v.type === "none") {
    return (
      <div style={{ aspectRatio: "16 / 9", borderRadius: 12, background: "var(--surface)",
        border: "1px dashed var(--hairline-2)", display: "grid", placeItems: "center" }}>
        <span style={{ fontFamily: "var(--font-sans)", fontSize: 14.5, color: "var(--ink-3)" }}>{t("learn.noVideo")}</span>
      </div>
    );
  }
  if (v.type === "embed") {
    return (
      <div style={{ aspectRatio: "16 / 9", borderRadius: 12, overflow: "hidden", background: "#000" }}>
        <iframe src={v.src} title={lesson.title} allow="fullscreen; picture-in-picture" allowFullScreen
          style={{ width: "100%", height: "100%", border: "none" }} />
      </div>
    );
  }
  return (
    <video ref={vidRef} src={v.src} controls onTimeUpdate={onTime} onEnded={onEnded}
      style={{ width: "100%", aspectRatio: "16 / 9", borderRadius: 12, background: "#000", display: "block" }} />
  );
}

/* карточка доступа к закрытому Telegram-каналу — только для купивших */
function SecretAccessCard() {
  const { t } = useT();
  // персональная одноразовая ссылка на закрытый канал — с бэкенда (по доступу).
  // Фолбэк на общую ссылку из links.jsx, если сервера нет.
  const [st, setSt] = React.useState({ loading: true });
  React.useEffect(() => {
    let alive = true;
    const fallback = () => { if (alive) setSt({ loading: false, fallback: true }); };
    if (typeof backendUp === "function" && typeof getToken === "function" && getToken()) {
      backendUp().then((up) => {
        if (!up) return fallback();
        apiGet("/api/channel/link").then((r) => { if (alive) setSt({ loading: false, ...r }); }).catch(fallback);
      });
    } else fallback();
    return () => { alive = false; };
  }, []);

  const staticUrl = (window.CHANNELS && window.CHANNELS.telegramClosed) || "";
  const url = st.link || (st.fallback ? staticUrl : "");
  const ready = !!url && url.indexOf("PLACEHOLDER") === -1;
  const soon = !ready && st.configured === false;   // доступ есть, но канал ещё не настроен автором

  const inner = (
    <React.Fragment>
      <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 10 }}>
        <span style={{ width: 30, height: 30, borderRadius: 999, background: "#229ED9", display: "grid", placeItems: "center", flexShrink: 0 }}>
          <Icon name="send" style={{ width: 15, height: 15, strokeWidth: 1.8, color: "#fff" }} />
        </span>
        <span style={{ fontFamily: "var(--font-sans)", fontWeight: 600, fontSize: 14, color: "var(--paper-on-ink)" }}>{t("learn.secretTitle")}</span>
      </div>
      <p style={{ fontFamily: "var(--font-sans)", fontSize: 13, lineHeight: 1.5, color: "var(--ink-on-ink-2)", margin: "0 0 14px" }}>
        {ready ? "Персональная ссылка для входа в закрытый канал. Не передавайте её — она одноразовая." : t("learn.secretText")}
      </p>
      <span style={{ display: "inline-flex", alignItems: "center", gap: 8, fontFamily: "var(--font-sans)", fontWeight: 600,
        fontSize: 11, letterSpacing: "0.14em", textTransform: "uppercase", color: ready ? "var(--paper-on-ink)" : "var(--ink-on-ink-2)" }}>
        {st.loading ? "…" : ready ? "Вступить в канал" : soon ? "Скоро" : t("learn.secretSoon")}
        {ready && <Icon name="arrow-up-right" style={{ width: 13, height: 13, strokeWidth: 1.8 }} />}
      </span>
    </React.Fragment>
  );
  const box = { display: "block", textDecoration: "none", marginBottom: 22, padding: "18px 18px",
    borderRadius: 12, background: "var(--ink)" };
  return ready
    ? <a href={url} target="_blank" rel="noopener noreferrer" style={box}>{inner}</a>
    : <div style={box}>{inner}</div>;
}

function LearnPage() {
  const { t } = useT();
  const { phone, user } = useAuth();
  React.useEffect(() => { if (window.lucide) lucide.createIcons(); });

  const [cur, setCur] = React.useState(loadCurriculum);
  const flat = React.useMemo(() => flatLessons(cur), [cur]);
  const [tick, setTick] = React.useState(0);                 // форсируем перерисовку прогресса
  const [currentId, setCurrentId] = React.useState(() => (phone && lastLessonId(phone)) || (flat[0] && flat[0].id));

  // программа — с сервера (общая для всех), если он доступен
  React.useEffect(() => {
    let alive = true;
    if (window.syncCurriculumFromServer) syncCurriculumFromServer().then((c) => { if (alive && c) setCur(c); });
    return () => { alive = false; };
  }, []);

  // прогресс — с сервера в кэш, затем встаём на последний открытый урок
  React.useEffect(() => {
    if (phone && window.syncProgressFromServer) {
      syncProgressFromServer(phone).then(() => {
        const last = lastLessonId(phone);
        if (last) setCurrentId(last);
        setTick((n) => n + 1);
      });
    }
  }, [phone]);

  // фиксируем последний открытый урок как точку возврата («Продолжить»)
  React.useEffect(() => { if (phone && currentId) setLessonProgress(phone, currentId, {}); }, [currentId, phone]);

  if (!phone) return (<React.Fragment><SubHeader /><LearnGate /><SubFooter /></React.Fragment>);
  if (!flat.length) {
    return (<React.Fragment><SubHeader />
      <div style={{ minHeight: "60vh", display: "grid", placeItems: "center", padding: 40 }}>
        <p style={{ fontFamily: "var(--font-sans)", color: "var(--ink-2)" }}>{t("learn.empty")}</p>
      </div><SubFooter /></React.Fragment>);
  }

  const hasPurchase = !!(user && (user.purchased || []).length);
  const prog = userProgress(phone);
  const done = completedCount(phone);
  const total = flat.length;
  const pct = Math.round((done / total) * 100);
  const current = flat.find((l) => l.id === currentId) || flat[0];
  const idx = flat.findIndex((l) => l.id === current.id);

  const go = (id) => { setCurrentId(id); window.scrollTo({ top: 0, behavior: "smooth" }); };
  const resume = () => { const last = lastLessonId(phone); if (last) go(last); };
  const markDone = () => { setLessonProgress(phone, current.id, { completed: true }); setTick((n) => n + 1); };
  const isDone = (id) => !!(userProgress(phone)[id] || {}).completed;

  const wrap = { maxWidth: 1200, margin: "0 auto", padding: "0 28px" };

  return (
    <React.Fragment>
      <SubHeader cta={t("learn.title")} ctaHref="learn.html" />

      <section style={{ paddingTop: 108, paddingBottom: 24, background: "var(--surface)" }}>
        <div style={wrap}>
          <div style={{ marginBottom: 18 }}><SubCrumb here={t("learn.title")} /></div>
          <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 20, flexWrap: "wrap" }}>
            <div>
              <h1 style={{ fontFamily: "var(--font-display)", fontWeight: 300, fontSize: "clamp(28px,4vw,48px)",
                letterSpacing: "-0.012em", color: "var(--ink)", margin: 0 }}>{t("learn.heading")}</h1>
              <p style={{ fontFamily: "var(--font-sans)", fontSize: 14, color: "var(--ink-2)", margin: "10px 0 0" }}>
                {done} {t("learn.of")} {total} {t("learn.lessonsDone")} · {pct}%
              </p>
            </div>
            <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
              {lastLessonId(phone) && <Pill variant="primary" icon="arrow" onClick={resume}>{t("learn.resume")}</Pill>}
            </div>
          </div>
          {/* прогресс-бар */}
          <div style={{ marginTop: 20, height: 4, borderRadius: 4, background: "var(--hairline-2)", overflow: "hidden" }}>
            <div style={{ width: pct + "%", height: "100%", background: "var(--ink)",
              transition: "width var(--dur-slow) var(--ease)" }} />
          </div>
        </div>
      </section>

      <section style={{ background: "var(--paper)", padding: "clamp(28px,4vw,48px) 0 80px" }}>
        <div style={{ ...wrap, display: "grid", gridTemplateColumns: "320px 1fr", gap: "clamp(24px,3vw,44px)",
          alignItems: "start" }} className="learn-grid">

          {/* ---- программа (сайдбар) ---- */}
          <aside style={{ position: "sticky", top: 92 }} className="learn-side">
            {hasPurchase && <SecretAccessCard />}
            <div style={{ marginBottom: 14 }}><Label>{t("learn.program")}</Label></div>
            <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
              {cur.map((m) => (
                <div key={m.id}>
                  <div style={{ fontFamily: "var(--font-sans)", fontWeight: 600, fontSize: 13,
                    letterSpacing: "0.02em", color: "var(--ink)", margin: "0 0 6px", padding: "0 12px" }}>{m.title}</div>
                  {m.lessons.map((l) => (
                    <LessonRow key={l.id} lesson={l} active={l.id === current.id} done={isDone(l.id)}
                      onClick={() => go(l.id)} />
                  ))}
                </div>
              ))}
            </div>
          </aside>

          {/* ---- плеер + описание ---- */}
          <div>
            <div style={{ marginBottom: 16 }}>
              <Label>{current.moduleTitle} · {t("learn.lesson")} {idx + 1} {t("learn.of")} {total}</Label>
            </div>
            <VideoPane key={current.id} lesson={current} phone={phone} onCompleted={() => setTick((n) => n + 1)} />

            <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 300, fontSize: "clamp(22px,2.6vw,32px)",
              letterSpacing: "-0.01em", color: "var(--ink)", margin: "24px 0 0" }}>{current.title}</h2>
            {current.desc && <p style={{ fontFamily: "var(--font-sans)", fontSize: 15.5, lineHeight: 1.65,
              color: "var(--ink-2)", margin: "14px 0 0", maxWidth: 640 }}>{current.desc}</p>}

            <div style={{ display: "flex", gap: 12, flexWrap: "wrap", marginTop: 28,
              paddingTop: 24, borderTop: "1px solid var(--hairline)" }}>
              <Pill variant="ghost" onClick={() => { if (idx > 0) go(flat[idx - 1].id); }}
                style={{ opacity: idx > 0 ? 1 : 0.4, pointerEvents: idx > 0 ? "auto" : "none" }}>{t("learn.prev")}</Pill>
              <Pill variant={isDone(current.id) ? "secondary" : "primary"} icon={isDone(current.id) ? undefined : "plus"}
                onClick={markDone}>{isDone(current.id) ? t("learn.done") : t("learn.markDone")}</Pill>
              <Pill variant="primary" icon="arrow" onClick={() => { if (idx < total - 1) go(flat[idx + 1].id); }}
                style={{ opacity: idx < total - 1 ? 1 : 0.4, pointerEvents: idx < total - 1 ? "auto" : "none" }}>{t("learn.next")}</Pill>
            </div>
          </div>
        </div>
      </section>

      <SubFooter />
    </React.Fragment>
  );
}

Object.assign(window, { LearnPage });
