/* maydays — shared components */
const { useState, useEffect, useRef, useMemo } = React;

/* ============================================================
   Botanical SVG accents
   ============================================================ */

// Tiny sprig (3 small leaves on a curved stem)
function BotanicalSprig({ size = 24, color = 'var(--sage)' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" style={{ display:'inline-block', verticalAlign:'middle' }}>
      <path d="M12 22 C 12 14, 12 8, 12 2" stroke={color} strokeWidth="1" strokeLinecap="round"/>
      <path d="M12 18 Q 6 16, 4 11" stroke={color} strokeWidth="1" strokeLinecap="round" fill="none"/>
      <path d="M12 14 Q 18 12, 20 7"  stroke={color} strokeWidth="1" strokeLinecap="round" fill="none"/>
      <path d="M12 10 Q 7 8,  6 4"    stroke={color} strokeWidth="1" strokeLinecap="round" fill="none"/>
      <path d="M12 6  Q 16 5,  18 2"  stroke={color} strokeWidth="1" strokeLinecap="round" fill="none"/>
      <circle cx="4"  cy="11" r="1"   fill={color} />
      <circle cx="20" cy="7"  r="1"   fill={color} />
      <circle cx="6"  cy="4"  r="1"   fill={color} />
      <circle cx="18" cy="2"  r="0.8" fill={color} />
      <circle cx="12" cy="2"  r="1.1" fill={color} />
    </svg>
  );
}

// A small fern/branch with paired leaves
function BotanicalFern({ size = 28, color = 'var(--sage)' }) {
  const leaves = [];
  for (let i = 0; i < 5; i++) {
    const y = 4 + i * 4;
    const len = 7 - i * 0.8;
    leaves.push(
      <g key={i}>
        <ellipse cx={12 - len/2} cy={y} rx={len/2} ry="1.4" fill={color} opacity="0.55" />
        <ellipse cx={12 + len/2} cy={y} rx={len/2} ry="1.4" fill={color} opacity="0.55" />
      </g>
    );
  }
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" style={{ display:'inline-block', verticalAlign:'middle' }}>
      <line x1="12" y1="2" x2="12" y2="22" stroke={color} strokeWidth="1.1" strokeLinecap="round" />
      {leaves}
    </svg>
  );
}

// A vine running vertically (for lesson margin)
function VineColumn({ height = 800, color = 'var(--sage)' }) {
  // Make a wavy stem with little leaf pairs
  const segments = Math.floor(height / 60);
  const stops = [];
  for (let i = 0; i <= segments; i++) {
    const y = (i / segments) * 100;
    const x = 50 + Math.sin(i * 1.1) * 18;
    stops.push([x, y]);
  }
  const path = stops.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p[0]} ${p[1]}`).join(' ');
  return (
    <svg viewBox="0 0 100 100" preserveAspectRatio="none"
         style={{ width: '100%', height: '100%', opacity: 0.5 }}>
      <path d={path} stroke={color} strokeWidth="0.8" fill="none" strokeLinecap="round" />
      {stops.filter((_,i) => i > 0 && i < stops.length-1).map(([x,y], i) => {
        const left = i % 2 === 0;
        const lx = left ? x - 10 : x + 10;
        return (
          <g key={i}>
            <ellipse cx={lx} cy={y} rx="6" ry="2" fill={color} opacity="0.35"
                     transform={`rotate(${left ? -20 : 20} ${lx} ${y})`} />
            <circle cx={x} cy={y} r="0.8" fill={color} />
          </g>
        );
      })}
    </svg>
  );
}

// Horizontal branch divider (replaces the simple line divider sometimes)
function BranchDivider({ color = 'var(--sage)' }) {
  return (
    <div style={{ display:'flex', alignItems:'center', gap: 14, margin: '28px 0', color }}>
      <div style={{ flex: 1, height: 1, background: 'var(--line)' }} />
      <svg width="120" height="20" viewBox="0 0 120 20" style={{ flexShrink: 0 }}>
        <path d="M2 10 L 118 10" stroke={color} strokeWidth="0.8" />
        <ellipse cx="20" cy="10" rx="5" ry="1.6" transform="rotate(-25 20 10)" fill={color} opacity="0.5"/>
        <ellipse cx="35" cy="10" rx="5" ry="1.6" transform="rotate(25 35 10)" fill={color} opacity="0.5"/>
        <ellipse cx="85" cy="10" rx="5" ry="1.6" transform="rotate(-25 85 10)" fill={color} opacity="0.5"/>
        <ellipse cx="100" cy="10" rx="5" ry="1.6" transform="rotate(25 100 10)" fill={color} opacity="0.5"/>
        <circle cx="60" cy="10" r="2.5" fill="none" stroke={color} strokeWidth="0.8"/>
        <circle cx="60" cy="10" r="0.9" fill={color}/>
      </svg>
      <div style={{ flex: 1, height: 1, background: 'var(--line)' }} />
    </div>
  );
}

// Corner ornament (botanical curlicue)
function CornerOrnament({ color = 'var(--sage)' }) {
  return (
    <svg width="36" height="36" viewBox="0 0 36 36" fill="none">
      <path d="M2 2 Q 18 2, 18 18 Q 18 2, 34 2" stroke={color} strokeWidth="0.9" fill="none"/>
      <circle cx="18" cy="18" r="1.3" fill={color} />
      <ellipse cx="10" cy="6" rx="3" ry="1" fill={color} opacity="0.4" />
      <ellipse cx="26" cy="6" rx="3" ry="1" fill={color} opacity="0.4" />
    </svg>
  );
}

const ORN = { fleuron: '❦', flower: '❀', leaf: '☘', sprig: '❧' };

/* ============================================================
   Brand mark (maydays with M and D highlighted = MD)
   ============================================================ */
function BrandText() {
  return (
    <span className="brand">
      <span className="md">m</span>ay<span className="md">d</span>ays
    </span>
  );
}
function BrandMark() {
  // simple botanical mark instead of the M·D circle
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', color: 'var(--sage-2)' }}>
      <BotanicalFern size={26} color="var(--sage-2)" />
    </span>
  );
}

/* ============================================================
   Header / Crumbs / Footer
   ============================================================ */

function Header({ route, onNavigate, onOpenSearch }) {
  // any library-related route (the Step hubs, deep pages, Progress) lights up the Library tab
  const libraryRouteNames = ['library','step','subject','topic','lesson','progress'];
  const rdxRouteNames     = ['rapids','rapids-filter','rapids-quiz','rdx','rdx-section'];
  const toolsRouteNames   = ['tools'];

  const isLibActive  = libraryRouteNames.includes(route.name);
  const isRdxActive  = rdxRouteNames.includes(route.name);
  const isToolsActive= toolsRouteNames.includes(route.name);

  return (
    <header className="hdr">
      <div className="logo" onClick={() => onNavigate({ name: 'home' })}>
        <BrandMark />
        <BrandText />
      </div>
      <nav>
        <a className={route.name === 'home' ? 'active' : ''} onClick={() => onNavigate({ name: 'home' })}>Home</a>

        <HeaderDropdown
          label="Library"
          active={isLibActive}
          onActivate={() => onNavigate({ name: 'library' })}
          items={[
            { id: 'step2',    label: 'Step 2 CK', desc: 'Clinical knowledge by rotation.',     go: { name: 'step', stepId: 'step2' } },
            { id: 'bugs',     label: 'Bugs',      desc: 'Microbiology browser.',               go: { name: 'step', stepId: 'bugs'  } },
            { id: 'drugs',    label: 'Drugs',     desc: 'Pharmacology by class.',              go: { name: 'step', stepId: 'drugs' } },
            { id: 'progress', label: 'Progress',  desc: 'Where you are strong and weak.',      go: { name: 'progress' } },
          ]}
          onPick={(item) => onNavigate(item.go)}
        />

        <a className={isRdxActive ? 'active' : ''} onClick={() => onNavigate({ name: 'rapids' })}>Rapids</a>
        <a className={isToolsActive ? 'active' : ''} onClick={() => onNavigate({ name: 'tools' })}>Tools</a>
      </nav>
      <div className="grow" />
      <div className="search" onClick={onOpenSearch}>
        <span style={{ flex: 1 }}>Search the curriculum</span>
        <kbd>⌘K</kbd>
      </div>
      <AccountMenu onNavigate={onNavigate} />
    </header>
  );
}

/* ---------- Header dropdown (hover/focus) ---------- */
function HeaderDropdown({ label, active, items, onPick, onActivate }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  const closeTimer = useRef(null);

  const openNow  = () => { clearTimeout(closeTimer.current); setOpen(true); };
  const closeSoon = () => { clearTimeout(closeTimer.current); closeTimer.current = setTimeout(() => setOpen(false), 120); };

  // close on outside click / esc
  useEffect(() => {
    const onDoc = e => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    const onKey = e => { if (e.key === 'Escape') setOpen(false); };
    document.addEventListener('mousedown', onDoc);
    document.addEventListener('keydown', onKey);
    return () => { document.removeEventListener('mousedown', onDoc); document.removeEventListener('keydown', onKey); };
  }, []);

  return (
    <div className="hdr-dropdown" ref={ref}
         onMouseEnter={openNow}
         onMouseLeave={closeSoon}>
      <a className={`hdr-dd-trigger ${active ? 'active' : ''}`}
         onClick={() => { onActivate && onActivate(); setOpen(false); }}>
        {label}
        <span className="hdr-dd-caret">▾</span>
      </a>
      <div className={`hdr-dd-menu ${open ? 'open' : ''}`}
           onMouseEnter={openNow}
           onMouseLeave={closeSoon}>
        {items.map(it => (
          <button key={it.id} className="hdr-dd-item"
                  onClick={() => { onPick(it); setOpen(false); }}>
            <div className="hdr-dd-item-l">
              <BotanicalSprig size={16} color="var(--sage)" />
            </div>
            <div className="hdr-dd-item-text">
              <div className="hdr-dd-item-title">{it.label}</div>
              <div className="hdr-dd-item-desc">{it.desc}</div>
            </div>
          </button>
        ))}
      </div>
    </div>
  );
}

function Crumbs({ items, onNavigate }) {
  return (
    <div className="crumbs">
      {items.map((it, i) => (
        <React.Fragment key={i}>
          {i > 0 && <span className="sep">/</span>}
          {it.to
            ? <a onClick={() => onNavigate(it.to)} style={{ cursor: 'pointer' }}>{it.label}</a>
            : <span className={i === items.length - 1 ? 'last' : ''}>{it.label}</span>}
        </React.Fragment>
      ))}
    </div>
  );
}

function Footer() {
  return (
    <footer className="foot">
      <div>© maydays · est. 2026 · A study companion for Step 1 and Step 2 CK</div>
      <div className="flourish" style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <BotanicalSprig size={18} color="var(--sage)" />
        <span style={{ fontSize: 18, fontFamily: 'Newsreader, serif' }}>{ORN.fleuron}</span>
        <BotanicalFern size={18} color="var(--sage)" />
      </div>
      <div className="mono">v0.2 · prototype</div>
    </footer>
  );
}

/* ============================================================
   Mastery dots / progress / subject card
   ============================================================ */

function MasteryDots({ value }) {
  const cls = (target) => {
    if (value === 'm') return 'm';
    if (value === 'l' && target <= 1) return 'l';
    return '';
  };
  return (
    <span className="mastery" title={
      value === 'm' ? 'Mastered' : value === 'l' ? 'Learning' : 'Not started'
    }>
      <i className={cls(0)} />
      <i className={cls(1)} />
      <i className={cls(2)} />
    </span>
  );
}

function Progress({ value, tone = 'clay' }) {
  return (
    <div className={`prog ${tone === 'sage' ? 'sage' : ''}`}>
      <i style={{ width: `${Math.max(0, Math.min(100, value || 0))}%` }} />
    </div>
  );
}

function SubjectCard({ subject, onClick }) {
  return (
    <div className="card hov subject-card" onClick={onClick}>
      <div style={{ position:'absolute', top: 10, right: 10, opacity: 0.6 }}>
        <BotanicalFern size={26} color="var(--sage)" />
      </div>
      <div className="head">
        <div className="ttl">{subject.title}</div>
      </div>
      <div className="desc">{subject.blurb}</div>
      <div className="row" style={{ gap: 10 }}>
        <MasteryDots value={subject.mastery} />
        <span className="meta">{subject.progress}% · {subject.topics.length} topics · {subject.count} cards</span>
      </div>
      <Progress value={subject.progress} />
      <div className="foot">
        <span className="badge">{subject.topics.length} topics</span>
        <span>Open →</span>
      </div>
    </div>
  );
}

/* ============================================================
   Botanical placeholder frame
   ============================================================ */
function BotanicalFrame({ label = 'botanical · placeholder', height }) {
  return (
    <div className="botanical-frame" style={ height ? { aspectRatio: 'auto', height } : null }>
      <div className="stripe" />
      <div className="inner-border" />
      <div className="corner c1">{ORN.fleuron}</div>
      <div className="corner c2">{ORN.fleuron}</div>
      <div className="corner c3">{ORN.fleuron}</div>
      <div className="corner c4">{ORN.fleuron}</div>
      <div className="label">{label}</div>
    </div>
  );
}

/* ============================================================
   Anki button (visual only for now — wires up later via AnkiConnect)
   ============================================================ */
function AnkiButton({ label = 'Send deck to Anki', count = null, onClick }) {
  return (
    <span className="tip-wrap">
      <button className="anki-btn" onClick={onClick || (() => {})} type="button">
        <span className="ico">{ORN.leaf}</span>
        <span>{label}{count != null ? ` (${count})` : ''}</span>
        <span style={{ opacity: 0.6, fontSize: 11, fontFamily: 'JetBrains Mono, monospace' }}>+anki</span>
      </button>
      <span className="tip">Coming soon. Will sync via the AnkiConnect addon.</span>
    </span>
  );
}

/* ============================================================
   Search Overlay
   ============================================================ */
function SearchOverlay({ open, onClose, onNavigate, index }) {
  const [q, setQ] = useState('');
  const [hl, setHl] = useState(0);
  const inputRef = useRef(null);

  useEffect(() => {
    if (open) {
      setQ(''); setHl(0);
      setTimeout(() => inputRef.current && inputRef.current.focus(), 50);
    }
  }, [open]);

  const filtered = useMemo(() => {
    if (!q.trim()) return index.slice(0, 18);
    const needle = q.toLowerCase();
    const score = (it) => {
      const t = it.title.toLowerCase();
      if (t === needle) return 0;
      if (t.startsWith(needle)) return 1;
      if (t.includes(needle)) return 2;
      if (it.path.toLowerCase().includes(needle)) return 3;
      return 99;
    };
    return index
      .map(it => ({ it, s: score(it) }))
      .filter(x => x.s < 99)
      .sort((a,b) => a.s - b.s)
      .slice(0, 30)
      .map(x => x.it);
  }, [q, index]);

  if (!open) return null;

  const choose = (it) => {
    const { stepId, subjectId, topicId, subtopicId } = it.ref;
    if (subtopicId) onNavigate({ name: 'lesson', stepId, subjectId, topicId, subtopicId });
    else if (topicId) onNavigate({ name: 'topic', stepId, subjectId, topicId });
    else if (subjectId) onNavigate({ name: 'subject', stepId, subjectId });
    else onNavigate({ name: 'step', stepId });
    onClose();
  };

  const onKey = (e) => {
    if (e.key === 'Escape') { onClose(); return; }
    if (e.key === 'ArrowDown') { setHl(h => Math.min(h+1, filtered.length-1)); e.preventDefault(); }
    if (e.key === 'ArrowUp')   { setHl(h => Math.max(h-1, 0)); e.preventDefault(); }
    if (e.key === 'Enter' && filtered[hl]) { choose(filtered[hl]); }
  };

  return (
    <div className="search-ov" onClick={onClose}>
      <div className="search-box" onClick={e => e.stopPropagation()}>
        <div className="ib">
          <input ref={inputRef} placeholder="Search across all subjects, topics, and lessons" value={q}
                 onChange={e => { setQ(e.target.value); setHl(0); }}
                 onKeyDown={onKey} />
          <span className="mono muted">esc</span>
        </div>
        <div className="results">
          {filtered.length === 0 && <div style={{ padding: 24, color: 'var(--muted)', textAlign:'center' }}>No matches.</div>}
          {filtered.map((it, i) => (
            <div key={i} className={`search-result ${i === hl ? 'hl' : ''}`} onMouseEnter={() => setHl(i)} onClick={() => choose(it)}>
              <span className="kind">{it.kind}</span>
              <div style={{ flex: 1 }}>
                <div className="ttl">{it.title}</div>
                <div className="path">{it.path}</div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  Header, Crumbs, MasteryDots, Progress, SubjectCard,
  BotanicalFrame, BotanicalSprig, BotanicalFern, VineColumn, BranchDivider, CornerOrnament,
  SearchOverlay, Footer, ORN,
  BrandText, BrandMark, AnkiButton,
});
