/* Библиотека — живой каталог киоска (/api/library/books) */
const PAGE_SIZE = 32;

const LIB_FILTER_ORDER = ['Малыши и дошкольники', 'Младшие школьники',
  'Подростки', 'Взрослые', 'Научно-популярная', 'Ст. 282'];
const LIB_SPINES = ['#5E6E42', '#B5562F', '#3E4A6B', '#879761',
  '#7A4A2E', '#46604A', '#6B5B7A', '#A05A2C'];

function spineColor(title) {
  let h = 0;
  for (const ch of String(title || '')) h = (h * 31 + ch.charCodeAt(0)) >>> 0;
  return LIB_SPINES[h % LIB_SPINES.length];
}

function fmtUpdated(iso) {
  if (!iso) return '';
  const d = new Date(iso);
  if (isNaN(d)) return '';
  return d.toLocaleDateString('ru-RU', { day: 'numeric', month: 'long' }) +
    ', ' + d.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' });
}

function Library({ go }) {
  const [books, setBooks] = useState(null); // null — идёт загрузка
  const [updatedAt, setUpdatedAt] = useState(null);
  const [error, setError] = useState(false);
  const [q, setQ] = useState('');
  const [cat, setCat] = useState('Все');
  const [onlyAvail, setOnlyAvail] = useState(false);
  const [selected, setSelected] = useState(null);
  const [page, setPage] = useState(0);

  useEffect(() => {
    fetch('/api/library/books')
      .then(r => { if (!r.ok) throw new Error(r.status); return r.json(); })
      .then(d => {
        const arr = d.books || [];
        for (let i = arr.length - 1; i > 0; i--) {
          const j = Math.floor(Math.random() * (i + 1));
          [arr[i], arr[j]] = [arr[j], arr[i]];
        }
        setBooks(arr);
        setUpdatedAt(d.updated_at);
      })
      .catch(() => setError(true));
  }, []);

  const cats = useMemo(() => {
    if (!books || !books.length) return [];
    const present = new Set(books.map(b => b.filter).filter(Boolean));
    return ['Все',
      ...LIB_FILTER_ORDER.filter(f => present.has(f)),
      ...[...present].filter(f => !LIB_FILTER_ORDER.includes(f)).sort()];
  }, [books]);

  const filtered = useMemo(() => {
    if (!books) return [];
    const qq = q.trim().toLowerCase();
    return books.filter(b => {
      if (cat !== 'Все' && b.filter !== cat) return false;
      if (onlyAvail && !b.avail) return false;
      if (!qq) return true;
      return ((b.title || '') + ' ' + (b.author || '')).toLowerCase().includes(qq);
    });
  }, [books, q, cat, onlyAvail]);

  // сброс страницы при смене фильтров/поиска
  useEffect(() => { setPage(0); }, [q, cat, onlyAvail]);

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

  return (
    <div className="wrap section-pad">
      <SectionHead index="03" kicker="библиотека"
        title="Полка дома"
        intro="Книги живут у камина и едут с вами на вечер. Ищите по названию, автору или жанру — всё из нашей базы. Берите почитать в пространстве или возьмите домой на две недели." />

      {/* фото полок */}
      <div className="ph" style={{ aspectRatio:'21/7', marginBottom:30, border:'1px solid var(--ink)' }}>
        <img src="assets/photos/books-adult.png" alt="Полки библиотеки" style={{ objectPosition:'center 42%' }} />
        <span className="ph__label">наши полки · @dzagli_tbilisi</span>
      </div>

      {error ? (
        <div className="lib-empty">
          <span className="serif" style={{ fontSize:34 }}>База временно недоступна</span>
          <p className="muted" style={{ marginTop:8 }}>Загляните чуть позже — каталог скоро вернётся.</p>
        </div>
      ) : books === null ? (
        <div className="lib-empty"><span className="mono faint">загружаем каталог…</span></div>
      ) : books.length === 0 ? (
        <div className="lib-empty">
          <span className="serif" style={{ fontSize:34 }}>Каталог скоро появится</span>
        </div>
      ) : (<>
        {/* поиск */}
        <div className="lib-search">
          <span style={{ color:'var(--ink-faint)' }}><Search size={18} /></span>
          <input value={q} onChange={e=>setQ(e.target.value)} placeholder="Набоков, Зицер, «Патриот»…" />
          {q && <button className="mono lib-search__clear" onClick={()=>setQ('')}>очистить ✕</button>}
        </div>

        {/* фильтры */}
        <div className="flex between center" style={{ marginTop:18, marginBottom:30, flexWrap:'wrap', gap:16 }}>
          <div className="flex gap-s" style={{ flexWrap:'wrap' }}>
            {cats.map(c => (
              <button key={c} className={'chip'+(cat===c?' is-on':'')} onClick={()=>setCat(c)}>{c}</button>
            ))}
          </div>
          <label className="flex center gap-s mono lib-avail">
            <input type="checkbox" checked={onlyAvail} onChange={e=>setOnlyAvail(e.target.checked)} />
            только в наличии
          </label>
        </div>

        <div className="flex between center" style={{ marginBottom:18 }}>
          <span className="mono faint" style={{ fontSize:12 }}>
            {filtered.length} {plural(filtered.length,['книга','книги','книг'])}
          </span>
          {updatedAt && <span className="mono faint" style={{ fontSize:12 }}>обновлено {fmtUpdated(updatedAt)}</span>}
        </div>

        {filtered.length === 0 ? (
          <div className="lib-empty">
            <span className="serif" style={{ fontSize:34 }}>Ничего не нашлось</span>
            <p className="muted" style={{ marginTop:8 }}>Попробуйте другое слово или сбросьте фильтры.</p>
            <button className="btn btn--ghost" style={{ marginTop:18 }} onClick={()=>{setQ('');setCat('Все');setOnlyAvail(false);}}>Сбросить всё</button>
          </div>
        ) : (<>
          <div className="book-grid">
            {pageBooks.map(b => <BookCard key={b.id} b={b} onOpen={setSelected} />)}
          </div>

          {totalPages > 1 && (
            <div className="lib-pages">
              <button className="lib-pages__btn mono" disabled={page === 0}
                onClick={()=>{ setPage(p=>p-1); window.scrollTo({top:0,behavior:'smooth'}); }}>← назад</button>
              <span className="mono faint lib-pages__info">{page+1} / {totalPages}</span>
              <button className="lib-pages__btn mono" disabled={page >= totalPages-1}
                onClick={()=>{ setPage(p=>p+1); window.scrollTo({top:0,behavior:'smooth'}); }}>вперёд →</button>
            </div>
          )}
        </>)}
      </>)}

      {selected && <BookModal b={selected} onClose={()=>setSelected(null)} />}
    </div>
  );
}

function BookCover({ b, large }) {
  const [imgFailed, setImgFailed] = useState(false);
  const showImg = b.has_cover && b.isbn && !imgFailed;
  return (
    <div className="book__cover" style={{ '--spine': spineColor(b.title) }}>
      {showImg ? (
        <img src={'/api/library/covers/'+b.isbn} alt={b.title} loading="lazy"
          style={{ width:'100%', height:'100%', objectFit:'cover' }}
          onError={()=>setImgFailed(true)} />
      ) : (<>
        <div className="book__spine"></div>
        <div className="book__face">
          <span className="serif book__title" style={large?{fontSize:26}:null}>{b.title}</span>
          <span className="book__author">{b.author}</span>
        </div>
      </>)}
      {!b.avail && <span className="book__out mono">на руках</span>}
    </div>
  );
}

function BookCard({ b, onOpen }) {
  return (
    <button className="book book--btn" onClick={()=>onOpen(b)}>
      <BookCover b={b} />
      <div className="book__meta">
        <span className="mono book__genre">{b.filter}</span>
        <span className="mono faint">{b.year || ''}</span>
      </div>
    </button>
  );
}

function BookModal({ b, onClose }) {
  useEffect(() => {
    const onKey = e => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = '';
    };
  }, [onClose]);

  return (
    <div className="lib-modal" onClick={onClose}>
      <div className="lib-modal__box" onClick={e=>e.stopPropagation()}>
        <button className="lib-modal__close mono" onClick={onClose}>закрыть ✕</button>
        <div className="lib-modal__cover"><BookCover b={b} large /></div>
        <div className="lib-modal__info">
          <span className="mono book__genre">{b.filter}{b.age != null ? ` · ${b.age}+` : ''}</span>
          <h3 className="serif lib-modal__title">{b.title}</h3>
          <p className="mono faint" style={{ fontSize:12 }}>
            {[b.author, b.publisher, b.year].filter(Boolean).join(' · ')}
          </p>
          <p className={'mono lib-modal__status'+(b.avail?' is-avail':'')}>
            {b.avail ? '● в наличии' : '○ на руках'}
          </p>
          {b.summary && <p className="lib-modal__summary">{b.summary}</p>}
        </div>
      </div>
    </div>
  );
}

function plural(n, forms) {
  const n10 = n % 10, n100 = n % 100;
  if (n10 === 1 && n100 !== 11) return forms[0];
  if (n10 >= 2 && n10 <= 4 && (n100 < 10 || n100 >= 20)) return forms[1];
  return forms[2];
}
Object.assign(window, { Library });
