/* ============================================================
   CURIO — Shared UI primitives
   ============================================================ */
const { useState, useEffect, useRef, useMemo } = React;

const ICON_BY_NAME = (n) => window[n] || window.Book;
const CAT_ICON = { tech:'Code', business:'Briefcase', design:'Palette', marketing:'Trend', data:'Cpu', wellness:'Heart', finance:'Dollar', creative:'Wand' };

/* ---------- Logo ---------- */
function Logo({ onClick, light = false, size = 18 }) {
  return (
    <div className="logo" onClick={onClick} style={{ cursor: onClick ? 'pointer' : 'default', fontSize: size, color: light ? '#fff' : 'var(--ink)' }}>
      <span className="logo-mark"><Spark /></span>
      <span>Coursedy</span>
    </div>
  );
}

/* ---------- Button ---------- */
function Btn({ variant = 'primary', size, block, icon, iconR, children, className = '', ...p }) {
  const cls = ['btn', `btn-${variant}`, size === 'sm' ? 'btn-sm' : size === 'lg' ? 'btn-lg' : '', block ? 'btn-block' : '', className].filter(Boolean).join(' ');
  return (
    <button className={cls} {...p}>
      {icon}{children}{iconR}
    </button>
  );
}

/* ---------- Avatar ---------- */
function Avatar({ name = '?', size = 32, cat, style }) {
  const initials = name.split(' ').map(w => w[0]).slice(0, 2).join('').toUpperCase();
  const c = cat ? catOf(cat) : null;
  return (
    <span className="avatar" style={{ width: size, height: size, fontSize: size * 0.4, background: c ? c.grad : 'var(--brand)', ...style }}>
      {initials}
    </span>
  );
}

/* ---------- Stars ---------- */
function Stars({ value = 5, size = 14 }) {
  return (
    <span className="row" style={{ gap: 1, color: 'var(--amber)' }}>
      {[1,2,3,4,5].map(i => <StarFill key={i} size={size} style={{ opacity: i <= Math.round(value) ? 1 : 0.22 }} />)}
    </span>
  );
}

/* ---------- Progress bar ---------- */
function Progress({ value = 0, height = 6, color = 'var(--brand)', track = 'var(--surface-3)' }) {
  return (
    <div style={{ height, background: track, borderRadius: 99, overflow: 'hidden', width: '100%' }}>
      <div style={{ height: '100%', width: `${value}%`, background: color, borderRadius: 99, transition: 'width .6s var(--ease)' }} />
    </div>
  );
}

/* ---------- Course cover art (gradient + faint glyph) ---------- */
function CourseCover({ course, radius = 12, children, big }) {
  const c = catOf(course.cat);
  const Glyph = ICON_BY_NAME(CAT_ICON[course.cat]);
  return (
    <div style={{ position: 'relative', borderRadius: radius, overflow: 'hidden', background: c.grad, aspectRatio: big ? '16/10' : '16/9' }} className="noise">
      {/* faint big glyph */}
      <div style={{ position: 'absolute', right: -14, bottom: -22, color: '#fff', opacity: 0.16 }}>
        <Glyph size={big ? 168 : 118} sw={1.2} />
      </div>
      {/* category label */}
      <div style={{ position: 'absolute', top: 12, left: 13 }}>
        <span className="mono" style={{ fontSize: 11, letterSpacing: '.12em', textTransform: 'uppercase', color: '#fff', opacity: .92, fontWeight: 500 }}>{c.name}</span>
      </div>
      {children}
    </div>
  );
}

/* ---------- Card export dropdown (used by CourseCard) ---------- */
function CardExportMenu({ courseId }) {
  const [open, setOpen] = useState(false);
  const [coords, setCoords] = useState({ top: 0, left: 0 });
  const btnRef = useRef(null);
  const popRef = useRef(null);
  const MENU_W = 200;
  const MENU_H = 290; // approximate; trim if needed

  const positionPopover = () => {
    if (!btnRef.current) return;
    const r = btnRef.current.getBoundingClientRect();
    const spaceBelow = window.innerHeight - r.bottom;
    const top = spaceBelow >= MENU_H + 8
      ? r.bottom + 4
      : Math.max(8, r.top - MENU_H - 4);
    const left = Math.min(
      window.innerWidth - MENU_W - 8,
      Math.max(8, r.right - MENU_W),
    );
    setCoords({ top, left });
  };

  useEffect(() => {
    if (!open) return;
    const onDown = (e) => {
      if (popRef.current && popRef.current.contains(e.target)) return;
      if (btnRef.current && btnRef.current.contains(e.target)) return;
      setOpen(false);
    };
    const onScroll = () => positionPopover();
    document.addEventListener('mousedown', onDown);
    window.addEventListener('scroll', onScroll, true);
    window.addEventListener('resize', onScroll);
    return () => {
      document.removeEventListener('mousedown', onDown);
      window.removeEventListener('scroll', onScroll, true);
      window.removeEventListener('resize', onScroll);
    };
  }, [open]);

  const items = [
    { label: 'Word (.docx)',     fmt: 'docx' },
    { label: 'PDF (.pdf)',       fmt: 'pdf' },
    { label: 'HTML (.html)',     fmt: 'html' },
    { label: 'Markdown (.md)',   fmt: 'markdown' },
    { label: 'ePub (.epub)',     fmt: 'epub' },
    { label: 'JSON (.json)',     fmt: 'json' },
    { label: 'Quiz CSV (.csv)',  fmt: 'csv' },
    { label: 'SCORM 1.2 (.zip)', fmt: 'scorm' },
  ];

  const popover = open && ReactDOM.createPortal(
    <div
      ref={popRef}
      className="card fade-in"
      style={{
        position: 'fixed', top: coords.top, left: coords.left,
        width: MENU_W, padding: 4, zIndex: 1000,
        boxShadow: 'var(--sh-md)', background: 'var(--surface)',
      }}
      onClick={e => e.stopPropagation()}
    >
      {items.map(it => (
        <button
          key={it.fmt}
          className="nav-item"
          style={{ width: '100%', height: 32, padding: '0 10px', fontSize: 12.8, color: 'var(--ink-2)', textAlign: 'left' }}
          onClick={(e) => { e.stopPropagation(); setOpen(false); window.API.exportCourse(courseId, it.fmt); }}
        >{it.label}</button>
      ))}
    </div>,
    document.body,
  );

  return (
    <>
      <button
        ref={btnRef}
        className="btn btn-sm btn-outline"
        style={{ height: 30, padding: '0 10px', fontSize: 12.5, gap: 6 }}
        onClick={(e) => {
          e.stopPropagation();
          if (!open) positionPopover();
          setOpen(o => !o);
        }}
      >
        <Download size={13} /> Export
      </button>
      {popover}
    </>
  );
}

/* ---------- Course card (browser grid) ---------- */
function CourseCard({ course, onClick, progress }) {
  const c = catOf(course.cat);
  const realId = course.id && window.isRealCourseId && window.isRealCourseId(course.id);
  return (
    <div className="card card-hover" style={{ overflow: 'hidden', cursor: 'pointer', display: 'flex', flexDirection: 'column' }} onClick={onClick}>
      <CourseCover course={course}>
        {course.featured && (
          <div style={{ position: 'absolute', top: 12, right: 12 }}>
            <span className="badge" style={{ background: 'rgba(255,255,255,.92)', color: c.ink }}><Flame size={12} /> Trending</span>
          </div>
        )}
        {course.status === 'draft' && (
          <div style={{ position: 'absolute', top: 12, left: 12 }}>
            <span className="badge badge-amber">Draft</span>
          </div>
        )}
      </CourseCover>
      <div style={{ padding: '15px 16px 16px', display: 'flex', flexDirection: 'column', gap: 9, flex: 1 }}>
        <div className="row" style={{ gap: 7, fontSize: 12.5 }}>
          <span className="mono" style={{ color: 'var(--faint)', fontWeight: 500 }}>{course.level}</span>
          <span className="dot" />
          <span className="muted">{course.hours}h</span>
          <span className="dot" />
          <span className="muted">{course.lessonsN} lessons</span>
        </div>
        <h3 style={{ fontSize: 17, lineHeight: 1.22, letterSpacing: '-0.02em' }}>{course.title}</h3>
        <p className="muted" style={{ fontSize: 13.5, lineHeight: 1.45, flex: 1 }}>{course.subtitle}</p>
        {progress != null ? (
          <div style={{ marginTop: 2 }}>
            <Progress value={progress} />
            <div className="row" style={{ justifyContent: 'space-between', marginTop: 7, fontSize: 12 }}>
              <span className="muted">{progress}% complete</span>
              <span className="mono" style={{ color: 'var(--brand)', fontWeight: 600 }}>Continue →</span>
            </div>
          </div>
        ) : null}
        {realId && (
          <div className="row" style={{ gap: 8, marginTop: 6, paddingTop: 10, borderTop: '1px solid var(--line-2)' }}>
            <button
              className="btn btn-sm btn-outline"
              style={{ height: 30, padding: '0 10px', fontSize: 12.5, gap: 6 }}
              onClick={(e) => { e.stopPropagation(); window.open('/preview/' + course.id, '_blank'); }}
            ><Eye size={13} /> Preview</button>
            <CardExportMenu courseId={course.id} />
            <span className="grow" />
            <span className="mono" style={{ fontSize: 11, color: 'var(--brand)', fontWeight: 600 }}>Open →</span>
          </div>
        )}
      </div>
    </div>
  );
}

/* ---------- Section eyebrow heading ---------- */
function SectionHead({ eyebrow, title, sub, center, style }) {
  return (
    <div style={{ textAlign: center ? 'center' : 'left', maxWidth: center ? 640 : 'none', margin: center ? '0 auto' : 0, ...style }}>
      {eyebrow && <div className="eyebrow" style={{ marginBottom: 14 }}>{eyebrow}</div>}
      <h2 style={{ fontSize: 'clamp(28px,4vw,42px)', lineHeight: 1.05, letterSpacing: '-0.03em', fontWeight: 800 }}>{title}</h2>
      {sub && <p className="lead" style={{ marginTop: 16, maxWidth: 560, marginLeft: center ? 'auto' : 0, marginRight: center ? 'auto' : 0 }}>{sub}</p>}
    </div>
  );
}

/* ---------- AI typing dots ---------- */
function TypingDots() {
  return (
    <span className="row" style={{ gap: 4 }}>
      {[0,1,2].map(i => <span key={i} style={{ width: 6, height: 6, borderRadius: 50, background: 'var(--faint)', animation: `pulse-dot 1.2s ${i*0.18}s infinite` }} />)}
    </span>
  );
}

/* ---------- Toggle ---------- */
function Toggle({ on, onClick }) {
  return (
    <button onClick={onClick} style={{ width: 42, height: 24, borderRadius: 99, background: on ? 'var(--brand)' : 'var(--surface-3)', position: 'relative', transition: 'background .2s', flexShrink: 0 }}>
      <span style={{ position: 'absolute', top: 3, left: on ? 21 : 3, width: 18, height: 18, borderRadius: 50, background: '#fff', boxShadow: 'var(--sh-sm)', transition: 'left .2s var(--ease)' }} />
    </button>
  );
}

/* ---------- Modal shell ---------- */
function Modal({ children, onClose, width = 440 }) {
  return (
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 100, background: 'rgba(21,20,26,.42)', backdropFilter: 'blur(3px)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20, animation: 'fadeIn .2s' }}>
      <div onClick={e => e.stopPropagation()} className="scale-in" style={{ width, maxWidth: '100%', background: 'var(--surface)', borderRadius: 'var(--r-lg)', boxShadow: 'var(--sh-lg)', overflow: 'hidden' }}>
        {children}
      </div>
    </div>
  );
}

Object.assign(window, { Logo, Btn, Avatar, Stars, Progress, CourseCover, CourseCard, SectionHead, TypingDots, Toggle, Modal, ICON_BY_NAME, CAT_ICON });
