// library.jsx — Library / home screen
// Grid of concept cards, search, filter, quick-add field.

const { useEffect: _le, useState: _ls, useMemo: _lm, useRef: _lr } = React;

const PAGE_SIZE = 12;

function _updatedRank(v) {
  if (v === "moments ago") return Infinity;
  if (!v || v === "recently") return 0;
  return new Date(v).getTime() || 0;
}

function Library({ concepts, onOpen, onCreate, onDelete, onOpenSolar, onOpenGraph, onOpenGroup, onOpenCardsHub }) {
  const [query, setQuery] = _ls("");
  const [filter, setFilter] = _ls("all"); // all | filled | unfilled
  const [draft, setDraft] = _ls("");
  const [page, setPage] = _ls(0);
  const [cardImages, setCardImages] = _ls({});
  const [hovTab, setHovTab] = _ls(null);

  _le(() => {
    if (!window.cardsService) return;
    window.cardsService.getAllCards().then(rows => {
      const map = {};
      rows.forEach(q => {
        if (q.type !== "image" || !q.content) return;
        if (!map[q.concept_id]) map[q.concept_id] = [];
        if (map[q.concept_id].length < 5) map[q.concept_id].push(q.content);
      });
      setCardImages(map);
    });
  }, []);

  const filtered = _lm(() => {
    let list = [...concepts].sort((a, b) => _updatedRank(b.updated) - _updatedRank(a.updated));
    if (query.trim()) {
      const q = query.toLowerCase();
      list = list.filter(c =>
        c.title.toLowerCase().includes(q)
        || c.category.toLowerCase().includes(q)
        || (c.essences || []).some(e => e.body.toLowerCase().includes(q))
      );
    }
    if (filter === "filled") list = list.filter(c => window.fillCount(c) === 5);
    if (filter === "unfilled") list = list.filter(c => window.fillCount(c) < 5);
    return list;
  }, [concepts, query, filter]);

  const totalPages = Math.ceil(filtered.length / PAGE_SIZE);
  const paged = filtered.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE);

  _le(() => { setPage(0); }, [query, filter]);

  const totalFilled = concepts.filter(c => window.fillCount(c) === 5).length;

  function submitDraft(e) {
    e.preventDefault();
    if (!draft.trim()) return;
    onCreate(draft.trim());
    setDraft("");
  }

  return (
    <div className="page" data-screen-label="Library" style={{ maxWidth: "none" }}>
      <div className="lib-grid" style={{
        display: "grid",
        gridTemplateColumns: "repeat(4, minmax(0, 1fr))",
        columnGap: 20,
        rowGap: 20,
        alignItems: "start",
      }}>

        {/* Hero text — cols 1–2, row 1 */}
        <div className="lib-hero" style={{ gridColumn: "1 / 3", gridRow: 1 }}>
          <div className="tag-flat" style={{ marginBottom: 14 }}>Your library · {concepts.length} concepts · {totalFilled} complete</div>
          <h1 className="concept-title lib-hero-title" style={{ fontSize: 56, margin: "0 0 14px" }}>
            What do you want to <em style={{ fontStyle: "italic", color: "var(--c-nucleus)" }}>understand</em> today?
          </h1>
          <p style={{ color: "var(--fg-2)", fontSize: 15, margin: 0, lineHeight: 1.55 }}>
            A concept becomes yours when you can describe what it&#8217;s made of, how it works, what it felt like in your hand, and what stays when all of that is gone.
          </p>
        </div>

        {/* Graph panel — cols 3–4, rows 1–3 */}
        <div className="lib-graph" style={{
          gridColumn: "3 / 5", gridRow: "1 / 4",
          alignSelf: "stretch", position: "relative",
          borderRadius: 12, overflow: "hidden",
          background: "var(--bg-sunk)",
        }}>
          <window.GraphPanel
            concepts={concepts}
            onOpen={(id) => onOpen(id, "edit")}
            onOpenGraph={onOpenGraph}
          />
          <div style={{ position: "absolute", top: 10, right: 10, zIndex: 10, display: "flex", gap: 4 }}>
            <button onClick={onOpenCardsHub} className="btn ghost tiny" style={{ background: "var(--bg-elev)", boxShadow: "0 1px 2px rgba(0,0,0,.06), 0 4px 16px -4px rgba(0,0,0,.1)" }} title="Open cards">
              {window.Icons.Cards(13)} Card
            </button>
            <button onClick={() => onOpenGraph()} className="btn ghost tiny" style={{ background: "var(--bg-elev)", boxShadow: "0 1px 2px rgba(0,0,0,.06), 0 4px 16px -4px rgba(0,0,0,.1)" }} title="Open graph">
              {window.Icons.Graph(13)} Graph
            </button>
            <button onClick={() => onOpenGroup()} className="btn ghost tiny" style={{ background: "var(--bg-elev)", boxShadow: "0 1px 2px rgba(0,0,0,.06), 0 4px 16px -4px rgba(0,0,0,.1)" }} title="Open group">
              {window.Icons.Atom(13)} Group
            </button>
          </div>
        </div>

        {/* Quick-add form — cols 1–2, row 2 */}
        <form className="surface lib-quickadd" onSubmit={submitDraft} style={{
          gridColumn: "1 / 3", gridRow: 2,
          display: "flex", alignItems: "center", gap: 10,
          padding: "10px 14px",
        }}>
          <span style={{ color: "var(--fg-3)", display: "flex", alignItems: "center" }}>{window.Icons.Plus(15)}</span>
          <input
            value={draft}
            onChange={e => setDraft(e.target.value)}
            placeholder="Add a concept — single word or phrase"
            style={{ flex: 1, fontSize: 15, fontFamily: "var(--font-serif)", lineHeight: 1 }}
          />
          <span className="tag-flat" style={{ opacity: draft.trim() ? .9 : 0, transition: "opacity 160ms" }}>
            <span className="kbd">↵</span> create
          </span>
        </form>

        {/* Search — col 1, row 3 */}
        <div className="lib-search" style={{ gridColumn: "1 / 2", gridRow: 3 }}>
          <div className="field" style={{ display: "flex", alignItems: "center", gap: 8, padding: "8px 12px" }}>
            <span style={{ color: "var(--fg-3)", display: "flex", alignItems: "center" }}>{window.Icons.Search(14)}</span>
            <input
              value={query}
              onChange={e => setQuery(e.target.value)}
              placeholder="Search by name, category, or essence…"
              style={{ fontSize: 13, width: "100%" }}
            />
          </div>
        </div>

        {/* Filters — col 2, row 3 */}
        <div className="lib-filters" style={{ gridColumn: "2 / 3", gridRow: 3, display: "flex", alignItems: "center" }}>
          <div className="mode-pill" style={{ padding: "6px 4px" }}>
            {[
              ["all", "All", concepts.length],
              ["filled", "Complete", concepts.filter(c => window.fillCount(c) === 5).length],
              ["unfilled", "In progress", concepts.filter(c => window.fillCount(c) < 5).length],
            ].map(([k, label, n]) => (
              <button key={k} onClick={() => setFilter(k)} className="btn tiny"
                onMouseEnter={() => setHovTab(k)}
                onMouseLeave={() => setHovTab(null)}
                style={{
                  border: 0,
                  background: filter === k ? "var(--c-nucleus)" : hovTab === k ? "var(--bg-sunk)" : "transparent",
                  boxShadow: filter === k ? "0 1px 3px rgba(0,0,0,.15)" : "none",
                  color: filter === k ? "rgba(0,0,0,0.8)" : "var(--fg-3)",
                }}>
                {label} <span style={{ color: filter === k ? "rgba(0,0,0,0.8)" : "var(--fg-3)", marginLeft: 4, opacity: filter === k ? 0.7 : 1 }}>{n}</span>
              </button>
            ))}
          </div>
        </div>

        {/* Cards — auto-placed from row 4, 4 per row */}
        {paged.map((c, i) => <ConceptCard key={c.id} c={c} onOpen={() => onOpen(c.id, "edit")} delay={i * 18} images={cardImages[c.id] || []} />)}
        {filtered.length === 0 && (
          <div style={{ gridColumn: "1 / -1", padding: "60px 0", textAlign: "center", color: "var(--fg-3)", fontFamily: "var(--font-serif)", fontSize: 22, fontStyle: "italic" }}>
            Nothing here yet. The empty page is also a thought.
          </div>
        )}

        {/* Pagination */}
        {totalPages > 1 && (
          <div style={{ gridColumn: "1 / -1", display: "flex", alignItems: "center", justifyContent: "center", gap: 8, paddingTop: 8, paddingBottom: 8 }}>
            <button className="btn ghost tiny" onClick={() => setPage(p => p - 1)} disabled={page === 0}
              style={{ opacity: page === 0 ? 0.3 : 1 }}>
              {window.Icons.ArrowL(13)}
            </button>
            {Array.from({ length: totalPages }, (_, i) => (
              <button key={i} className="btn tiny" onClick={() => setPage(i)} style={{
                border: 0, minWidth: 28,
                background: i === page ? "var(--bg-elev)" : "transparent",
                boxShadow: i === page ? "0 1px 2px rgba(0,0,0,.05)" : "none",
                color: i === page ? "var(--fg)" : "var(--fg-3)",
                fontFamily: "var(--font-mono)", fontSize: 11,
              }}>{i + 1}</button>
            ))}
            <button className="btn ghost tiny" onClick={() => setPage(p => p + 1)} disabled={page === totalPages - 1}
              style={{ opacity: page === totalPages - 1 ? 0.3 : 1, transform: "rotate(180deg)" }}>
              {window.Icons.ArrowL(13)}
            </button>
          </div>
        )}

      </div>
    </div>
  );
}

function ConceptCard({ c, onOpen, onDelete, delay, images = [] }) {
  const essence = (c.essences || [])[0]?.body || "";
  const f = window.fillCount(c);
  const isComplete = f === 5;
  const [hov, setHov] = _ls(false);
  const [confirm, setConfirm] = _ls(false);
  const confirmTimer = _lr(null);
  const [landscape, setLandscape] = _ls({});

  function handleDelete(e) {
    e.stopPropagation();
    if (!confirm) {
      setConfirm(true);
      clearTimeout(confirmTimer.current);
      confirmTimer.current = setTimeout(() => setConfirm(false), 2500);
    } else {
      clearTimeout(confirmTimer.current);
      onDelete();
    }
  }

  return (
    <button
      onClick={onOpen}
      onMouseEnter={() => setHov(true)}
      onMouseLeave={() => { setHov(false); setConfirm(false); clearTimeout(confirmTimer.current); }}
      className="surface surface-hover fade-up"
      style={{
        textAlign: "left",
        padding: 20,
        cursor: "pointer",
        display: "flex", flexDirection: "column", gap: 12,
        minHeight: 240,
        animationDelay: delay + "ms",
        font: "inherit", color: "inherit",
        position: "relative",
        overflow: "hidden",
      }}
    >
      {onDelete && (hov || confirm) && (
        <button
          onClick={handleDelete}
          style={{
            position: "absolute", top: 10, right: 10,
            background: confirm ? "var(--c-essence)" : "var(--bg-sunk)",
            border: "1px solid " + (confirm ? "var(--c-essence)" : "var(--border-soft)"),
            borderRadius: 6,
            padding: "3px 8px",
            fontSize: 11, fontFamily: "var(--font-mono)", letterSpacing: ".04em",
            color: confirm ? "#fff" : "var(--fg-3)",
            cursor: "pointer",
            transition: "all 150ms",
          }}
        >
          {confirm ? "confirm?" : "delete"}
        </button>
      )}
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 12 }}>
        <div>
          <div className="tag-flat" style={{ marginBottom: 6 }}>{c.category}</div>
          <h3 className="concept-title" style={{ fontSize: 30, margin: 0, lineHeight: 1.05 }}>{c.title}</h3>
        </div>
        <window.Dots concept={c} />
      </div>

      <div style={{ flex: 1, color: "var(--fg-2)", fontSize: 13.5, lineHeight: 1.55 }}>
        {essence
          ? <span style={{ fontFamily: "var(--font-serif)", fontSize: 16.5, fontStyle: "italic", color: "var(--fg)" }}>
              &ldquo;{essence}&rdquo;
            </span>
          : <span style={{ color: "var(--fg-3)", fontStyle: "italic" }}>
              {c.perspectives?.length
                ? `${c.perspectives.length} ${c.perspectives.length === 1 ? "perspective" : "perspectives"}, no essence yet`
                : "Awaiting first thought…"}
            </span>
        }
      </div>

      <div style={{ color: "var(--fg-3)", fontSize: 11.5, fontFamily: "var(--font-mono)", letterSpacing: ".06em" }}>
        <span>{c.updated}</span>
      </div>

      {images.length > 0 && (() => {
        const imgs = images.slice(0, 5);
        const n = imgs.length;
        const rots = [-7, 4, -5, 6, -4];
        return (
          <div style={{ position: "absolute", bottom: -16, left: 0, right: 0, height: 96, pointerEvents: "none", opacity: hov ? 1 : 0, transform: hov ? "translateY(0)" : "translateY(18px)", transition: "opacity 260ms ease, transform 260ms ease" }}>
            {imgs.map((url, i) => (
              <img key={i} src={url} alt=""
                onLoad={e => {
                  if (e.target.naturalWidth > e.target.naturalHeight)
                    setLandscape(prev => ({ ...prev, [i]: true }));
                }}
                style={{
                  position: "absolute",
                  right: (n - 1 - i) * 22 + 4,
                  bottom: landscape[i] ? 18 : 0,
                  maxWidth: 58,
                  maxHeight: 80,
                  width: "auto",
                  height: "auto",
                  display: "block",
                  borderRadius: 4,
                  boxShadow: "0 2px 10px rgba(0,0,0,0.22)",
                  transform: `rotate(${rots[i % rots.length]}deg)`,
                  transformOrigin: "bottom center",
                  zIndex: i + 1,
                }}
              />
            ))}
          </div>
        );
      })()}
    </button>
  );
}

Object.assign(window, { Library });
