// app/screen-library.jsx — browse, search, filter, click into a recipe.
// Responsive: laptop 4-col + feature · iPad 3-col + feature · iPhone 2-col + featured card.

function useLibraryFilter() {
  const { allRecipes, state } = useApp();
  const q = (state.search || '').trim().toLowerCase();
  const f = state.filter || 'all';
  const list = allRecipes.filter((r) => {
    if (f !== 'all') {
      if (!(r.meals || []).includes(f)) return false;
    }
    if (q) {
      const hay = (r.name + ' ' + (r.meals || []).join(' ') + ' ' + r.ingredients.join(' ')).toLowerCase();
      if (!hay.includes(q)) return false;
    }
    return true;
  });
  return window.LCDomain.sortRecipes(list, state.sort || 'recent');
}

const LIB_CHIPS = ['all', 'breakfast', 'lunch', 'dinner', 'dessert', 'snack'];

// Fixed sort options. Each key has ONE meaningful direction (no asc/desc toggle);
// missing data always sinks to the bottom — see LCDomain.sortRecipes.
const SORT_OPTIONS = [
  { key: 'recent', label: 'Recently cooked', note: 'default order' },
  { key: 'rating-desc', label: 'Rating', note: 'high to low' },
  { key: 'cost-asc', label: 'Cost', note: 'low to high' },
  { key: 'effort-asc', label: 'Effort', note: 'quick first' },
];

function SortControl({ iconOnly }) {
  const { state, set } = useApp();
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!open) return;
    const onDown = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    document.addEventListener('mousedown', onDown);
    document.addEventListener('keydown', onKey);
    return () => { document.removeEventListener('mousedown', onDown); document.removeEventListener('keydown', onKey); };
  }, [open]);
  const cur = state.sort || 'recent';
  const active = cur !== 'recent';
  const curOpt = SORT_OPTIONS.find((o) => o.key === cur) || SORT_OPTIONS[0];
  return (
    <div ref={ref} style={{ position: 'relative', flexShrink: 0 }}>
      <button onClick={() => setOpen((v) => !v)} aria-label="Sort recipes" title="Sort recipes" style={{
        display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, cursor: 'pointer',
        padding: iconOnly ? 0 : '10px 14px', width: iconOnly ? 44 : 'auto', height: iconOnly ? 44 : 'auto',
        borderRadius: 999, fontFamily: 'Bricolage Grotesque', fontSize: 12, fontWeight: 500,
        background: active ? 'linear-gradient(180deg, rgba(255,255,255,0.12), rgba(255,255,255,0.03))' : 'rgba(255,255,255,0.04)',
        border: active ? '1px solid rgba(255,255,255,0.18)' : '1px solid var(--hairline)',
        color: active ? 'var(--ink)' : 'var(--ink-3)' }}>
        <Icon.sort size={16} />
        {!iconOnly && (
          <React.Fragment>
            <span style={{ whiteSpace: 'nowrap' }}>{active ? curOpt.label : 'Sort'}</span>
            <Icon.chevD size={14} style={{ opacity: 0.55 }} />
          </React.Fragment>
        )}
      </button>
      {open && (
        <div style={{ position: 'absolute', top: 'calc(100% + 8px)', right: 0, zIndex: 60,
          minWidth: 192, padding: 6, borderRadius: 14, background: '#15151b',
          border: '1px solid var(--hairline)', boxShadow: '0 24px 60px rgba(0,0,0,0.55)' }}>
          <div style={{ padding: '6px 10px 8px', fontFamily: 'Bricolage Grotesque', fontSize: 10,
            fontWeight: 600, letterSpacing: '0.22em', textTransform: 'uppercase', color: 'var(--ink-3)' }}>
            Sort by
          </div>
          {SORT_OPTIONS.map((o) => {
            const on = o.key === cur;
            return (
              <button key={o.key} onClick={() => { set({ sort: o.key }); setOpen(false); }} style={{
                width: '100%', display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer',
                padding: '9px 10px', borderRadius: 9, border: 'none', textAlign: 'left',
                background: on ? 'rgba(255,255,255,0.06)' : 'transparent' }}>
                <span style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 1 }}>
                  <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 13.5, fontWeight: 500,
                    color: on ? 'var(--ink)' : 'var(--ink-2)' }}>{o.label}</span>
                  <span style={{ fontFamily: 'var(--mono)', fontSize: 10, color: 'var(--ink-3)' }}>{o.note}</span>
                </span>
                {on && <Icon.check size={15} style={{ color: 'var(--olive)' }} />}
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
}

function ClickableCard({ r, size }) {
  const { openRecipe, photoFor } = useApp();
  return (
    <div onClick={() => openRecipe(r.id)} style={{ cursor: 'pointer' }}>
      <FRecipeCard recipe={r} photoSrc={photoFor(r.id)} size={size} />
    </div>
  );
}

function SearchBar({ wide }) {
  const { state, set, allRecipes } = useApp();
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '12px 16px',
      background: 'rgba(255,255,255,0.04)', border: '1px solid var(--hairline)',
      borderRadius: 999, flex: wide ? 1 : 'none', maxWidth: wide ? 460 : 'none' }}>
      <Icon.search size={16} style={{ color: 'var(--ink-3)' }} />
      <input value={state.search} onChange={(e) => set({ search: e.target.value })}
        placeholder="search recipes, ingredients"
        style={{ border: 'none', background: 'transparent', outline: 'none', flex: 1,
          fontFamily: 'Bricolage Grotesque', fontSize: 15, color: 'var(--ink)' }} />
      {state.search ? (
        <button onClick={() => set({ search: '' })} style={{ background: 'transparent',
          border: 'none', cursor: 'pointer', color: 'var(--ink-3)', display: 'flex' }}>
          <Icon.x size={15} />
        </button>
      ) : (
        <span style={{ fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--ink-3)' }}>
          {allRecipes.length}
        </span>
      )}
    </div>
  );
}

function ChipRow({ scroll }) {
  const { state, set } = useApp();
  return (
    <div className={scroll ? 'lc-hscroll' : ''} style={{ display: 'flex', gap: 6, flexWrap: scroll ? 'nowrap' : 'wrap',
      overflowX: scroll ? 'auto' : 'visible' }}>
      {LIB_CHIPS.map((c) => {
        const active = state.filter === c;
        return (
          <button key={c} onClick={() => set({ filter: c })} style={{
            fontFamily: 'Bricolage Grotesque', fontSize: 12, fontWeight: 500,
            padding: '7px 12px', borderRadius: 999, cursor: 'pointer',
            flexShrink: scroll ? 0 : 1, whiteSpace: 'nowrap',
            background: active ? 'linear-gradient(180deg, rgba(255,255,255,0.12), rgba(255,255,255,0.03))' : 'transparent',
            border: active ? '1px solid rgba(255,255,255,0.18)' : '1px solid var(--hairline)',
            color: active ? 'var(--ink)' : 'var(--ink-3)',
          }}>{c}</button>
        );
      })}
    </div>
  );
}

function EmptyResults() {
  const { set } = useApp();
  return (
    <div style={{ padding: '60px 0', textAlign: 'center' }}>
      <div style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontSize: 22,
        color: 'var(--ink-2)' }}>Nothing matches that.</div>
      <button onClick={() => set({ search: '', filter: 'all' })} style={{ marginTop: 14,
        background: 'transparent', border: 'none', cursor: 'pointer', color: 'var(--olive)',
        fontFamily: 'Bricolage Grotesque', fontSize: 14, fontWeight: 500 }}>
        Clear search & filters →
      </button>
    </div>
  );
}

// ── Desktop / tablet ──
function LibraryWide({ compact }) {
  const { allRecipes, openRecipe, photoFor, go, state } = useApp();
  const list = useLibraryFilter();
  const featured = allRecipes.find((r) => r.id === 'sichuan-chicken');
  const cols = compact ? 3 : 4;
  const pad = compact ? '0 32px' : '0 48px';
  const searching = state.search || state.filter !== 'all';

  return (
    <div style={{ minHeight: '100%' }}>
      {/* Title row */}
      <div style={{ padding: compact ? '36px 32px 24px' : '30px 48px 20px', display: 'flex',
        alignItems: 'flex-end', justifyContent: 'space-between', gap: 32 }}>
        <div>
          <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 11, fontWeight: 600,
            letterSpacing: '0.28em', textTransform: 'uppercase', color: 'var(--olive)' }}>
            Your library · recently cooked
          </span>
          <h1 style={{ fontFamily: 'Bricolage Grotesque', fontWeight: 700,
            fontSize: compact ? 72 : 80, lineHeight: 0.92, letterSpacing: '-0.045em',
            color: 'var(--ink)', margin: '10px 0 0' }}>
            {allRecipes.length} recipes
            <span style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontWeight: 400,
              color: 'var(--olive)' }}> you cook.</span>
          </h1>
        </div>
        <FButton size="m" onClick={() => go('edit', { isNew: true })}>
          <Icon.plus size={16} />New recipe
        </FButton>
      </div>

      {/* Search + filters + sort */}
      <div style={{ padding: pad, display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap' }}>
        <SearchBar wide />
        <div style={{ flex: 1, minWidth: 280 }}><ChipRow /></div>
        <SortControl />
      </div>

      {/* Feature (only when not searching) */}
      {!searching && featured && (
        <div onClick={() => openRecipe(featured.id)} style={{ cursor: 'pointer',
          padding: compact ? '36px 32px 32px' : '26px 48px 32px', display: 'grid',
          gridTemplateColumns: '0.95fr 1.05fr', gap: compact ? 40 : 56, alignItems: 'stretch' }}>
          <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'flex-end',
            paddingBottom: 14 }}>
            <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 10, fontWeight: 600,
              letterSpacing: '0.28em', textTransform: 'uppercase', color: 'var(--olive)' }}>
              this week's pick
            </span>
            <FTitle name={featured.name} size={compact ? 44 : 54} lineHeight={0.95} breakBeforeWith={false} />
            <p style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontSize: compact ? 17 : 19,
              lineHeight: 1.5, color: 'var(--ink-2)', margin: '16px 0 0', maxWidth: 480 }}>
              {featured.description}
            </p>
            <div style={{ display: 'flex', alignItems: 'center', gap: 18, marginTop: 22,
              paddingTop: 18, borderTop: '1px solid var(--hairline)' }}>
              <Stars value={5} size={14} />
              <span style={{ width: 1, height: 16, background: 'var(--hairline)' }} />
              <span style={{ fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--ink-2)' }}>
                {window.LCDomain.costPerServeLabel(featured) ? `${window.LCDomain.costPerServeLabel(featured)} /serve` : 'no cost yet'} · 35 min · serves 4
              </span>
              <span style={{ flex: 1 }} />
              <FButton size="m">View →</FButton>
            </div>
          </div>
          <div style={{ position: 'relative', aspectRatio: compact ? '4 / 3.2' : '16 / 10', borderRadius: 18,
            overflow: 'hidden', boxShadow: '0 30px 80px rgba(0,0,0,0.5)' }}>
            <img src={photoFor(featured.id)} alt="" style={{ width: '100%', height: '100%',
              objectFit: 'cover', display: 'block' }} />
          </div>
        </div>
      )}

      {/* Grid header */}
      <div style={{ padding: compact ? '12px 32px 16px' : '12px 48px 16px', display: 'flex',
        alignItems: 'center', gap: 16 }}>
        <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 11, fontWeight: 600,
          letterSpacing: '0.28em', textTransform: 'uppercase', color: 'var(--olive)' }}>
          {searching ? `${list.length} ${list.length === 1 ? 'match' : 'matches'}` : 'The full library'}
        </span>
        <span style={{ flex: 1, height: 1, background: 'var(--hairline)' }} />
      </div>

      {/* Grid */}
      <div style={{ padding: compact ? '12px 32px 64px' : '12px 48px 80px' }}>
        {list.length === 0 ? <EmptyResults /> : (
          <div style={{ display: 'grid', gridTemplateColumns: `repeat(${cols}, 1fr)`,
            gap: '36px 24px' }}>
            {list.map((r) => <ClickableCard key={r.id} r={r} />)}
          </div>
        )}
      </div>
    </div>
  );
}

// ── Mobile ──
function LibraryMobile() {
  const { allRecipes, openRecipe, photoFor, state } = useApp();
  const list = useLibraryFilter();
  const featured = allRecipes.find((r) => r.id === 'sichuan-chicken');
  const searching = state.search || state.filter !== 'all';

  return (
    <div>
      <div style={{ padding: '24px 18px 16px' }}>
        <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 10, fontWeight: 600,
          letterSpacing: '0.28em', textTransform: 'uppercase', color: 'var(--olive)' }}>
          Your library
        </span>
        <h1 style={{ fontFamily: 'Bricolage Grotesque', fontWeight: 700, fontSize: 42,
          lineHeight: 0.95, letterSpacing: '-0.04em', color: 'var(--ink)', margin: '6px 0 0' }}>
          {allRecipes.length} recipes
          <span style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontWeight: 400,
            color: 'var(--olive)' }}> you cook.</span>
        </h1>
      </div>

      <div style={{ padding: '0 18px 14px', display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{ flex: 1 }}><SearchBar /></div>
        <SortControl iconOnly />
      </div>
      <div style={{ padding: '0 18px 18px' }}><ChipRow scroll /></div>

      {!searching && featured && (
        <div style={{ padding: '0 18px 24px' }}>
          <div onClick={() => openRecipe(featured.id)} style={{ position: 'relative',
            aspectRatio: '4 / 5', borderRadius: 18, overflow: 'hidden', cursor: 'pointer',
            boxShadow: '0 20px 50px rgba(0,0,0,0.5)' }}>
            <img src={photoFor(featured.id)} alt="" style={{ width: '100%', height: '100%',
              objectFit: 'cover', display: 'block' }} />
            <div style={{ position: 'absolute', top: 12, left: 12 }}>
              <FPill accent style={{ fontSize: 9 }}>★ THIS WEEK</FPill>
            </div>
            <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, padding: '20px 16px 16px',
              background: 'linear-gradient(180deg, transparent 0%, rgba(0,0,0,0.7) 30%, rgba(0,0,0,0.9) 100%)' }}>
              <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 9, fontWeight: 600,
                letterSpacing: '0.24em', textTransform: 'uppercase', color: 'var(--olive)' }}>
                Mains · Asian · Quick
              </span>
              <h2 style={{ fontFamily: 'Bricolage Grotesque', fontWeight: 700, fontSize: 32,
                lineHeight: 0.95, letterSpacing: '-0.04em', color: '#fff', margin: '8px 0 0' }}>
                sichuan-style cold chicken
                <span style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontWeight: 400,
                  color: 'var(--olive)' }}> with chilli oil.</span>
              </h2>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 10 }}>
                <Stars value={5} size={12} />
                <span style={{ fontFamily: 'var(--mono)', fontSize: 11, color: 'rgba(255,255,255,0.8)' }}>
                  {window.LCDomain.costPerServeLabel(featured) || '$4.20'} /serve · 35 min
                </span>
              </div>
            </div>
          </div>
        </div>
      )}

      <div style={{ padding: '0 18px 14px', display: 'flex', alignItems: 'center', gap: 10 }}>
        <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 10, fontWeight: 600,
          letterSpacing: '0.28em', textTransform: 'uppercase', color: 'var(--olive)' }}>
          {searching ? `${list.length} ${list.length === 1 ? 'match' : 'matches'}` : 'Full library'}
        </span>
        <span style={{ flex: 1, height: 1, background: 'var(--hairline)' }} />
      </div>

      <div style={{ padding: '0 18px 24px' }}>
        {list.length === 0 ? <EmptyResults /> : (
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '24px 14px' }}>
            {list.map((r) => <ClickableCard key={r.id} r={r} size="s" />)}
          </div>
        )}
      </div>
    </div>
  );
}

function LibraryScreen() {
  const { layout } = useApp();
  return (
    <Shell tab="recipes">
      {layout === 'mobile' ? <LibraryMobile /> : <LibraryWide compact={layout === 'tablet'} />}
    </Shell>
  );
}

Object.assign(window, { LibraryScreen });
