// Components.jsx — shared UI used across screens

function TypeTag({ type }) {
  const m = MAT_TYPE[type];
  return (
    <span className="tag" style={{ background: m.bg, color: m.tint }}>
      <span className="dot" style={{ background: m.tint }} /> {m.label}
    </span>);

}

function MatTile({ type, size = 36, radius = 10 }) {
  const m = MAT_TYPE[type];
  return (
    <span className="itile" style={{ width: size, height: size, borderRadius: radius, background: m.bg, color: m.tint }}>
      <Icon name={m.icon} size={size * 0.5} />
    </span>);

}

function ProgressBar({ value, lg }) {
  return <div className={'progress' + (lg ? ' lg' : '')}><i style={{ width: Math.max(2, value) + '%' }} /></div>;
}

function DueBadge({ count }) {
  if (!count) return <span className="tag" style={{ background: 'var(--surface-2)', color: 'var(--ink-3)' }}>up to date</span>;
  return <span className="tag" style={{ background: 'rgba(201,138,20,.14)', color: 'var(--warning)' }}>
    <span className="dot" style={{ background: 'var(--warning)' }} /> {count} due</span>;
}

function TopicCard({ topic, onOpen, onEdit, onDelete }) {
  const dom = domainById(topic.domain);
  return (
    <div className="card pad hover topic-card" onClick={() => onOpen(topic.id)}
    style={{ textAlign: 'left', display: 'flex', flexDirection: 'column', gap: 14, border: '1px solid var(--line)', cursor: 'pointer', position: 'relative' }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10 }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 9, fontFamily: 'var(--font-mono)', fontSize: 11,
          letterSpacing: '.03em', textTransform: 'uppercase', color: 'var(--ink-3)' }}>
          <span style={{ width: 9, height: 9, borderRadius: 99, background: dom.accent }} /> {dom.name}
        </span>
        <div className="topic-card-actions" style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
          {onEdit &&
          <button className="icon-btn tc-act" title="Edit topic" onClick={(e) => { e.stopPropagation(); onEdit(topic); }}
            style={{ width: 28, height: 28, border: 'none' }}><Icon name="edit" size={15} /></button>}
          {onDelete &&
          <button className="icon-btn tc-act tc-del" title="Delete topic" onClick={(e) => { e.stopPropagation(); onDelete(topic); }}
            style={{ width: 28, height: 28, border: 'none' }}><Icon name="trash" size={15} /></button>}
          <Icon name="arrow-up-right" size={16} style={{ color: 'var(--ink-4)' }} className="tc-arrow" />
        </div>
      </div>
      <div style={{ fontSize: 18, fontWeight: 600, letterSpacing: '-0.02em', lineHeight: 1.15 }}>{topic.name}</div>
      <ProgressBar value={topic.progress} />
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <span className="mono" style={{ fontSize: 12, color: 'var(--ink-3)' }}>{topic.notes} notes</span>
        <span className="mono" style={{ fontSize: 12, fontWeight: 600, color: 'var(--ink-2)' }}>{topic.progress}%</span>
      </div>
    </div>);

}

function MaterialCard({ mat, onOpen, onDelete }) {
  const m = MAT_TYPE[mat.type];
  const top = topicById(mat.topic);
  const activate = () => onOpen(mat);
  return (
    <div className="card hover material-card" role="button" tabIndex={0} onClick={activate}
    onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); activate(); } }}
    style={{ textAlign: 'left', display: 'flex', flexDirection: 'column', overflow: 'hidden', padding: 0, border: '1px solid var(--line)', cursor: 'pointer', position: 'relative' }}>
      <div style={{ height: 84, background: m.bg, display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative' }}>
        <MatTile type={mat.type} size={42} radius={12} />
        {mat.type === 'deck' && <span className="mono" style={{ position: 'absolute', bottom: 9, right: 11, fontSize: 11,
          color: m.tint, fontWeight: 600 }}>{mat.cards} cards</span>}
        {onDelete &&
        <button className="icon-btn mc-del" title="Delete material" onClick={(e) => { e.stopPropagation(); onDelete(mat); }}
          style={{ position: 'absolute', top: 8, left: 8, width: 28, height: 28, border: 'none' }}><Icon name="trash" size={15} /></button>}
      </div>
      <div style={{ padding: 14, display: 'flex', flexDirection: 'column', gap: 9, flex: 1 }}>
        <TypeTag type={mat.type} />
        <div style={{ fontSize: 14.5, fontWeight: 600, letterSpacing: '-0.01em', lineHeight: 1.25, color: "var(--ink)" }}>{mat.title}</div>
        <div style={{ marginTop: 'auto', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <span style={{ fontSize: 12, color: 'var(--ink-3)' }}>{top ? top.name : ''}</span>
          <span className="mono" style={{ fontSize: 11, color: 'var(--ink-3)' }}>{mat.updated}</span>
        </div>
      </div>
    </div>);

}

// Decorative constellation field (brand motif) — deterministic scattered dots
function ConstellationField({ opacity = 0.5 }) {
  const palette = ['#1E8FF0', '#2E7A3A', '#D49CEE', '#9FC09C', '#C7937D', '#ffffff'];
  const dots = React.useMemo(() => {
    let s = 7;
    const rnd = () => (s = (s * 9301 + 49297) % 233280) / 233280;
    return Array.from({ length: 46 }, () => ({
      x: rnd() * 100, y: rnd() * 100, r: 1.5 + rnd() * 3.5, c: palette[Math.floor(rnd() * palette.length)]
    }));
  }, []);
  const lines = [[2, 9], [9, 15], [20, 27], [27, 33], [33, 40]];
  return (
    <svg className="field" viewBox="0 0 100 100" preserveAspectRatio="none" style={{ opacity }}>
      {lines.map(([a, b], i) => dots[a] && dots[b] &&
      <line key={i} x1={dots[a].x} y1={dots[a].y} x2={dots[b].x} y2={dots[b].y}
      stroke="var(--ink-4)" strokeWidth="0.25" vectorEffect="non-scaling-stroke" />
      )}
      {dots.map((d, i) =>
      <circle key={i} cx={d.x} cy={d.y} r={d.r / 8} fill={d.c}
      stroke={d.c === '#ffffff' ? 'var(--line-strong)' : 'none'} strokeWidth="0.15" vectorEffect="non-scaling-stroke" />
      )}
    </svg>);

}

function EmptyHint({ icon, title, sub, action }) {
  return (
    <div className="card pad" style={{ textAlign: 'center', padding: '46px 30px', display: 'flex',
      flexDirection: 'column', alignItems: 'center', gap: 12 }}>
      <span className="itile" style={{ width: 52, height: 52, borderRadius: 14, background: 'var(--surface-2)', color: 'var(--ink-3)' }}>
        <Icon name={icon} size={24} /></span>
      <div style={{ fontSize: 17, fontWeight: 600 }}>{title}</div>
      <div className="t-body" style={{ maxWidth: '40ch' }}>{sub}</div>
      {action}
    </div>);

}

Object.assign(window, { TypeTag, MatTile, ProgressBar, DueBadge, TopicCard, MaterialCard, ConstellationField, EmptyHint });