// upprofiler — Shared components

const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ---------- Theme toggle ----------
function readStoredTheme() {
  try {
    const t = localStorage.getItem('upprofiler-theme');
    if (t === 'light' || t === 'dark') return t;
  } catch (_) {}
  return null;
}
function systemPrefersDark() {
  return typeof window !== 'undefined'
    && window.matchMedia
    && window.matchMedia('(prefers-color-scheme: dark)').matches;
}
function applyTheme(theme) {
  const root = document.documentElement;
  if (theme) root.setAttribute('data-theme', theme);
  else root.removeAttribute('data-theme');
}

function ThemeToggle() {
  const [theme, setTheme] = useState(() => {
    const stored = readStoredTheme();
    if (stored) return stored;
    return systemPrefersDark() ? 'dark' : 'light';
  });

  useEffect(() => { applyTheme(theme); }, [theme]);

  const toggle = useCallback(() => {
    setTheme(t => {
      const next = t === 'dark' ? 'light' : 'dark';
      try { localStorage.setItem('upprofiler-theme', next); } catch (_) {}
      return next;
    });
  }, []);

  const isDark = theme === 'dark';
  return (
    <button
      type="button"
      className="theme-toggle"
      onClick={toggle}
      aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
      title={isDark ? 'Switch to light mode' : 'Switch to dark mode'}>
      {isDark ? (
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"
          strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
          <circle cx="12" cy="12" r="4" />
          <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41" />
        </svg>
      ) : (
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"
          strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
          <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79Z" />
        </svg>
      )}
    </button>
  );
}

// ---------- Logo / brand glyph ----------
// Lucide-React's `trending-up` icon (MIT licensed) — a line trending up to the
// right with an arrow tip. Inlined as SVG paths since this project doesn't
// have a bundler. Visually says "up" — matches the brand name.
function PulseGlyph({ size = 22, color = '#14B8A6' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke={color} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
      <path d="m22 7-8.5 8.5-5-5L2 17" />
      <path d="M16 7h6v6" />
    </svg>
  );
}

function Logo({ size = 22 }) {
  return (
    <span className="nav-logo">
      <span className="pulse-glyph"><PulseGlyph size={size} /></span>
      <span><span style={{ color: '#14B8A6' }}>up</span>profiler</span>
    </span>
  );
}

// ---------- Nav ----------
// Stripped down to only what actually works. The mock links from the
// original concept (Dashboard / Drafts / Stories / Monday Brief / Profile
// / Audience) showed hardcoded data and have been removed to avoid
// confusing real users. The mock pages still exist in the codebase as
// reference but are not surfaced in navigation.
function Nav({ current, onNavigate }) {
  return (
    <header className="nav">
      <a onClick={() => onNavigate('/')} style={{ cursor: 'pointer' }}>
        <Logo />
      </a>
      <nav className="nav-links">
        <a className={`nav-link ${current === '/' ? 'active' : ''}`}
           onClick={() => onNavigate('/')} style={{ cursor: 'pointer' }}>
          Score a profile
        </a>
        <a className={`nav-link ${current?.startsWith('/account') ? 'active' : ''}`}
           onClick={() => onNavigate('/account')} style={{ cursor: 'pointer' }}>
          Account
        </a>
        <a className="nav-link"
           href="https://whop.com/linkupbyjasmin?a=whpreviews"
           target="_blank" rel="noopener"
           style={{ cursor: 'pointer' }}>
          Link Up community
        </a>
      </nav>
      <div className="nav-right">
        <ThemeToggle />
      </div>
    </header>
  );
}

// ---------- Score Ring ----------
function ScoreRing({
  value = 71,
  size = 380,
  strokeWidth = 14,
  showHalo = true,
  showPulse = true,
  label = 'Conviction',
  delta = null,
  animateKey = 'default',
  decimal = false,
}) {
  const r = (size - strokeWidth) / 2;
  const c = 2 * Math.PI * r;
  const targetOffset = c - (value / 100) * c;

  const [drawn, setDrawn] = useState(false);
  useEffect(() => {
    setDrawn(false);
    const t = setTimeout(() => setDrawn(true), 60);
    return () => clearTimeout(t);
  }, [animateKey, value]);

  const numSize = size * (decimal ? 0.30 : 0.37);
  const labelSize = Math.max(11, size * 0.032);

  return (
    <div className="score-ring-wrap" style={{ width: size, height: size }}>
      {showHalo && <div className="score-ring-halo" />}
      <svg width={size} height={size} style={{ transform: 'rotate(-90deg)' }}>
        <defs>
          <linearGradient id={`ring-grad-${animateKey}`} x1="0" y1="0" x2="1" y2="1">
            <stop offset="0%" stopColor="#0D9488" />
            <stop offset="100%" stopColor="#14B8A6" />
          </linearGradient>
        </defs>
        <circle className="ring-track" cx={size / 2} cy={size / 2} r={r}
          strokeWidth={strokeWidth} fill="none" />
        <circle cx={size / 2} cy={size / 2} r={r}
          stroke={`url(#ring-grad-${animateKey})`}
          strokeWidth={strokeWidth} fill="none"
          strokeLinecap="round"
          strokeDasharray={c}
          strokeDashoffset={drawn ? targetOffset : c}
          style={{ transition: 'stroke-dashoffset 1.6s cubic-bezier(0.4, 0, 0.2, 1)' }} />
      </svg>
      <div className="score-ring-num">
        <div style={{
          fontSize: numSize, fontWeight: 700, lineHeight: 1, color: 'var(--pink)',
          letterSpacing: '-0.04em', fontVariantNumeric: 'tabular-nums',
        }}>
          {decimal ? Number(value).toFixed(1) : Math.round(value)}
        </div>
        <div style={{ marginTop: size * 0.04, display: 'flex', alignItems: 'center', gap: 8 }}>
          {showPulse && <span className="pulse-dot"></span>}
          <span className="label-mono" style={{ fontSize: labelSize }}>{label}</span>
        </div>
        {delta !== null && (
          <div style={{
            marginTop: 12,
            fontFamily: 'var(--font-mono)', fontSize: labelSize,
            color: delta >= 0 ? 'var(--good)' : 'var(--warn)',
            fontWeight: 500, letterSpacing: '0.08em',
          }}>
            {delta >= 0 ? '↑' : '↓'} {Math.abs(delta)} · 30D
          </div>
        )}
      </div>
    </div>
  );
}

// ---------- Trend chart ----------
function TrendChart({ data, width = 600, height = 220, events = [] }) {
  const max = Math.max(...data) + 5;
  const min = Math.max(0, Math.min(...data) - 5);
  const range = max - min || 1;
  const stepX = width / (data.length - 1);

  const points = data.map((v, i) => [i * stepX, height - ((v - min) / range) * height]);
  const linePath = points.map(([x, y], i) => `${i === 0 ? 'M' : 'L'} ${x.toFixed(1)} ${y.toFixed(1)}`).join(' ');
  const areaPath = `${linePath} L ${width} ${height} L 0 ${height} Z`;

  return (
    <svg viewBox={`0 0 ${width} ${height}`} style={{ width: '100%', height: 'auto', display: 'block' }}>
      <defs>
        <linearGradient id="chart-area" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="#14B8A6" stopOpacity="0.15" />
          <stop offset="100%" stopColor="#14B8A6" stopOpacity="0" />
        </linearGradient>
      </defs>
      <path d={areaPath} fill="url(#chart-area)" />
      <path d={linePath} className="trend-line" />
      {events.map((e, i) => {
        const [x, y] = points[e.index];
        return (
          <g key={i}>
            <circle cx={x} cy={y} r="6" fill="white" stroke="#14B8A6" strokeWidth="2.5" />
            <line x1={x} y1={y + 8} x2={x} y2={height - 14} stroke="#14B8A6" strokeWidth="1" strokeDasharray="2 3" opacity="0.5" />
          </g>
        );
      })}
    </svg>
  );
}

// ---------- Sparkline (small) ----------
function Sparkline({ data, width = 160, height = 40, color = '#14B8A6' }) {
  const max = Math.max(...data);
  const min = Math.min(...data);
  const range = max - min || 1;
  const stepX = width / (data.length - 1);
  const pts = data.map((v, i) => [i * stepX, height - ((v - min) / range) * (height - 6) - 3]);
  const path = pts.map(([x, y], i) => `${i === 0 ? 'M' : 'L'} ${x.toFixed(1)} ${y.toFixed(1)}`).join(' ');
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
      <path d={path} stroke={color} strokeWidth="1.8" fill="none" strokeLinecap="round" />
    </svg>
  );
}

// ---------- Page chrome ----------
function PageHeader({ id, name, sub, tag, right }) {
  return (
    <div className="page-header">
      <div>
        <div className="page-id">{id}</div>
        <div className="page-name">{name}</div>
        {sub && <div className="page-sub">{sub}</div>}
      </div>
      <div className="row gap-12">
        {tag && <span className={`tag ${tag.kind || ''}`}>{tag.label}</span>}
        {right}
      </div>
    </div>
  );
}

function Card({ children, id, title, tag, hover, style, className = '' }) {
  return (
    <div className={`card ${hover ? 'hoverable' : ''} ${className}`} style={style}>
      {(id || title || tag) && (
        <div className="card-head">
          <div>
            {id && <div className="card-id">{id}</div>}
            {title && <div className="card-title">{title}</div>}
          </div>
          {tag && <span className={`tag ${tag.kind || ''}`}>{tag.label}</span>}
        </div>
      )}
      {children}
    </div>
  );
}

// ---------- Algorithm alert banner ----------
function AlgoAlert({ onDismiss, onView }) {
  return (
    <div className="algo-alert">
      <div style={{ position: 'relative', width: 32, height: 32, flexShrink: 0 }}>
        <span className="pulse-dot" style={{ position: 'absolute', top: 12, left: 12 }}></span>
      </div>
      <div style={{ flex: 1 }}>
        <div className="row gap-12" style={{ marginBottom: 4 }}>
          <span className="tag pink">Heads up</span>
          <span className="label-mono">28 Apr · 06:14 GMT</span>
        </div>
        <div style={{ fontSize: 16, fontWeight: 700, color: 'var(--ink)', letterSpacing: '-0.01em' }}>
          LinkedIn just shifted the goalposts. Your score moved <span className="pink">−4 overnight</span>.
        </div>
        <div style={{ fontSize: 14, color: 'var(--ink-soft)', marginTop: 2 }}>
          Dwell-time is now worth 22% more. Carousels win this week. I'll show you exactly what to do. — Coach J
        </div>
      </div>
      <button className="btn btn-primary btn-sm" onClick={onView}>Show me</button>
      <button onClick={onDismiss} className="label-mono" style={{ padding: 8, color: 'var(--mute)' }} aria-label="Dismiss">✕</button>
    </div>
  );
}

// ---------- Footer ----------
function Footer({ onNavigate }) {
  const goto = onNavigate || ((href) => { window.location.hash = href; });
  return (
    <footer style={{
      borderTop: '1px solid var(--line)',
      padding: '32px 64px',
      maxWidth: 1440,
      width: '100%',
      margin: '0 auto',
      color: 'var(--mute)',
      fontSize: 13,
    }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', flexWrap: 'wrap', gap: 24 }}>
        <div className="row gap-12" style={{ alignItems: 'center' }}>
          <PulseGlyph size={16} />
          <span style={{ fontWeight: 700, color: 'var(--ink)' }}>upprofiler</span>
          <span className="label-mono">By Coach J · from Bosnia to the world</span>
        </div>
        <div className="row gap-24" style={{ flexWrap: 'wrap' }}>
          <a className="muted" onClick={() => goto('/privacy')} style={{ cursor: 'pointer' }}>Privacy</a>
          <a className="muted" onClick={() => goto('/terms')} style={{ cursor: 'pointer' }}>Terms</a>
          <a className="muted" onClick={() => goto('/cookies')} style={{ cursor: 'pointer' }}>Cookies</a>
          <a className="muted" href="https://whop.com/linkupbyjasmin?a=whpreviews" target="_blank" rel="noopener" style={{ cursor: 'pointer' }}>Link Up community</a>
        </div>
      </div>
      <div style={{ marginTop: 16, fontSize: 11, color: 'var(--mute)', lineHeight: 1.6 }}>
        upprofiler is not affiliated with or endorsed by LinkedIn Corporation. We read only the public profile data LinkedIn shows without authentication. By using the service you agree to our{' '}
        <a className="muted" onClick={() => goto('/terms')} style={{ cursor: 'pointer', textDecoration: 'underline' }}>Terms</a>
        {' '}and acknowledge our{' '}
        <a className="muted" onClick={() => goto('/privacy')} style={{ cursor: 'pointer', textDecoration: 'underline' }}>Privacy Policy</a>.
      </div>
    </footer>
  );
}

// ---------- Cookie notice ----------
function CookieNotice() {
  const [show, setShow] = useState(false);
  useEffect(() => {
    try {
      if (!localStorage.getItem('upprofiler-cookie-ack')) {
        // Small delay so it doesn't flash before the page settles
        const t = setTimeout(() => setShow(true), 600);
        return () => clearTimeout(t);
      }
    } catch (_) {}
  }, []);
  function ack() {
    try { localStorage.setItem('upprofiler-cookie-ack', '1'); } catch (_) {}
    setShow(false);
  }
  if (!show) return null;
  return (
    <div style={{
      position: 'fixed', bottom: 16, left: 16, right: 16,
      maxWidth: 720, margin: '0 auto',
      background: 'var(--surface)',
      border: '1px solid var(--line)',
      borderLeft: '4px solid var(--pink)',
      borderRadius: 12,
      padding: '14px 18px',
      boxShadow: 'var(--shadow-card)',
      display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap',
      zIndex: 100,
      fontSize: 13, color: 'var(--ink-soft)', lineHeight: 1.5,
    }}>
      <div style={{ flex: '1 1 320px' }}>
        We use essential cookies for sign-in and remembering your theme. No analytics, no tracking.{' '}
        <a className="muted" onClick={() => { window.location.hash = '/cookies'; }} style={{ cursor: 'pointer', textDecoration: 'underline', color: 'var(--pink)' }}>Read more</a>.
      </div>
      <button className="btn btn-primary btn-sm" onClick={ack} style={{ flexShrink: 0 }}>Got it</button>
    </div>
  );
}

// Export
Object.assign(window, {
  PulseGlyph, Logo, Nav, ThemeToggle, ScoreRing, TrendChart, Sparkline,
  PageHeader, Card, AlgoAlert, Footer, CookieNotice,
});
