/* global React */
const { useState, useEffect, useMemo, useRef } = React;

/* ── Icons ── */
const Icon = ({ name, size = 18, ...p }) => {
  const s = { width: size, height: size };
  const c = { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.7, strokeLinecap: "round", strokeLinejoin: "round", ...p, style: { ...s, ...(p.style || {}) } };
  switch (name) {
    case "home":      return <svg {...c}><path d="M3 11l9-7 9 7v9a2 2 0 0 1-2 2h-3v-7h-8v7H5a2 2 0 0 1-2-2z"/></svg>;
    case "shelf":     return <svg {...c}><path d="M4 4v16M9 4v16M14 4v10M19 4v16M4 4h16M4 14h11M4 20h16"/></svg>;
    case "handoff":   return <svg {...c}><path d="M3 7l9 4 9-4M3 7v10l9 4 9-4V7M3 7l9-4 9 4"/></svg>;
    case "heart":     return <svg {...c}><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78L12 21.23l8.84-8.84a5.5 5.5 0 0 0 0-7.78z"/></svg>;
    case "chat":      return <svg {...c}><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>;
    case "plus":      return <svg {...c}><path d="M12 5v14M5 12h14"/></svg>;
    case "search":    return <svg {...c}><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>;
    case "close":     return <svg {...c}><path d="M18 6 6 18M6 6l12 12"/></svg>;
    case "back":      return <svg {...c}><path d="M19 12H5M12 19l-7-7 7-7"/></svg>;
    case "forward":   return <svg {...c}><path d="M5 12h14M12 5l7 7-7 7"/></svg>;
    case "calendar":  return <svg {...c}><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>;
    case "book":      return <svg {...c}><path d="M2 4.5A1.5 1.5 0 0 1 3.5 3H9a3 3 0 0 1 3 3v15M22 4.5A1.5 1.5 0 0 0 20.5 3H15a3 3 0 0 0-3 3v15"/><path d="M2 21h20"/></svg>;
    case "check":     return <svg {...c}><circle cx="12" cy="12" r="9"/><path d="m8 12 3 3 5-6"/></svg>;
    case "star":      return <svg {...c} fill="currentColor"><path d="m12 2 3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>;
    case "starO":     return <svg {...c}><path d="m12 2 3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>;
    case "bookmark":  return <svg {...c}><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/></svg>;
    case "filter":    return <svg {...c}><path d="M3 6h18M6 12h12M10 18h4"/></svg>;
    case "edit":      return <svg {...c}><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.12 2.12 0 0 1 3 3L12 15l-4 1 1-4z"/></svg>;
    case "trash":     return <svg {...c}><path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M10 11v6M14 11v6"/></svg>;
    case "send":      return <svg {...c}><path d="m22 2-7 20-4-9-9-4z"/><path d="M22 2 11 13"/></svg>;
    case "mic":       return <svg {...c}><rect x="9" y="2" width="6" height="12" rx="3"/><path d="M19 10a7 7 0 0 1-14 0M12 19v4M8 23h8"/></svg>;
    case "sparkle":   return <svg {...c}><path d="M12 3v3M12 18v3M5 12H2M22 12h-3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1"/></svg>;
    case "openbook":  return <svg {...c}><path d="M2 19V5a1 1 0 0 1 1-1h5.5A3.5 3.5 0 0 1 12 7.5V20"/><path d="M22 19V5a1 1 0 0 0-1-1h-5.5A3.5 3.5 0 0 0 12 7.5V20"/><path d="M2 19h7.5a2.5 2.5 0 0 1 2.5 2.5V20M22 19h-7.5a2.5 2.5 0 0 0-2.5 2.5V20"/></svg>;
    case "clock":     return <svg {...c}><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>;
    case "user":      return <svg {...c}><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></svg>;
    case "tag":       return <svg {...c}><path d="M20.6 12.6 12.4 4.4a1 1 0 0 0-.7-.3H4a1 1 0 0 0-1 1v7.7c0 .3.1.5.3.7l8.2 8.2a1 1 0 0 0 1.4 0l7.7-7.7a1 1 0 0 0 0-1.4z"/><circle cx="7.5" cy="7.5" r=".5" fill="currentColor"/></svg>;
    case "more":      return <svg {...c}><circle cx="5" cy="12" r="1.2" fill="currentColor"/><circle cx="12" cy="12" r="1.2" fill="currentColor"/><circle cx="19" cy="12" r="1.2" fill="currentColor"/></svg>;
    case "image":     return <svg {...c}><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="M21 15l-5-5L5 21"/></svg>;
    default: return null;
  }
};

/* ── Book Cover ── shows real image when coverUrl is set ── */
const BookCover = ({ book, width = 70, height = 100, onClick }) => {
  const bg = `hsl(${book.coverHue} 45% 30%)`;
  const [imgErr, setImgErr] = useState(false);

  if (book.coverUrl && !imgErr) {
    return (
      <div
        className="cover"
        style={{ width, height, "--cover-color": bg, padding: 0, overflow: "hidden", background: bg }}
        onClick={onClick}
      >
        <img
          src={book.coverUrl}
          alt={book.title}
          style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }}
          onError={() => setImgErr(true)}
        />
      </div>
    );
  }

  return (
    <div className="cover" style={{ width, height, "--cover-color": bg }} onClick={onClick}>
      <div className="cover-band"></div>
      <div className="cover-title" style={{ fontSize: width / 5.5 }}>{book.title}</div>
      <div className="cover-author" style={{ fontSize: width / 8.5 }}>{book.author}</div>
    </div>
  );
};

/* ── Book Spine ── */
const BookSpine = ({ book, height = 200, onClick }) => {
  const w = 30 + (book.pages / 60);
  return (
    <div
      className="spine"
      style={{ height, width: Math.min(w, 60), "--spine-color": book.spineColor }}
      onClick={onClick}
      title={`${book.title} — ${book.author}`}
    >
      <div className="spine-band top"></div>
      <div className="spine-text">{book.title}</div>
      <div className="spine-band bot"></div>
    </div>
  );
};

/* ── Status Pill ── */
const STATUS_LABEL = {
  available: { label: "זמין",    className: "pill-available" },
  loaned:    { label: "מושאל",   className: "pill-loaned"    },
  reading:   { label: "בקריאה", className: "pill-reading"   },
  finished:  { label: "נקרא",   className: "pill-finished"  },
};
const StatusPill = ({ status }) => {
  const s = STATUS_LABEL[status] || STATUS_LABEL.available;
  return <span className={`pill ${s.className}`}><span className="pill-dot"></span>{s.label}</span>;
};

/* ── Stars ── */
const Stars = ({ value = 0, size = 14 }) => (
  <span className="stars" style={{ fontSize: size }}>
    {[1,2,3,4,5].map(n => <Icon key={n} name={n <= value ? "star" : "starO"} size={size} />)}
  </span>
);

/* ── Avatar ── */
const Avatar = ({ name, size = "" }) => {
  const letter = (name || "?").trim()[0];
  return <span className={`avatar ${size === "lg" ? "avatar-lg" : size === "sm" ? "avatar-sm" : ""}`}>{letter}</span>;
};

/* ── Modal ── */
const Modal = ({ open, onClose, title, sub, children, footer, wide }) => {
  useEffect(() => {
    if (!open) return;
    const h = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", h);
    return () => document.removeEventListener("keydown", h);
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div className="modal-back" onClick={onClose}>
      <div className="modal" style={wide ? { maxWidth: 720 } : null} onClick={e => e.stopPropagation()}>
        <div className="row between gap-3" style={{ alignItems: "flex-start" }}>
          <div>
            {title && <h2 className="modal-title">{title}</h2>}
            {sub && <div className="modal-sub">{sub}</div>}
          </div>
          <button className="btn btn-icon btn-ghost" onClick={onClose}><Icon name="close" size={20} /></button>
        </div>
        {children}
        {footer && <div className="row gap-3 mt-6" style={{ justifyContent: "flex-start" }}>{footer}</div>}
      </div>
    </div>
  );
};

/* ── Field ── */
const Field = ({ label, children }) => (
  <div className="field">
    {label && <label className="field-label">{label}</label>}
    {children}
  </div>
);
const TextInput   = (props) => <input className="field-input" {...props} />;
const TextArea    = (props) => <textarea className="field-input" rows={3} {...props} />;
const SelectInput = ({ options, ...props }) => (
  <select className="field-input" {...props}>
    {options.map(o => typeof o === "string"
      ? <option key={o} value={o}>{o}</option>
      : <option key={o.value} value={o.value}>{o.label}</option>)}
  </select>
);

/* ── Segment ── */
const Segment = ({ items, value, onChange }) => (
  <div style={{ display: "inline-flex", padding: 4, borderRadius: 999, background: "rgba(58,33,19,.06)", border: "1px solid var(--line)", gap: 2 }}>
    {items.map(it => (
      <button key={it.id} className="btn btn-sm" onClick={() => onChange(it.id)} style={{
        background: value === it.id ? "var(--paper-card)" : "transparent",
        border: 0,
        color: value === it.id ? "var(--ink)" : "var(--ink-mute)",
        fontWeight: value === it.id ? 700 : 500,
        boxShadow: value === it.id ? "0 1px 2px rgba(58,33,19,.1)" : "none",
        whiteSpace: "nowrap",
      }}>
        <span>{it.label}</span>
        {it.count !== undefined && <span style={{ opacity: .55, fontWeight: 500, marginInlineStart: 4 }}>{it.count}</span>}
      </button>
    ))}
  </div>
);

/* ── Empty State ── */
const Empty = ({ icon, title, sub, action }) => (
  <div style={{ padding: "60px 24px", textAlign: "center", borderRadius: 22, border: "1px dashed var(--line-strong)", background: "rgba(255,255,255,.25)" }}>
    <div style={{ display: "inline-grid", placeItems: "center", width: 64, height: 64, borderRadius: 20, background: "rgba(180,138,58,.12)", color: "var(--gold)", marginBottom: 14 }}>
      <Icon name={icon} size={28} />
    </div>
    <div className="serif" style={{ fontSize: 22, fontWeight: 700 }}>{title}</div>
    {sub && <div className="muted mt-2">{sub}</div>}
    {action && <div className="mt-4">{action}</div>}
  </div>
);

/* ── Google Books API ── */
async function searchGoogleBooks(title, author) {
  if (!title || title.length < 2) return [];
  const q = [title && `intitle:${title}`, author && `inauthor:${author}`].filter(Boolean).join("+");
  try {
    const res = await fetch(`https://www.googleapis.com/books/v1/volumes?q=${encodeURIComponent(q)}&maxResults=6&fields=items(volumeInfo(title,authors,imageLinks))`);
    const data = await res.json();
    return (data.items || [])
      .filter(i => i.volumeInfo?.imageLinks)
      .map(i => ({
        title: i.volumeInfo.title,
        author: (i.volumeInfo.authors || []).join(", "),
        coverUrl: (i.volumeInfo.imageLinks.thumbnail || i.volumeInfo.imageLinks.smallThumbnail || "").replace("http:", "https:"),
      }))
      .filter(i => i.coverUrl);
  } catch { return []; }
}

Object.assign(window, {
  Icon, BookCover, BookSpine, StatusPill, Stars, Avatar, Modal,
  Field, TextInput, TextArea, SelectInput, Segment, Empty, searchGoogleBooks,
});
