// Trove — small generic UI bits used across screens

// Measures a thumbnail once and reports how many pages are side by side in it.
// Two-up sheets (main + answers) come through as one wide image, so we split them.
function useThumbPages(src) {
  const [pages, setPages] = React.useState(1);
  React.useEffect(() => {
    if (!src) { setPages(1); return; }
    let live = true;
    const img = new Image();
    img.onload = () => {
      if (!live || !img.naturalHeight) return;
      const ratio = img.naturalWidth / img.naturalHeight;
      // A single portrait page is ~0.7. Two portrait pages side by side are ~1.4.
      setPages(ratio > 1.15 ? 2 : 1);
    };
    img.src = src;
    return () => { live = false; };
  }, [src]);
  return pages;
}

function ResourceCover({ resource, size = 'md', page = null }) {
  // A faux PDF-cover: paper with the resource's subject + year + a key/nib mark
  const r = resource;
  const isMaths = r.subject === 'Maths';
  const isGold = r.accent === 'gold';
  const isNavy = r.accent === 'navy';
  const palette = isGold
    ? { bg: 'var(--gold-soft)', ink: 'var(--navy-900)', accent: 'var(--gold-deep)' }
    : isNavy
    ? { bg: 'var(--navy-900)', ink: '#FFFFFF', accent: 'var(--gold)' }
    : isMaths
    ? { bg: 'var(--cool-100)', ink: 'var(--navy-900)', accent: 'var(--gold-deep)' }
    : { bg: 'var(--cool-200)', ink: 'var(--navy-900)', accent: 'var(--gold-deep)' };

  const seed = r.id.charCodeAt(r.id.length - 1) + r.id.charCodeAt(r.id.length - 2);
  const variant = seed % 4;
  const thumbPages = useThumbPages(r.thumbnail);

  // Real thumbnail — render the actual PDF cover image instead of the stylized one
  if (r.thumbnail) {
    // `page` (0-based) shows one half of a two-up sheet; otherwise show page 1.
    const totalPages = thumbPages;
    const shown = page === null ? 0 : Math.min(page, totalPages - 1);
    const isSplit = totalPages > 1;
    return (
      <div
        className="resource-cover"
        style={{
          position: 'relative', width: '100%', aspectRatio: '3 / 4',
          background: '#FFFFFF',
          borderRadius: '6px',
          overflow: 'hidden', boxShadow: '0 1px 0 rgba(0,0,0,.06), inset 0 0 0 1px rgba(0,0,0,.08)',
        }}
      >
        {isSplit ? (
          <div style={{
            width: '100%', height: '100%',
            backgroundImage: `url(${r.thumbnail})`,
            backgroundSize: '200% 100%',
            backgroundPosition: shown === 0 ? 'left center' : 'right center',
            backgroundRepeat: 'no-repeat',
          }} />
        ) : (
          <img src={r.thumbnail} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'top' }} />
        )}
      </div>
    );
  }

  return (
    <div
      className="resource-cover"
      style={{
        position: 'relative', width: '100%', aspectRatio: '3 / 4',
        background: palette.bg, color: palette.ink,
        borderRadius: '6px',
        overflow: 'hidden', boxShadow: '0 1px 0 rgba(0,0,0,.06), inset 0 0 0 1px rgba(255,255,255,.5)',
        fontFamily: 'var(--font-sans)',
      }}
    >
      {/* paper grain */}
      <div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(circle at 30% 20%, rgba(255,255,255,.4), transparent 60%)', pointerEvents: 'none' }} />
      {/* top rail */}
      <div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 4, background: palette.accent }} />

      {variant === 0 && (
        <svg width="100%" height="100%" viewBox="0 0 120 160" preserveAspectRatio="xMidYMid slice" style={{ position: 'absolute', inset: 0, opacity: .14 }}>
          <g stroke={palette.accent} strokeWidth=".5" fill="none">
            {Array.from({ length: 18 }).map((_, i) => <line key={i} x1="0" x2="120" y1={i * 9 + 30} y2={i * 9 + 30} />)}
          </g>
        </svg>
      )}
      {variant === 1 && (
        <svg width="100%" height="100%" viewBox="0 0 120 160" preserveAspectRatio="xMidYMid slice" style={{ position: 'absolute', inset: 0, opacity: .12 }}>
          <g fill={palette.accent}>
            {Array.from({ length: 60 }).map((_, i) => <circle key={i} cx={(i * 13) % 120} cy={(i * 19) % 160} r=".7" />)}
          </g>
        </svg>
      )}
      {variant === 2 && (
        <svg width="100%" height="100%" viewBox="0 0 120 160" preserveAspectRatio="xMidYMid slice" style={{ position: 'absolute', inset: 0, opacity: .15 }}>
          <g stroke={palette.accent} strokeWidth=".4" fill="none">
            <path d="M0 100 Q 30 80 60 100 T 120 100" />
            <path d="M0 110 Q 30 90 60 110 T 120 110" />
            <path d="M0 120 Q 30 100 60 120 T 120 120" />
          </g>
        </svg>
      )}
      {variant === 3 && (
        <svg width="100%" height="100%" viewBox="0 0 120 160" preserveAspectRatio="xMidYMid slice" style={{ position: 'absolute', inset: 0, opacity: .12 }}>
          <g stroke={palette.accent} strokeWidth=".5" fill="none">
            {Array.from({ length: 8 }).map((_, i) => <rect key={i} x={i*8 + 30} y={70} width="3" height={i*4 + 10} />)}
          </g>
        </svg>
      )}

      <div style={{ position: 'absolute', inset: 0, padding: size === 'lg' ? '20px 18px' : '12px 11px', display: 'flex', flexDirection: 'column' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 6, fontSize: size === 'lg' ? 11 : 9, letterSpacing: '.08em', textTransform: 'uppercase', fontWeight: 600, opacity: .8 }}>
          <span>{r.subject}</span><span>{r.year}</span>
        </div>
        <div style={{ marginTop: 'auto' }}>
          <div style={{ fontFamily: 'var(--font-serif)', fontSize: size === 'lg' ? 22 : 13, fontWeight: 500, lineHeight: 1.15, letterSpacing: '-.01em' }}>
            {r.title.split(':')[0].trim()}
          </div>
          {r.title.includes(':') && (
            <div style={{ marginTop: 4, fontSize: size === 'lg' ? 12 : 9, opacity: .7, fontWeight: 500 }}>
              {r.title.split(':').slice(1).join(':').trim()}
            </div>
          )}
          <div style={{ marginTop: size === 'lg' ? 14 : 8, display: 'flex', alignItems: 'center', gap: 6, fontSize: size === 'lg' ? 10 : 8, opacity: .65, letterSpacing: '.05em', textTransform: 'uppercase', fontWeight: 600 }}>
            <span>{r.scheme}</span><span>•</span><span>{r.lessons} {r.lessons === 1 ? 'lesson' : 'lessons'}</span>
          </div>
        </div>
      </div>
    </div>
  );
}

function Stars({ value, count }) {
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, color: 'var(--fg-muted)', fontSize: 12.5 }}>
      <Icon.Star width="13" height="13" style={{ color: 'var(--gold-deep)' }} />
      <span style={{ color: 'var(--fg)', fontWeight: 600 }}>{value.toFixed(1)}</span>
      {count != null && <span style={{ color: 'var(--fg-subtle)' }}>({count})</span>}
    </span>
  );
}

function ResourceCard({ resource, onClick, density = 'md' }) {
  const r = resource;
  const subj = window.getSubject ? window.getSubject(r.subject) : { name: r.subject || 'Resource', color: '#5D6B85', bg: '#E7E9EF', accent: '#7A8AA8', Icon: null };
  const SubjIcon = subj.Icon;
  const [hover, setHover] = React.useState(false);
  // Deterministic tilt per card so the row reads as deliberate, not random.
  const seed = (r.id || '').split('').reduce((s, c) => s + c.charCodeAt(0), 0);
  const tilt = ((seed % 5) - 2); // -2..+2 degrees
  const cardThumbPages = useThumbPages(r.thumbnail);
  return (
    <button
      onClick={onClick}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      className="card focus-ring"
      style={{
        padding: 0, textAlign: 'left', cursor: 'pointer',
        display: 'flex', flexDirection: 'column', gap: 0,
        background: 'var(--surface)', overflow: 'hidden',
        transform: hover ? 'translateY(-3px)' : 'translateY(0)',
        boxShadow: hover ? `0 18px 32px -16px rgba(15,26,48,.28), 0 4px 10px -2px rgba(15,26,48,.10)` : 'var(--shadow-sm)',
        borderColor: hover ? subj.color : undefined,
        transition: 'transform .18s ease, box-shadow .18s ease, border-color .18s ease',
      }}
    >
      {/* Top: subject-coloured banner with icon + small tilted thumbnail sticker */}
      <div style={{
        position: 'relative', height: 140, background: subj.bg,
        borderBottom: `1px solid color-mix(in oklab, ${subj.color} 18%, var(--border))`,
        overflow: 'hidden',
      }}>
        {/* Big subject icon, low-opacity, top-left */}
        {SubjIcon && (
          <div style={{ position: 'absolute', left: 22, top: 22, color: subj.color, opacity: .9 }}>
            <SubjIcon width="56" height="56" />
          </div>
        )}
        {/* Subject label at the bottom */}
        <div style={{ position: 'absolute', left: 22, bottom: 16, display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{ color: subj.color, fontWeight: 700, fontSize: 13, letterSpacing: '.06em', textTransform: 'uppercase' }}>
            {subj.name}
          </span>
        </div>
        {/* Thumbnail sticker, top-right, deterministic tilt */}
        {r.thumbnail ? (
          <div style={{
            position: 'absolute', right: 14, top: 14, bottom: 14,
            width: 86, transform: `rotate(${tilt}deg)`,
            background: '#fff', padding: 3,
            boxShadow: '0 6px 14px -4px rgba(15,26,48,.28), 0 2px 4px rgba(15,26,48,.12)',
            borderRadius: 2,
            transition: 'transform .18s ease',
          }}>
            {cardThumbPages > 1 ? (
              <div style={{
                width: '100%', height: '100%', display: 'block',
                backgroundImage: `url(${r.thumbnail})`,
                backgroundSize: '200% 100%',
                backgroundPosition: 'left center',
                backgroundRepeat: 'no-repeat',
              }} />
            ) : (
              <img src={r.thumbnail} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'top', display: 'block' }} />
            )}
          </div>
        ) : (
          <div style={{
            position: 'absolute', right: 14, top: 14, bottom: 14,
            width: 86, transform: `rotate(${tilt}deg)`,
            background: '#fff', padding: 6,
            boxShadow: '0 6px 14px -4px rgba(15,26,48,.28), 0 2px 4px rgba(15,26,48,.12)',
            borderRadius: 2,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: subj.color, opacity: .35,
          }}>
            {SubjIcon && <SubjIcon width="32" height="32" />}
          </div>
        )}
      </div>
      <div style={{ padding: '12px 14px 14px', display: 'flex', flexDirection: 'column', gap: 8 }}>
        <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 6 }}>
          <span className={'pill ' + (r.ks === 'KS1' ? 'pill-ks1' : 'pill-ks2')}>{r.ks}{r.year ? ` · ${r.year}` : ''}</span>
          {r.isNew && (
            <span style={{
              display: 'inline-flex', alignItems: 'center', gap: 5,
              padding: '3px 9px', borderRadius: 999,
              background: subj.color, color: '#fff',
              fontSize: 10.5, fontWeight: 800, letterSpacing: '.08em', textTransform: 'uppercase',
              boxShadow: '0 1px 3px rgba(15,26,48,.18)',
            }}>
              <span style={{ width: 4, height: 4, borderRadius: 999, background: '#fff' }} />New
            </span>
          )}
        </div>
        <div className="t-h3" style={{ display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden', textWrap: 'pretty', minHeight: '2.4em' }}>
          {r.title}
        </div>
        {r.objectiveText && (
          <div style={{ fontSize: 12.5, color: 'var(--fg-muted)', lineHeight: 1.45, display: '-webkit-box', WebkitLineClamp: 1, WebkitBoxOrient: 'vertical', overflow: 'hidden', textOverflow: 'ellipsis', textWrap: 'pretty' }}>
            {r.objectiveText}
          </div>
        )}
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 'auto', paddingTop: 6, borderTop: '1px solid var(--border)', gap: 8 }}>
          <span style={{
            display: 'inline-flex', alignItems: 'center', gap: 5,
            padding: '3px 9px', borderRadius: 999,
            background: 'var(--bg-sunken)', color: 'var(--fg-muted)',
            fontSize: 11.5, fontWeight: 600,
            border: '1px solid var(--border)',
            letterSpacing: '.01em',
          }}>{r.type || 'Worksheet'}</span>
          {r.reviews > 0 ? (
            <Stars value={r.rating} count={r.reviews} />
          ) : (
            <span style={{ fontSize: 11.5, color: 'var(--fg-subtle)', fontWeight: 500 }}>{r.pages} {r.pages === 1 ? 'page' : 'pages'}</span>
          )}
        </div>
      </div>
    </button>
  );
}

function TroveLogoMark({ color = 'currentColor', goldColor = 'var(--gold)', size = 24 }) {
  // A simplified mark inspired by the logo: pen-nib joined to key teeth, with a gold band.
  return (
    <svg width={size} height={size} viewBox="0 0 32 32" fill="none" aria-hidden="true">
      <path d="M9 2 L17 13 L13 16 L4 5 Z" fill={color} />
      <circle cx="9.5" cy="6.5" r="1.4" fill="var(--surface,#fff)" />
      <rect x="11" y="14.5" width="6" height="2.6" fill={goldColor} />
      <path d="M13 17 L13 25 L11 25 L11 28 L14 28 L14 30 L17 30 L17 19 L13 17 Z" fill={color} />
    </svg>
  );
}

window.ResourceCover = ResourceCover;
window.useThumbPages = useThumbPages;
window.ResourceCard = ResourceCard;
window.Stars = Stars;
window.TroveLogoMark = TroveLogoMark;
