/* ── Biblioteca metodologica - vizual Windows Explorer (spec 24.07, agent 002) ──────────
   3 niveluri: credinte -> tipuri de material -> materialele. 4 trepte size-driven
   (Extra Large / Large / Medium / Details), geometrie IDENTICA platformei: celula fixa
   240 / 160 / 104 px, reflow auto-fill; coperta PDF la raport A4 cu numele la hover.
   Materialele: PDF (tab nou, viewer nativ) · Excel (download-only) · audio (modal cu player).
   Datele: biblio_data.js (window.PRP_BIBLIO), generat de biblioteca/build_biblioteca.py -
   scheletul 7x5 exista chiar fara documente (structura e produsul, cerinta Marian).
   Iconita PDF = fisierul oficial din platforma (public/file-icons/pdf.webp), inline base64;
   XLS si AUDIO = sistemul „Solid" al platformei (DOC_STYLE din type-icon.tsx). */

const IcBiblio = (p) => (
  <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor"
    strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}>
    <path d="M3 6.8A1.8 1.8 0 0 1 4.8 5h3.9l1.6 2.1h8.9A1.8 1.8 0 0 1 21 8.9v8.3A1.8 1.8 0 0 1 19.2 19H4.8A1.8 1.8 0 0 1 3 17.2z" />
  </svg>
);
window.IcBiblio = IcBiblio;

const BIB_DATE = () => window.PRP_BIBLIO || { prefix: "PENDING", foldere: [] };
const BIB_TILE_W = { xl: "240px", large: "160px", medium: "104px", details: "160px" };

/* store.biblio = { view: "xl"|"large"|"medium"|"details", deschise: { [idDoc]: "YYYY-MM-DD" } } */
function bibStarea(store) {
  const b = store.biblio || {};
  const v = ["xl", "large", "medium", "details"].includes(b.view) ? b.view : "large";
  return { view: v, deschise: b.deschise || {} };
}

/* folderul galben Windows 11 - acelasi desen ca fisierul ales de Marian pentru platforma:
   clapa aurie stanga-sus, dunga alba de accent, corp lucios cu gradient */
function BibFolder({ w }) {
  return (
    <svg viewBox="0 0 48 40" style={{ width: w || "86%" }} aria-hidden>
      <defs>
        <linearGradient id="bibf1" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor="#ffd873" /><stop offset="1" stopColor="#efa829" />
        </linearGradient>
        <linearGradient id="bibf2" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor="#ffcb52" /><stop offset="1" stopColor="#e7961b" />
        </linearGradient>
      </defs>
      <path d="M2 8a3 3 0 0 1 3-3h11l4 4H2z" fill="url(#bibf2)" />
      <path d="M2 9.5h44a2 2 0 0 1 2 2v23a3 3 0 0 1-3 3H5a3 3 0 0 1-3-3z" fill="url(#bibf1)" />
      <path d="M4.5 11.5h39v2h-39z" fill="#fff" opacity=".5" />
    </svg>
  );
}

/* foaie „Solid" ca in platforma: corp colorat, colt pliat deschis, glyph + eticheta albe */
function BibFoaie({ culoare, fold, eticheta, glyph, w }) {
  return (
    <svg viewBox="0 0 72 92" style={{ width: w || "70%" }} aria-hidden>
      <path d="M6 4h40l20 20v64H6z" fill={culoare} />
      <path d="M46 4l20 20H46z" fill={fold} />
      {glyph}
      <text x="36" y="82" textAnchor="middle" fill="#fff" fontSize="13" fontWeight="700"
        fontFamily="inherit" letterSpacing=".5">{eticheta}</text>
    </svg>
  );
}
const BibIcXls = ({ w }) => (
  <BibFoaie w={w} culoare="#217346" fold="#7cc79b" eticheta="XLS" glyph={
    <g fill="#fff" opacity=".95">
      <rect x="21" y="36" width="13" height="9" rx="1.5" /><rect x="37" y="36" width="13" height="9" rx="1.5" />
      <rect x="21" y="48" width="13" height="9" rx="1.5" /><rect x="37" y="48" width="13" height="9" rx="1.5" />
    </g>} />
);
const BibIcAudio = ({ w }) => (
  <BibFoaie w={w} culoare="#0D9488" fold="#5eded3" eticheta="AUDIO" glyph={
    <g fill="none" stroke="#fff" strokeWidth="4" strokeLinecap="round">
      <path d="M23 46v6" /><path d="M30 40v18" /><path d="M37 34v30" /><path d="M44 43v12" />
    </g>} />
);
/* PDF: iconita oficiala Adobe Acrobat - acelasi fisier ca in platforma (pdf.webp), inline */
const BibIcPdf = ({ w }) => (
  <img src={window.BIB_IC_PDF_URI} alt="" aria-hidden style={{ width: w || "62%", display: "block" }} />
);

function bibIconita(fel, w) {
  if (fel === "xlsx") return <BibIcXls w={w} />;
  if (fel === "audio") return <BibIcAudio w={w} />;
  return <BibIcPdf w={w} />;
}
const BIB_FEL_NUME = { pdf: "PDF", xlsx: "Excel", audio: "Audio" };

function bibMeta(d) {
  if (d.fel === "pdf") return d.pagini ? d.pagini + (d.pagini === 1 ? " pagină" : " pagini") : "-";
  if (d.fel === "xlsx") return d.foi ? d.foi + (d.foi === 1 ? " foaie" : " foi") : "-";
  return d.durata || "-";
}

/* comutatorul celor 4 trepte - aceleasi etichete si ordine ca in platforma */
function BibViewSwitch({ view, setView }) {
  const M = [["xl", "Extra Large"], ["large", "Large"], ["medium", "Medium"], ["details", "Details"]];
  return (
    <div className="mod-tabs" role="tablist" aria-label="Mod de vizualizare">
      {M.map(([k, et]) => (
        <button key={k} role="tab" aria-selected={view === k} title={et}
          className={"mod-tab" + (view === k ? " activ" : "")}
          onClick={() => setView(k)}>{et}</button>
      ))}
    </div>
  );
}

/* breadcrumb: Biblioteca / <credinta> / <tip> */
function BibNav({ nav, setNav }) {
  const D = BIB_DATE();
  const f = D.foldere.find((x) => x.slug === nav.folder);
  const t = f && f.tipuri.find((x) => x.tip === nav.tip);
  return (
    <div className="bib-crumb">
      <button className={!f ? "aici" : ""} onClick={() => setNav({ folder: null, tip: null })}>Biblioteca</button>
      {f && (
        <React.Fragment>
          <span>/</span>
          <button className={!t ? "aici" : ""} onClick={() => setNav({ folder: f.slug, tip: null })}>{f.nume}</button>
        </React.Fragment>
      )}
      {t && <React.Fragment><span>/</span><button className="aici">{t.nume}</button></React.Fragment>}
    </div>
  );
}

/* ── nivelul 3: materialele unui subfolder ── */
function BibMateriale({ documente, view, deschise, onDeschide }) {
  if (!documente.length) {
    return (
      <div className="panel empty">
        <div className="empty-title">Încă nu sunt materiale aici</div>
        <div className="small" style={{ maxWidth: 470 }}>
          Materialele acestei secțiuni se adaugă imediat ce sosesc de la Dr. Petre - structura
          îi așteaptă deja.
        </div>
      </div>
    );
  }
  const badge = (d) => deschise[d.id]
    ? <span className="bib-badge ok" title={"Deschis " + deschise[d.id]}>✓</span>
    : <span className="bib-badge nou" title="Nedeschis">!</span>;

  if (view === "details") {
    return (
      <div className="panel" style={{ overflowX: "auto" }}>
        <table className="bib-tbl">
          <thead>
            <tr><th>Material</th><th>Tip</th><th className="num">Foi / Durată</th><th>Stare</th></tr>
          </thead>
          <tbody>
            {documente.map((d) => (
              <React.Fragment key={d.id}>
                <tr className="clicabil" onClick={() => onDeschide(d)}>
                  <td>
                    <span className="bib-nume-cell">
                      <span className="mic">{bibIconita(d.fel, "100%")}</span>
                      {d.titlu}
                    </span>
                  </td>
                  <td>{BIB_FEL_NUME[d.fel]}</td>
                  <td className="num">{bibMeta(d)}</td>
                  <td>{deschise[d.id]
                    ? <span className="bib-pill ok">deschis</span>
                    : <span className="bib-pill nou">nedeschis</span>}</td>
                </tr>
                {d.fel === "audio" && (
                  <tr className="bib-audio-rand">
                    <td colSpan="4">
                      <audio controls preload="metadata" src={d.url === "PENDING" ? undefined : d.url} />
                    </td>
                  </tr>
                )}
              </React.Fragment>
            ))}
          </tbody>
        </table>
      </div>
    );
  }

  const cuCoperta = (d) => d.fel === "pdf" && d.coperta && (view === "xl" || view === "large");
  return (
    /* grila sta in ACELASI bloc alb ca tabelul Details (cerinta Marian 24.07: „details are bloc
       in jurul folderelor, trebuie sa avem unul identic si pentru medium, large...") */
    <div className="panel bib-panel">
    <div className="bib-grid" style={{ "--bib-w": BIB_TILE_W[view] }}>
      {documente.map((d) => (
        <button key={d.id} className="bib-tile" onClick={() => onDeschide(d)} title={d.titlu}
          aria-label={d.titlu + " - " + BIB_FEL_NUME[d.fel] + (deschise[d.id] ? ", deschis" : ", nedeschis")}>
          {cuCoperta(d) ? (
            <span className="bib-cover">
              <img src={d.coperta} alt="" loading="lazy" />
              {badge(d)}
              <span className="bib-cover-nume">{d.titlu}</span>
            </span>
          ) : (
            <React.Fragment>
              <span className="bib-icon">
                {bibIconita(d.fel)}
                {badge(d)}
              </span>
              <span className="bib-tile-nume">{d.titlu}</span>
            </React.Fragment>
          )}
        </button>
      ))}
    </div>
    </div>
  );
}

/* ── view-ul principal: rutare pe 3 niveluri, hash + history real ── */
function BibliotecaView({ store, set }) {
  const st = bibStarea(store);
  const dinHash = () => {
    const m = (location.hash || "").match(/^#biblioteca(?:\/([a-z-]+))?(?:\/([a-z]+))?$/);
    if (!m) return { folder: null, tip: null };
    return { folder: m[1] || null, tip: m[1] ? (m[2] || null) : null };
  };
  const [nav, setNavRaw] = React.useState(dinHash);
  const [audioActiv, setAudioActiv] = React.useState(null);
  const [eroare, setEroare] = React.useState(null);

  const setNav = (n) => {
    setNavRaw(n);
    setEroare(null);
    try {
      const h = "#biblioteca" + (n.folder ? "/" + n.folder + (n.tip ? "/" + n.tip : "") : "");
      history.pushState({ view: "biblioteca", bibNav: n }, "", h);
    } catch (e) { /* file:// restrictiv - navigarea ramane in state local */ }
  };
  React.useEffect(() => {
    const onPop = (e) => {
      if (e.state && e.state.bibNav) setNavRaw(e.state.bibNav);
      else if (e.state && e.state.view === "biblioteca") setNavRaw({ folder: null, tip: null });
    };
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, []);
  React.useEffect(() => {
    if (!audioActiv) return;
    const onKey = (e) => { if (e.key === "Escape") setAudioActiv(null); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [audioActiv]);

  const setView = (v) => set((s) => {
    const b = bibStarea(s);
    return { ...s, biblio: { ...s.biblio, view: v, deschise: b.deschise } };
  });
  const marcheaza = (id) => set((s) => {
    const b = bibStarea(s);
    const azi = window.PRP_UTIL ? window.PRP_UTIL.fmtISO(new Date())
      : new Date().toISOString().slice(0, 10);
    return { ...s, biblio: { ...s.biblio, view: b.view, deschise: { ...b.deschise, [id]: azi } } };
  });
  /* „deschis" se marcheaza DUPA ce materialul chiar s-a deschis: daca browserul blocheaza
     fereastra noua, badge-ul verde ar minti (audit 25.07) */
  const deschide = (d) => {
    if (!d.url || d.url === "PENDING") { setEroare({ ...d, motiv: "link" }); return; }
    if (d.fel === "audio") { setAudioActiv(d); marcheaza(d.id); return; }
    if (d.fel === "xlsx") {
      const a = document.createElement("a");
      a.href = d.url; a.download = d.fisier || "";
      document.body.appendChild(a); a.click(); a.remove();
      marcheaza(d.id);
      return;
    }
    const w = window.open(d.url, "_blank", "noopener");
    if (w) marcheaza(d.id); else setEroare({ ...d, motiv: "blocat" });
  };

  const D = BIB_DATE();
  const folder = D.foldere.find((x) => x.slug === nav.folder) || null;
  const tipCurent = folder ? (folder.tipuri.find((x) => x.tip === nav.tip) || null) : null;
  const nDoc = (f) => f.tipuri.reduce((n, t) => n + t.documente.length, 0);
  const nDeschise = (lista) => lista.filter((d) => st.deschise[d.id]).length;
  const grid = { "--bib-w": BIB_TILE_W[st.view] };

  /* badge agregat pe folder: verde cand toate materialele au fost deschise, galben n/total */
  const badgeFolder = (lista) => {
    if (!lista.length) return null;
    const n = nDeschise(lista);
    if (n === 0) return null;
    if (n === lista.length) return <span className="bib-badge ok" title="Toate materialele deschise">✓</span>;
    return <span className="bib-badge part" title={n + " din " + lista.length + " deschise"}>{n}/{lista.length}</span>;
  };
  const toateDin = (f) => f.tipuri.reduce((a, t) => a.concat(t.documente), []);

  const celulaFolder = (key, nume, lista, onClick) => (
    <button key={key} className={"bib-tile" + (lista.length === 0 ? " gol" : "")} onClick={onClick}
      title={nume} aria-label={nume + " - " + (lista.length ? lista.length + " materiale" : "în pregătire")}>
      <span className="bib-icon">
        <BibFolder />
        {badgeFolder(lista)}
      </span>
      <span className="bib-tile-nume">{nume}</span>
      {lista.length > 0
        ? <span className="bib-tile-meta">{lista.length} {lista.length === 1 ? "material" : "materiale"}</span>
        : <span className="bib-gol-eticheta">în pregătire la Dr. Petre</span>}
    </button>
  );
  const randFolder = (key, nume, lista, onClick) => (
    <tr key={key} className="clicabil" onClick={onClick}>
      <td><span className="bib-nume-cell"><span className="mic"><BibFolder w="100%" /></span>{nume}</span></td>
      <td>Folder</td>
      <td className="num">{lista.length || "-"}</td>
      <td>{lista.length > 0
        ? <span className="bib-pill ok">{lista.length} {lista.length === 1 ? "material" : "materiale"}</span>
        : <span className="bib-pill mut">în pregătire</span>}</td>
    </tr>
  );
  const tabelFoldere = (randuri) => (
    <div className="panel" style={{ overflowX: "auto" }}>
      <table className="bib-tbl">
        <thead><tr><th>Folder</th><th>Tip</th><th className="num">Materiale</th><th>Stare</th></tr></thead>
        <tbody>{randuri}</tbody>
      </table>
    </div>
  );

  let continut;
  if (!folder) {
    continut = st.view === "details"
      ? tabelFoldere(D.foldere.map((f) => randFolder(f.slug, f.nume, toateDin(f),
          () => setNav({ folder: f.slug, tip: null }))))
      : (
        <div className="panel bib-panel">
          <div className="bib-grid" style={grid}>
            {D.foldere.map((f) => celulaFolder(f.slug, f.nume, toateDin(f),
              () => setNav({ folder: f.slug, tip: null })))}
          </div>
        </div>
      );
  } else if (!tipCurent) {
    continut = st.view === "details"
      ? tabelFoldere(folder.tipuri.map((t) => randFolder(t.tip, t.nume, t.documente,
          () => setNav({ folder: folder.slug, tip: t.tip }))))
      : (
        <div className="panel bib-panel">
          <div className="bib-grid" style={grid}>
            {folder.tipuri.map((t) => celulaFolder(t.tip, t.nume, t.documente,
              () => setNav({ folder: folder.slug, tip: t.tip })))}
          </div>
        </div>
      );
  } else {
    continut = <BibMateriale documente={tipCurent.documente} view={st.view}
      deschise={st.deschise} onDeschide={deschide} />;
  }

  return (
    <div className="page">
      <div className="bib-bar">
        <BibNav nav={nav} setNav={setNav} />
        <span style={{ marginLeft: "auto" }}><BibViewSwitch view={st.view} setView={setView} /></span>
      </div>

      {!folder && (
        <div className="panel" style={{ marginBottom: 14 }}>
          <h2 style={{ margin: "0 0 4px", fontSize: "var(--m-fs-6)", color: "var(--m-navy)" }}>
            Biblioteca metodologică
          </h2>
          <p className="small" style={{ margin: 0, maxWidth: 680 }}>
            Materialele metodologice ale programului, organizate pe credințe și pe tipuri de material.
            Documentele se deschid în vizualizator; instrumentele Excel se descarcă; materialele audio
            se ascultă direct aici.
          </p>
        </div>
      )}

      {eroare && (
        <div className="panel" style={{ marginBottom: 14, borderColor: "var(--m-warn)" }}>
          <p className="small" style={{ margin: 0 }}>
            <b>{eroare.titlu}</b> - {eroare.motiv === "blocat"
              ? "browserul a blocat fereastra nouă. Permite ferestrele pentru această pagină și încearcă din nou; materialul nu a fost marcat ca deschis."
              : "materialul se descarcă de pe serverul PRP, iar linkul nu este încă disponibil (sau conexiunea lipsește). Restul bibliotecii funcționează normal."}
          </p>
        </div>
      )}

      {continut}

      {audioActiv && (
        <div className="bib-modal" role="dialog" aria-modal="true" aria-label={audioActiv.titlu}
          onClick={() => setAudioActiv(null)}>
          <div className="bib-modal-corp" onClick={(e) => e.stopPropagation()}>
            <div className="bib-modal-titlu">
              <span>{audioActiv.titlu}</span>
              <button className="btn btn-ghost btn-sm" onClick={() => setAudioActiv(null)}>Închide</button>
            </div>
            <audio controls autoPlay preload="metadata" src={audioActiv.url} />
          </div>
        </div>
      )}
    </div>
  );
}
window.BibliotecaView = BibliotecaView;
