/* ============================================================
   APP — menyatukan foto, konsep interaksi, dan panel.
   Setelan tampilan dikunci permanen (panel Tweaks sudah dihapus).
   Ubah nilai di THEME ini kalau mau ganti tema situs.
   ============================================================ */
const THEME = {
  dark: true,          // mode gelap
  accent: "#c6f432",   // warna aksen (lime)
  motion: true,        // animasi aktif
  videoBg: false,      // video latar (nonaktif)
  videoAuto: true,
  videoDark: 0.62,
  cvUrl: "",           // kosong → pakai link CV dari cv-data.js
};

/* Gabungkan konten dari Firestore (site/content) di atas cv-data.js.
   Field yang tidak ada di Firestore otomatis pakai nilai cv-data.js. */
function mergeContent(base, c) {
  if (!c) return base;
  const out = { ...base };
  ["name", "location", "tagline", "experience", "birth", "brandRoles", "typeWords", "tools"].forEach((k) => {
    if (c[k] !== undefined && c[k] !== null) out[k] = c[k];
  });
  out.defaults = { ...(base.defaults || {}), ...(c.defaults || {}) };
  out.sections = { ...(base.sections || {}), ...(c.sections || {}) };
  return out;
}

/* Baca dokumen konten secara realtime; null = belum ada / offline. */
function useContent() {
  const [content, setContent] = useState(null);
  useEffect(() => {
    if (!window.FB || !window.FB.db) return;
    const unsub = window.FB.db.collection("site").doc("content").onSnapshot(
      (snap) => { setContent(snap.exists ? snap.data() : null); },
      (err) => { console.error("content snapshot:", err); }
    );
    return () => unsub();
  }, []);
  return content;
}

function App() {
  const staticData = window.CV_DATA;
  // Konten teks live dari Firestore (site/content); null → pakai cv-data.js.
  const content = useContent();
  // Portofolio realtime dari Firestore; kalau kosong/offline → pakai seed di cv-data.js.
  const live = usePortfolio();
  const staticPf = staticData.sections.portofolio || {};
  const useSeed = !live.loaded || live.empty;
  const liveShorts = useSeed ? (staticPf.shorts || []) : live.shorts;
  const liveFeatured = useSeed ? (staticPf.featured || []) : live.featured;
  const data = React.useMemo(() => {
    const base = mergeContent(staticData, content);
    const pf = base.sections.portofolio || {};
    return {
      ...base,
      sections: { ...base.sections, portofolio: { ...pf, shorts: liveShorts, featured: liveFeatured } },
    };
  }, [staticData, content, liveShorts, liveFeatured]);

  const defs = data.defaults || {};
  const t = THEME;
  const [active, setActive] = useState(null);

  const accent = t.accent;
  const motion = t.motion !== false;

  const pick = useCallback((id) => {
    setActive((cur) => (cur === id ? null : id));
    setPfWide(false); // buka panel selalu mulai dari mode biasa
  }, []);

  // Lightbox portofolio — { kind: "shorts"|"featured", index } | null
  const pf = data.sections.portofolio || {};
  const pfShorts = pf.shorts || [];
  const pfFeatured = pf.featured || [];
  const [lightbox, setLightbox] = useState(null);
  const [pfWide, setPfWide] = useState(false);
  const lbList = lightbox ? (lightbox.kind === "featured" ? pfFeatured : pfShorts) : [];
  const navVideo = useCallback((dir) => {
    setLightbox((cur) => {
      if (!cur) return cur;
      const list = cur.kind === "featured" ? pfFeatured : pfShorts;
      if (!list.length) return cur;
      return { kind: cur.kind, index: (cur.index + dir + list.length) % list.length };
    });
  }, [pfShorts.length, pfFeatured.length]);

  // Koreografi intro: foto muncul di tengah → jeda → geser kiri + menu masuk.
  const [revealed, setRevealed] = useState(false);
  useEffect(() => {
    const id = setTimeout(() => setRevealed(true), 680);
    return () => clearTimeout(id);
  }, []);

  return (
    <div
      className={"app" + (revealed ? " revealed" : "")}
      data-mode={t.dark ? "dark" : "light"}
      data-concept="menu"
      style={{ "--accent": accent }}
    >
      <VideoBg enabled={!!t.videoBg} darkness={t.videoDark} autoData={t.videoAuto !== false} />
      <header className="topbar">
        <div className="brand">
          <span className="brand-dot" style={{ background: accent }} />
          <span className="brand-name">IAN SEPTIAN</span>
          <span className="brand-sep">/</span>
          <span className="brand-role"><RotatingRole words={data.brandRoles} motion={motion} /></span>
        </div>
      </header>

      <main className={"stage"}>
        <BigType words={data.typeWords} motion={motion} />

        <div className="comp-wrap">
          <div className="comp">
            <PhotoSlot accent={accent} styleMode="cutout" defaultSrc={defs.photo} />
          </div>

          <FloatingMenu data={data} accent={accent} active={active} onPick={pick} />
        </div>

        <div className="hero-foot">
          <div className="foot-loc">
            <svg className="foot-pin" viewBox="0 0 24 24" fill="none" stroke={accent}
              strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M12 21s7-5.6 7-11a7 7 0 1 0-14 0c0 5.4 7 11 7 11Z" />
              <circle cx="12" cy="10" r="2.5" />
            </svg>
            {data.location}
          </div>
          <div className="foot-hint">
            <CvDownload accent={accent} url={t.cvUrl || defs.cvUrl} defaultPreview={defs.cvPreview} />
          </div>
        </div>
      </main>

      <InfoPanel id={active} data={data} accent={accent} onClose={() => setActive(null)}
        onPlayVideo={(kind, index) => setLightbox({ kind, index })}
        expanded={pfWide} onToggleExpand={() => setPfWide((v) => !v)} />
      <VideoLightbox state={lightbox ? lightbox.index : null} videos={lbList}
        land={lightbox ? lightbox.kind === "featured" : false} accent={accent}
        onClose={() => setLightbox(null)} onNav={navVideo} />

      <AdminGate accent={accent} />
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
