/* knowledge-base.jsx — Research portal section for OnCourt
   Renders LIVE from the shared data layer (window.ResearchData). No placeholders.
   Cards open the real submitted material (download a file / open a link). */

const RESEARCH_CATEGORIES = ['All'].concat(window.ResearchData.CATEGORIES);

const kbStyles = {
  section: {
    background: 'var(--surface-inverse)',
    padding: 'clamp(2rem, 4vw, 3rem) 0 clamp(4rem, 10vw, 8rem)',
    position: 'relative',
    overflow: 'hidden'
  },
  inner: {
    maxWidth: 'var(--container-wide)',
    margin: '0 auto',
    padding: '0 var(--gutter)'
  },
  filters: {
    display: 'flex',
    flexWrap: 'wrap',
    gap: 'var(--space-2)',
    marginBottom: 'var(--space-7)'
  },
  filterBtn: (active) => ({
    fontFamily: 'var(--font-label)',
    fontWeight: 'var(--weight-medium)',
    fontSize: '0.8125rem',
    letterSpacing: 'var(--tracking-label)',
    textTransform: 'uppercase',
    padding: '10px 20px',
    borderRadius: 'var(--radius-pill)',
    border: active ? '1px solid var(--flame-500)' : '1px solid var(--border-inverse)',
    background: active ? 'var(--flame-500)' : 'transparent',
    color: active ? '#fff' : 'var(--graphite-300)',
    cursor: 'pointer',
    transition: 'all var(--dur-fast) var(--ease-standard)',
    whiteSpace: 'nowrap'
  }),
  grid: {
    display: 'grid',
    gridTemplateColumns: 'repeat(3, minmax(0, 400px))',
    justifyContent: 'center',
    gap: 'var(--space-5)'
  },
  card: {
    background: 'var(--graphite-800)',
    borderRadius: 'var(--radius-md)',
    padding: 'var(--space-6)',
    border: '1px solid rgba(255,255,255,0.06)',
    cursor: 'pointer',
    transition: 'transform var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-standard)',
    display: 'flex',
    flexDirection: 'column',
    gap: 'var(--space-4)',
    textAlign: 'left',
    minHeight: 260
  },
  cardHover: {
    transform: 'translateY(-2px)',
    borderColor: 'rgba(255,255,255,0.12)'
  },
  cardTopRow: {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    gap: 'var(--space-3)'
  },
  cardType: {
    fontFamily: 'var(--font-label)',
    fontWeight: 'var(--weight-medium)',
    fontSize: '0.6875rem',
    letterSpacing: 'var(--tracking-eyebrow)',
    textTransform: 'uppercase',
    color: 'var(--flame-400)'
  },
  formatBadge: {
    display: 'inline-flex',
    alignItems: 'center',
    gap: 6,
    fontFamily: 'var(--font-label)',
    fontWeight: 'var(--weight-medium)',
    fontSize: '0.625rem',
    letterSpacing: '0.1em',
    textTransform: 'uppercase',
    color: 'var(--graphite-300)',
    border: '1px solid rgba(255,255,255,0.12)',
    borderRadius: 'var(--radius-pill)',
    padding: '4px 10px',
    flexShrink: 0
  },
  cardTitle: {
    fontFamily: 'var(--font-display)',
    fontWeight: 'var(--weight-medium)',
    fontSize: 'var(--fs-h4)',
    lineHeight: 'var(--leading-snug)',
    color: 'var(--text-on-ink)',
    letterSpacing: 'var(--tracking-tight)',
    display: '-webkit-box',
    WebkitLineClamp: 2,
    WebkitBoxOrient: 'vertical',
    overflow: 'hidden',
    overflowWrap: 'anywhere',
    wordBreak: 'break-word',
    minWidth: 0
  },
  cardSummary: {
    fontFamily: 'var(--font-sans)',
    fontSize: 'var(--fs-body-sm)',
    lineHeight: 'var(--leading-body)',
    color: 'var(--graphite-400)',
    margin: 0,
    display: '-webkit-box',
    WebkitLineClamp: 2,
    WebkitBoxOrient: 'vertical',
    overflow: 'hidden'
  },
  cardTags: {
    display: 'flex',
    flexWrap: 'wrap',
    gap: 'var(--space-2)'
  },
  cardTag: {
    fontFamily: 'var(--font-label)',
    fontSize: '0.6875rem',
    letterSpacing: '0.04em',
    padding: '4px 10px',
    borderRadius: 'var(--radius-pill)',
    background: 'rgba(255,255,255,0.05)',
    color: 'var(--graphite-300)'
  },
  cardMeta: {
    display: 'flex',
    alignItems: 'center',
    gap: 'var(--space-3)',
    fontFamily: 'var(--font-sans)',
    fontSize: 'var(--fs-caption)',
    color: 'var(--graphite-400)',
    marginTop: 'auto',
    paddingTop: 'var(--space-2)'
  },
  cardAction: {
    display: 'inline-flex',
    alignItems: 'center',
    gap: 6,
    fontFamily: 'var(--font-label)',
    fontWeight: 'var(--weight-medium)',
    fontSize: '0.6875rem',
    letterSpacing: '0.1em',
    textTransform: 'uppercase',
    color: 'var(--flame-400)',
    marginLeft: 'auto'
  },
  dot: {
    width: 3, height: 3,
    borderRadius: '50%',
    background: 'var(--graphite-500)',
    flexShrink: 0
  },
  emptyWrap: {
    border: '1px dashed rgba(255,255,255,0.14)',
    borderRadius: 'var(--radius-lg)',
    padding: 'clamp(3rem, 8vw, 6rem) var(--gutter)',
    textAlign: 'center',
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    gap: 'var(--space-4)'
  },
  emptyTitle: {
    fontFamily: 'var(--font-display)',
    fontWeight: 'var(--weight-medium)',
    fontSize: 'var(--fs-h3)',
    color: 'var(--text-on-ink)',
    letterSpacing: 'var(--tracking-tight)'
  },
  emptyText: {
    fontFamily: 'var(--font-sans)',
    fontSize: 'var(--fs-body)',
    color: 'var(--graphite-400)',
    maxWidth: 420,
    lineHeight: 'var(--leading-body)'
  },
  pager: {
    marginTop: 'var(--space-8)',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    gap: 'var(--space-4)'
  },
  pagerBtn: (disabled) => ({
    display: 'inline-flex',
    alignItems: 'center',
    gap: 7,
    fontFamily: 'var(--font-label)',
    fontWeight: 'var(--weight-medium)',
    fontSize: '0.75rem',
    letterSpacing: 'var(--tracking-label)',
    textTransform: 'uppercase',
    color: disabled ? 'var(--graphite-500)' : 'var(--graphite-300)',
    background: 'transparent',
    border: '1px solid ' + (disabled ? 'rgba(255,255,255,0.06)' : 'rgba(255,255,255,0.14)'),
    borderRadius: 'var(--radius-pill)',
    padding: '9px 16px',
    cursor: disabled ? 'default' : 'pointer',
    opacity: disabled ? 0.5 : 1,
    transition: 'all var(--dur-fast) var(--ease-standard)'
  }),
  pagerLabel: {
    fontFamily: 'var(--font-sans)',
    fontSize: 'var(--fs-caption)',
    color: 'var(--graphite-400)',
    letterSpacing: '0.02em',
    minWidth: 96,
    textAlign: 'center'
  }
};

const PAGE_SIZE = 9; // 3 rows × 3 columns

/* ── Format icons ──────────────────────────────────────────────── */
function FormatIcon({ format }) {
  const common = { width: 13, height: 13, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' };
  if (format === 'Video') {
    return React.createElement('svg', common,
      React.createElement('path', { d: 'M10 8l6 4-6 4V8z' }),
      React.createElement('rect', { x: 2, y: 4, width: 20, height: 16, rx: 3 })
    );
  }
  if (format === 'Link') {
    return React.createElement('svg', common,
      React.createElement('path', { d: 'M10 13a5 5 0 007 0l2-2a5 5 0 00-7-7l-1 1' }),
      React.createElement('path', { d: 'M14 11a5 5 0 00-7 0l-2 2a5 5 0 007 7l1-1' })
    );
  }
  if (format === 'Slides') {
    return React.createElement('svg', common,
      React.createElement('rect', { x: 3, y: 4, width: 18, height: 12, rx: 2 }),
      React.createElement('path', { d: 'M8 20h8M12 16v4' })
    );
  }
  // PDF / Document
  return React.createElement('svg', common,
    React.createElement('path', { d: 'M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z' }),
    React.createElement('path', { d: 'M14 2v6h6' })
  );
}

function ActionArrowIcon() {
  return React.createElement('svg', { width: 13, height: 13, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' },
    React.createElement('path', { d: 'M5 12h14M13 6l6 6-6 6' })
  );
}

function openItem(item) {
  const action = window.ResearchData.resolveAction(item);
  if (!action) return;
  if (action.kind === 'url') {
    window.open(action.href, '_blank', 'noopener,noreferrer');
  } else {
    const a = document.createElement('a');
    a.href = action.href;
    a.download = action.download || 'material';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  }
}

function ArticleCard({ item }) {
  const [hover, setHover] = React.useState(false);
  const fmt = window.ResearchData.FORMATS[item.format] || window.ResearchData.FORMATS.PDF;
  return React.createElement('article', {
    style: { ...kbStyles.card, ...(hover ? kbStyles.cardHover : {}) },
    onMouseEnter: () => setHover(true),
    onMouseLeave: () => setHover(false),
    onClick: () => openItem(item),
    role: 'button',
    tabIndex: 0,
    onKeyDown: (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); openItem(item); } }
  },
    React.createElement('div', { style: kbStyles.cardTopRow },
      React.createElement('span', { style: kbStyles.cardType }, item.typeLabel || item.category),
      React.createElement('span', { style: kbStyles.formatBadge },
        React.createElement(FormatIcon, { format: item.format }),
        fmt.label
      )
    ),
    React.createElement('h3', { style: kbStyles.cardTitle }, item.title),
    item.summary ? React.createElement('p', { style: kbStyles.cardSummary }, item.summary) : null,
    item.tags && item.tags.length
      ? React.createElement('div', { style: kbStyles.cardTags },
          item.tags.map(tag => React.createElement('span', { key: tag, style: kbStyles.cardTag }, tag))
        )
      : null,
    React.createElement('div', { style: kbStyles.cardMeta },
      React.createElement('span', null, item.date),
      item.meta ? React.createElement('span', { style: kbStyles.dot }) : null,
      item.meta ? React.createElement('span', null, item.meta) : null,
      (item.publisherLogo || item.publisherName)
        ? React.createElement('span', { style: kbStyles.dot })
        : null,
      item.publisherLogo
        ? React.createElement('img', { src: item.publisherLogo, alt: item.publisherName || 'Publisher', style: { height: 40, maxWidth: 64, objectFit: 'contain', borderRadius: 4, flexShrink: 0 } })
        : item.publisherName
        ? React.createElement('span', null, item.publisherName)
        : null,
      React.createElement('span', { style: kbStyles.cardAction },
        fmt.verb,
        React.createElement(ActionArrowIcon)
      )
    )
  );
}

function LoadingState() {
  return React.createElement('div', { style: kbStyles.emptyWrap },
    React.createElement('div', {
      style: {
        width: 34, height: 34, borderRadius: '50%',
        border: '2px solid rgba(255,255,255,0.14)',
        borderTopColor: 'var(--flame-500)',
        animation: 'spin 0.8s linear infinite'
      }
    }),
    React.createElement('p', { style: kbStyles.emptyText }, 'Loading research…')
  );
}

function PagerArrow({ dir }) {
  return React.createElement('svg', { width: 14, height: 14, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' },
    dir === 'prev'
      ? React.createElement('path', { d: 'M19 12H5M11 18l-6-6 6-6' })
      : React.createElement('path', { d: 'M5 12h14M13 6l6 6-6 6' })
  );
}

function Pager({ page, totalPages, onPrev, onNext }) {
  const atStart = page <= 1;
  const atEnd = page >= totalPages;
  const hover = (e, on) => {
    if (e.currentTarget.getAttribute('data-disabled') === 'true') return;
    e.currentTarget.style.borderColor = on ? 'var(--flame-500)' : 'rgba(255,255,255,0.14)';
    e.currentTarget.style.color = on ? 'var(--flame-400)' : 'var(--graphite-300)';
  };
  return React.createElement('div', { style: kbStyles.pager },
    React.createElement('button', {
      type: 'button', onClick: atStart ? undefined : onPrev, disabled: atStart,
      'data-disabled': atStart ? 'true' : 'false',
      style: kbStyles.pagerBtn(atStart),
      onMouseEnter: (e) => hover(e, true), onMouseLeave: (e) => hover(e, false)
    }, React.createElement(PagerArrow, { dir: 'prev' }), 'Prev'),
    React.createElement('span', { style: kbStyles.pagerLabel }, 'Page ' + page + ' of ' + totalPages),
    React.createElement('button', {
      type: 'button', onClick: atEnd ? undefined : onNext, disabled: atEnd,
      'data-disabled': atEnd ? 'true' : 'false',
      style: kbStyles.pagerBtn(atEnd),
      onMouseEnter: (e) => hover(e, true), onMouseLeave: (e) => hover(e, false)
    }, 'Next', React.createElement(PagerArrow, { dir: 'next' }))
  );
}

function KnowledgeBase() {
  const [activeFilter, setActiveFilter] = React.useState('All');
  const [items, setItems] = React.useState([]);
  const [loaded, setLoaded] = React.useState(false);
  const [page, setPage] = React.useState(1);

  React.useEffect(() => {
    let alive = true;
    const load = () => window.ResearchData.getAll().then(list => {
      if (alive) { setItems(list); setLoaded(true); }
    });
    load();
    const unsub = window.ResearchData.subscribe(load);
    return () => { alive = false; unsub(); };
  }, []);

  const filtered = activeFilter === 'All'
    ? items
    : items.filter(a => a.category === activeFilter);

  // Reset to first page whenever the filter changes or the result set shrinks.
  React.useEffect(() => { setPage(1); }, [activeFilter]);

  const totalPages = Math.max(1, Math.ceil(filtered.length / PAGE_SIZE));
  const safePage = Math.min(page, totalPages);
  const pageItems = filtered.slice((safePage - 1) * PAGE_SIZE, safePage * PAGE_SIZE);

  const goPage = (n) => {
    setPage(n);
    // Bring the grid back into view when paging.
    const sec = document.getElementById('research');
    if (sec) sec.scrollIntoView({ behavior: 'smooth', block: 'start' });
  };

  // Only surface categories that actually have material (plus "All").
  const present = new Set(items.map(i => i.category));
  const visibleCategories = RESEARCH_CATEGORIES.filter(c => c === 'All' || present.has(c));

  return React.createElement('section', { id: 'research', style: kbStyles.section },
    React.createElement('div', { style: kbStyles.inner },
      // Category filters (only show if there is anything to filter)
      items.length
        ? React.createElement('div', { style: kbStyles.filters },
            visibleCategories.map(cat =>
              React.createElement('button', {
                key: cat,
                style: kbStyles.filterBtn(activeFilter === cat),
                onClick: () => setActiveFilter(cat)
              }, cat)
            )
          )
        : null,

      // Loading → Grid. A spinner shows during the initial Supabase fetch so
      // the grid never flashes empty. There is no empty-state message: the
      // library is always populated, so nothing is rendered if items is empty.
      !loaded
        ? React.createElement(LoadingState)
        : items.length
        ? React.createElement('div', { className: 'oc-research-grid', style: kbStyles.grid },
            pageItems.map((item) => React.createElement(ArticleCard, { key: item.id, item }))
          )
        : null,

      // Subtle pager — only when there is more than one page
      items.length && totalPages > 1
        ? React.createElement(Pager, {
            page: safePage,
            totalPages: totalPages,
            onPrev: () => goPage(safePage - 1),
            onNext: () => goPage(safePage + 1)
          })
        : null
    )
  );
}

window.KnowledgeBase = KnowledgeBase;
