/* Reusable visual primitives + sample data */

const SAMPLE = {
  chapter: 'Sigma Chi · Kappa Upsilon · University of Florida',
  cycle: 'Fall 2026 Rush · Day 12 of 45',
  rushChair: 'Chase Henderson',
};

const STAGE_COLORS = {
  Lead:           { fg: '#6B7280', bg: '#F3F4F6' },
  Contacted:      { fg: '#0E7490', bg: '#ECFEFF' },
  Met:            { fg: '#0369A1', bg: '#EFF6FF' },
  Invited:        { fg: '#7C3AED', bg: '#F5F3FF' },
  'Hot Prospect': { fg: '#B91C1C', bg: '#FEF2F2' },
  'Bid Pending':  { fg: '#B45309', bg: '#FFFBEB' },
  'Bid Extended': { fg: '#047857', bg: '#ECFDF5' },
  Accepted:       { fg: '#065F46', bg: '#D1FAE5' },
};
const STAGES = ['Lead', 'Contacted', 'Met', 'Invited', 'Hot Prospect', 'Bid Pending', 'Bid Extended', 'Accepted'];

const StagePill = ({ stage, size = 'sm' }) => {
  const c = STAGE_COLORS[stage] || STAGE_COLORS.Lead;
  const padding = size === 'sm' ? 'px-2 py-0.5 text-[11px]' : 'px-2.5 py-1 text-[12px]';
  return (
    <span className={`inline-flex items-center gap-1.5 rounded ${padding} font-medium`}
      style={{ color: c.fg, background: c.bg }}>
      <span className="w-1.5 h-1.5 rounded-full" style={{ background: c.fg }} />
      {stage}
    </span>
  );
};

const Avatar = ({ initials, size = 32, bg = '#1E3A8A', fg = '#fff', ring = false, className = '' }) => (
  <div
    className={`inline-flex items-center justify-center rounded-full font-semibold tracking-tight ${className}`}
    style={{
      width: size, height: size, background: bg, color: fg,
      fontSize: Math.round(size * 0.38),
      boxShadow: ring ? '0 0 0 2px #fff, 0 0 0 3px rgba(0,0,0,.06)' : 'none',
      fontFamily: 'Inter, system-ui, sans-serif',
    }}
  >
    {initials}
  </div>
);

/* Gradient avatar — used for hero PNM */
const GradAvatar = ({ initials = 'JM', size = 44, from = '#1E3A8A', to = '#6366F1' }) => (
  <div className="rounded-full flex items-center justify-center text-white font-semibold"
    style={{
      width: size, height: size,
      background: `linear-gradient(135deg, ${from}, ${to})`,
      fontSize: Math.round(size * 0.36),
    }}>
    {initials}
  </div>
);

/* Animated score ring */
const ScoreRing = ({ value = 92, size = 52, color = '#10B981', track = '#E5E7EB', label = true, thick = 5, animate = true }) => {
  const [v, setV] = React.useState(animate ? 0 : value);
  React.useEffect(() => {
    if (!animate) { setV(value); return; }
    let start; const target = value; const dur = 1200;
    const step = (t) => {
      if (!start) start = t;
      const k = Math.min(1, (t - start) / dur);
      const eased = 1 - Math.pow(1 - k, 3);
      setV(Math.round(eased * target));
      if (k < 1) requestAnimationFrame(step);
    };
    const id = requestAnimationFrame(step);
    return () => cancelAnimationFrame(id);
  }, [value, animate]);
  const r = (size - thick) / 2;
  const c = 2 * Math.PI * r;
  const off = c - (v / 100) * c;
  return (
    <div className="relative inline-flex items-center justify-center" style={{ width: size, height: size }}>
      <svg width={size} height={size} className="-rotate-90">
        <circle cx={size/2} cy={size/2} r={r} stroke={track} strokeWidth={thick} fill="none" />
        <circle cx={size/2} cy={size/2} r={r} stroke={color} strokeWidth={thick} fill="none"
          strokeDasharray={c} strokeDashoffset={off} strokeLinecap="round"
          style={{ transition: 'stroke-dashoffset .6s ease' }} />
      </svg>
      {label && (
        <div className="absolute inset-0 flex items-center justify-center font-semibold"
          style={{ fontSize: Math.round(size * 0.34), color: '#0A0A0A' }}>
          {v}
        </div>
      )}
    </div>
  );
};

/* Reveal-on-scroll wrapper */
const Reveal = ({ children, as: Tag = 'div', className = '', delay = 0 }) => {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    let triggered = false;
    const fire = () => {
      if (triggered) return;
      triggered = true;
      setTimeout(() => el.classList.add('in'), delay);
    };
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { fire(); io.disconnect(); }
    }, { threshold: 0.05 });
    io.observe(el);
    // Fallback: if observer hasn't fired in 1.2s but element is in viewport, force.
    const fallback = setTimeout(() => {
      const r = el.getBoundingClientRect();
      const inView = r.top < window.innerHeight && r.bottom > 0;
      if (inView) { fire(); io.disconnect(); }
    }, 800);
    return () => { io.disconnect(); clearTimeout(fallback); };
  }, [delay]);
  return <Tag ref={ref} className={`reveal ${className}`}>{children}</Tag>;
};

/* Eyebrow */
const Eyebrow = ({ children, color = '#6366F1', className = '' }) => (
  <div className={`inline-flex items-center gap-2 text-[11px] font-semibold tracking-[0.14em] uppercase ${className}`}
    style={{ color }}>
    {children}
  </div>
);

/* Buttons */
const Btn = ({ children, variant = 'primary', size = 'md', as = 'button', className = '', ...rest }) => {
  const sz = {
    md: 'h-10 px-4 text-[14px]',
    lg: 'h-12 px-5 text-[15px]',
    sm: 'h-9 px-3 text-[13px]',
  }[size];
  const styles = {
    primary: 'bg-primary text-white hover:bg-primary-hover',
    ghost: 'bg-white text-ink border border-border hover:border-ink/50',
    'navy-outline': 'bg-white text-primary border border-primary/30 hover:border-primary',
    'white-on-dark': 'bg-white text-primary hover:bg-white/90',
    'ghost-on-dark': 'bg-transparent text-white border border-white/30 hover:border-white/70',
  }[variant];
  const Tag = as;
  return (
    <Tag
      className={`inline-flex items-center justify-center gap-2 rounded-md font-medium transition-all duration-200 shimmer ${sz} ${styles} hover:scale-[1.02] active:scale-[0.99] ${className}`}
      {...rest}>
      {children}
    </Tag>
  );
};

/* AI summary block — left-rule indigo */
const AISummary = ({ children, title = '✦ AI SUMMARY' }) => (
  <div className="rounded-md border-l-[3px] border-ai bg-ai-soft px-3 py-2.5">
    <div className="mono text-[10px] font-semibold tracking-[0.14em] text-ai">{title}</div>
    <div className="mt-1 text-[12.5px] italic text-ink/80 leading-snug font-serif-display">
      {children}
    </div>
  </div>
);

/* Tag chip */
const Tag = ({ children, color = '#1E3A8A', bg }) => (
  <span className="inline-flex items-center rounded px-2 py-0.5 text-[11px] font-medium"
    style={{ color, background: bg || `${color}14` }}>
    {children}
  </span>
);

/* Confidence chip */
const ConfChip = ({ value }) => {
  const tone = value >= 95 ? { fg: '#047857', bg: '#ECFDF5' }
            : value >= 88 ? { fg: '#0369A1', bg: '#EFF6FF' }
            : { fg: '#B45309', bg: '#FFFBEB' };
  return (
    <span className="mono text-[10px] font-semibold rounded px-1.5 py-0.5"
      style={{ color: tone.fg, background: tone.bg }}>
      {value}%
    </span>
  );
};

/* Animated waveform */
const Waveform = ({ bars = 32, color = '#10B981', height = 56, gap = 3, width = 220 }) => {
  const arr = React.useMemo(() => Array.from({ length: bars }, () => 0.4 + Math.random() * 0.6), [bars]);
  return (
    <div className="flex items-center justify-center" style={{ height, gap }}>
      {arr.map((h, i) => (
        <div key={i} className="wf-bar rounded-full"
          style={{
            width: (width - bars * gap) / bars,
            height: `${h * 100}%`,
            background: color,
            animationDelay: `${(i * 0.05).toFixed(2)}s`,
            animationDuration: `${(0.7 + (i % 5) * 0.08).toFixed(2)}s`,
          }}
        />
      ))}
    </div>
  );
};

/* Count up on view */
const CountUp = ({ to, suffix = '', prefix = '', duration = 1400, format = (n) => n.toLocaleString() }) => {
  const ref = React.useRef(null);
  const [v, setV] = React.useState(0);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    let raf, start;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) {
        const tick = (t) => {
          if (!start) start = t;
          const k = Math.min(1, (t - start) / duration);
          const eased = 1 - Math.pow(1 - k, 3);
          setV(Math.round(eased * to));
          if (k < 1) raf = requestAnimationFrame(tick);
        };
        raf = requestAnimationFrame(tick);
        io.disconnect();
      }
    }, { threshold: 0.4 });
    io.observe(el);
    return () => { cancelAnimationFrame(raf); io.disconnect(); };
  }, [to, duration]);
  return <span ref={ref}>{prefix}{format(v)}{suffix}</span>;
};

/* Decorative dashed ring */
const DashRing = ({ size = 380, opacity = 0.5 }) => (
  <svg width={size} height={size} className="absolute inset-0 m-auto pointer-events-none" style={{ opacity }}>
    <circle cx={size/2} cy={size/2} r={(size-2)/2} fill="none"
      stroke="#1E3A8A" strokeOpacity="0.18" strokeDasharray="3 8" />
  </svg>
);

Object.assign(window, {
  SAMPLE, STAGE_COLORS, STAGES,
  StagePill, Avatar, GradAvatar, ScoreRing,
  Reveal, Eyebrow, Btn, AISummary, Tag, ConfChip,
  Waveform, CountUp, DashRing,
});
