// Shared components — Framer Motion enhanced

const { useState, useEffect, useRef } = React;
const FM = window.Motion || {};
var { motion, AnimatePresence, useScroll, useTransform, useSpring, useMotionValue, useInView } = FM;
if (!motion) {
  motion = new Proxy({}, {
    get: (_, tag) => React.forwardRef((inputProps, ref) => {
      const props = Object.assign({}, inputProps || {});
      const children = props.children;
      delete props.children;
      delete props.initial;
      delete props.animate;
      delete props.exit;
      delete props.transition;
      delete props.whileHover;
      delete props.whileTap;
      delete props.layout;
      delete props.variants;
      delete props.custom;
      return React.createElement(tag, Object.assign({}, props, { ref }), children);
    }),
  });
}
if (!AnimatePresence) AnimatePresence = ({ children }) => React.createElement(React.Fragment, null, children);
if (!useScroll) useScroll = () => ({ scrollYProgress: 0 });
if (!useTransform) useTransform = (_value, _input, output) => Array.isArray(output) ? output[0] : 0;
if (!useSpring) useSpring = (value) => value;
if (!useMotionValue) useMotionValue = (initial) => ({ get: () => initial, set: () => {} });
if (!useInView) useInView = () => true;

const showToast = (msg) => {
  const t = document.getElementById('toast');
  if (!t) return;
  t.textContent = msg;
  t.classList.add('show');
  clearTimeout(window.__toastT);
  window.__toastT = setTimeout(() => t.classList.remove('show'), 2200);
};

// ── Animation Variants ──────────────────────────────────────────────────────
const fadeUp = {
  hidden: { opacity: 0, y: 24, filter: 'blur(4px)' },
  visible: (delay = 0) => ({
    opacity: 1, y: 0, filter: 'blur(0px)',
    transition: { duration: 0.65, delay, ease: [0.16, 1, 0.3, 1] }
  }),
};

const fadeIn = {
  hidden: { opacity: 0 },
  visible: (delay = 0) => ({
    opacity: 1,
    transition: { duration: 0.5, delay, ease: 'easeOut' }
  }),
};

const scaleIn = {
  hidden: { opacity: 0, scale: 0.92 },
  visible: (delay = 0) => ({
    opacity: 1, scale: 1,
    transition: { duration: 0.6, delay, ease: [0.16, 1, 0.3, 1] }
  }),
};

const slideRight = {
  hidden: { opacity: 0, x: -20 },
  visible: (delay = 0) => ({
    opacity: 1, x: 0,
    transition: { duration: 0.5, delay, ease: [0.16, 1, 0.3, 1] }
  }),
};

// ── Motion Wrapper ──────────────────────────────────────────────────────────
const Reveal = ({ children, delay = 0, variants = fadeUp, className, style, as = 'div' }) => {
  const ref = useRef(null);
  const isInView = useInView(ref, { once: true, margin: '0px 0px -60px 0px' });
  const Tag = motion[as] || motion.div;
  return (
    <Tag
      ref={ref}
      initial="hidden"
      animate={isInView ? "visible" : "hidden"}
      custom={delay}
      variants={variants}
      className={className}
      style={style}
    >
      {children}
    </Tag>
  );
};

// ── Magnetic Button ─────────────────────────────────────────────────────────
const MagBtn = ({ children, className, onClick, style }) => {
  const ref = useRef(null);
  const x = useMotionValue(0);
  const y = useMotionValue(0);
  const sx = useSpring(x, { stiffness: 300, damping: 20 });
  const sy = useSpring(y, { stiffness: 300, damping: 20 });

  const onMouseMove = (e) => {
    const r = ref.current.getBoundingClientRect();
    const cx = r.left + r.width / 2;
    const cy = r.top + r.height / 2;
    x.set((e.clientX - cx) * 0.35);
    y.set((e.clientY - cy) * 0.35);
  };
  const onMouseLeave = () => { x.set(0); y.set(0); };

  return (
    <motion.button
      ref={ref}
      className={className}
      style={{ ...style, x: sx, y: sy }}
      onMouseMove={onMouseMove}
      onMouseLeave={onMouseLeave}
      onClick={onClick}
      whileTap={{ scale: 0.96 }}
    >
      {children}
    </motion.button>
  );
};

// ── Sticky Nav ──────────────────────────────────────────────────────────────
const Nav = ({ route, go, user }) => {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 8);
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  const links = [
    { id: 'explore', label: 'Explore' },
    { id: 'aiNews', label: 'AI News' },
    { id: 'about', label: 'About' },
    { id: 'pricing', label: 'Pricing' },
  ];
  const onLink = (id) => {
    if (id === 'explore') return go('recent');
    if (id === 'aiNews') return go('aiNews');
    if (id === 'about') return go('about');
    if (id === 'pricing') return go('pricing');
  };

  return (
    <motion.div
      className={`nav-shell ${scrolled ? 'scrolled' : ''}`}
      initial={{ y: -80, opacity: 0 }}
      animate={{ y: 0, opacity: 1 }}
      transition={{ duration: 0.7, ease: [0.16, 1, 0.3, 1] }}
    >
      <div className="container nav-inner">
        <motion.div
          className="logo"
          onClick={() => go('home')}
          whileHover={{ scale: 1.04 }}
          whileTap={{ scale: 0.96 }}
        >
          <img className="logo-full" src="assets/wordmark.png" alt="VidVerdict" width="148" height="38" decoding="async" />
        </motion.div>

        <div className="nav-center">
          {links.map((l, i) => (
            <motion.div
              key={l.id}
              className="nav-link"
              onClick={() => onLink(l.id)}
              initial={{ opacity: 0, y: -10 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{ delay: 0.1 + i * 0.06, duration: 0.5, ease: [0.16, 1, 0.3, 1] }}
              whileHover={{ y: -1 }}
            >
              {l.label}
            </motion.div>
          ))}
        </div>

        <motion.div
          className="nav-right"
          initial={{ opacity: 0, x: 20 }}
          animate={{ opacity: 1, x: 0 }}
          transition={{ delay: 0.3, duration: 0.6, ease: [0.16, 1, 0.3, 1] }}
        >
          <motion.button className="btn btn-ghost nav-account-btn" onClick={() => go(user ? 'account' : 'signin')} whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.96 }}>
            {user ? <span className="nav-avatar">{user.name?.slice(0, 1) || 'R'}</span> : null}
            {user ? 'Account' : 'Sign In'}
          </motion.button>
          <MagBtn className="btn btn-accent" onClick={() => go('home')}>
            <span key="label">Analyze Now</span><I.ArrowRight key="icon" size={14} style={{ color: '#fff' }} />
          </MagBtn>
        </motion.div>
      </div>
    </motion.div>
  );
};

// ── Footer ──────────────────────────────────────────────────────────────────
const Footer = ({ go }) => (
  <footer>
    <div className="container">
      <div className="footer-grid">
        <div>
          <div className="logo" style={{ marginBottom: 14 }}>
            <img className="logo-full small" src="assets/wordmark.png" alt="VidVerdict" width="122" height="31" decoding="async" />
          </div>
          <div style={{ fontSize: 14, color: 'var(--ink-3)', maxWidth: 320, lineHeight: 1.6 }}>
            AI-assisted fact-checking for public social video. Source-backed verdicts in seconds.
          </div>
        </div>
        {[
          { h: 'Product', links: [
            { l: 'Analyze a video', fn: () => go('home') },
            { l: 'Explore checks', fn: () => go('recent') },
            { l: 'Pricing', fn: () => go('pricing') },
            { l: 'API (soon)', fn: null },
          ]},
          { h: 'Company', links: [
            { l: 'About', fn: () => go('about') },
            { l: 'Methodology', fn: null },
            { l: 'Press', fn: null },
            { l: 'Contact', fn: null },
          ]},
          { h: 'Legal', links: [
            { l: 'Privacy', fn: () => go('privacy') },
            { l: 'Terms', fn: () => go('terms') },
            { l: 'Cookies', fn: null },
            { l: 'Disclaimers', fn: null },
          ]},
        ].map(col => (
          <div key={col.h}>
            <div className="footer-h">{col.h}</div>
            {col.links.map(link => (
              <div key={link.l} className="footer-link" onClick={link.fn}>{link.l}</div>
            ))}
          </div>
        ))}
      </div>
      <div className="footer-bottom">
        <div>© 2026 VidVerdict, Inc. All rights reserved.</div>
        <div>Built for clarity. Used by skeptics.</div>
      </div>
    </div>
  </footer>
);

// ── CountUp ─────────────────────────────────────────────────────────────────
const CountUp = ({ to, duration = 1200, className }) => {
  const [n, setN] = useState(0);
  useEffect(() => {
    let raf, start;
    const step = (ts) => {
      if (!start) start = ts;
      const p = Math.min(1, (ts - start) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setN(Math.round(eased * to));
      if (p < 1) raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [to, duration]);
  return <span className={className}>{n}</span>;
};

// ── Score Ring (animated SVG with Framer) ────────────────────────────────────
const ScoreRing = ({ score, size = 156, stroke = 10, color }) => {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const [animScore, setAnimScore] = useState(0);

  useEffect(() => {
    let raf, start;
    const step = (ts) => {
      if (!start) start = ts;
      const p = Math.min(1, (ts - start) / 1600);
      const eased = 1 - Math.pow(1 - p, 4);
      setAnimScore(eased * score);
      if (p < 1) raf = requestAnimationFrame(step);
    };
    const timer = setTimeout(() => { raf = requestAnimationFrame(step); }, 200);
    return () => { clearTimeout(timer); cancelAnimationFrame(raf); };
  }, [score]);

  const dash = c * (animScore / 100);
  const ringColor = color || (score >= 75 ? 'var(--green)' : score >= 50 ? 'var(--amber)' : 'var(--red)');

  return (
    <motion.div
      style={{ position: 'relative', width: size, height: size }}
      initial={{ scale: 0.5, opacity: 0 }}
      animate={{ scale: 1, opacity: 1 }}
      transition={{ duration: 0.7, ease: [0.16, 1, 0.3, 1], delay: 0.1 }}
    >
      <svg width={size} height={size} style={{ transform: 'rotate(-90deg)' }}>
        <circle cx={size/2} cy={size/2} r={r} stroke="var(--surface-2)" strokeWidth={stroke} fill="none" />
        <circle cx={size/2} cy={size/2} r={r} stroke={ringColor} strokeWidth={stroke} fill="none"
          strokeDasharray={`${dash} ${c}`} strokeLinecap="round"
          style={{ transition: 'stroke 600ms, stroke-dasharray 40ms' }} />
      </svg>
      <div style={{ position: 'absolute', inset: 0, display: 'grid', placeItems: 'center' }}>
        <div style={{ textAlign: 'center' }}>
          <div className="big-ring-num">{Math.round(animScore)}</div>
        </div>
      </div>
    </motion.div>
  );
};

const SmallRing = ({ score, size = 56, stroke = 5 }) => {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const [animScore, setAnimScore] = useState(0);
  useEffect(() => {
    let raf, start;
    const step = (ts) => {
      if (!start) start = ts;
      const p = Math.min(1, (ts - start) / 1000);
      const eased = 1 - Math.pow(1 - p, 3);
      setAnimScore(eased * score);
      if (p < 1) raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [score]);
  const dash = c * (animScore / 100);
  const color = score >= 75 ? 'var(--green)' : score >= 50 ? 'var(--amber)' : 'var(--red)';
  return (
    <svg width={size} height={size} style={{ transform: 'rotate(-90deg)', flexShrink: 0 }}>
      <circle cx={size/2} cy={size/2} r={r} stroke="var(--surface-2)" strokeWidth={stroke} fill="none" />
      <circle cx={size/2} cy={size/2} r={r} stroke={color} strokeWidth={stroke} fill="none"
        strokeDasharray={`${dash} ${c}`} strokeLinecap="round"
        style={{ transition: 'stroke-dasharray 30ms' }} />
    </svg>
  );
};

// ── URL Input ────────────────────────────────────────────────────────────────
const UrlInput = ({ value, onChange, onSubmit, autoFocus }) => {
  const [focused, setFocused] = useState(false);
  return (
    <motion.div
      className={`url-input-wrap ${focused ? 'focused' : ''}`}
      whileFocus={{ scale: 1.01 }}
    >
      <motion.div animate={{ rotate: focused ? 15 : 0 }} transition={{ duration: 0.3 }}>
        <I.Link size={18} />
      </motion.div>
      <input
        autoFocus={autoFocus}
        value={value}
        onChange={(e) => onChange(e.target.value)}
        onFocus={() => setFocused(true)}
        onBlur={() => setFocused(false)}
        onKeyDown={(e) => { if (e.key === 'Enter') onSubmit(); }}
        placeholder="Paste any public video URL..."
      />
      <MagBtn className="btn btn-accent" style={{ height: 48 }} onClick={onSubmit}>
        <span key="label">Analyze Video</span><I.ArrowRight key="icon" size={14} style={{ color: '#fff' }} />
      </MagBtn>
    </motion.div>
  );
};

// ── Verdict Pill ─────────────────────────────────────────────────────────────
const Verdict = ({ kind, label }) => {
  const map = {
    accurate: 'accurate', mostly: 'mostly', misleading: 'misleading',
    false: 'false', unverified: 'unverified',
  };
  return (
    <motion.span
      className={`verdict ${map[kind] || 'unverified'}`}
      initial={{ scale: 0.8, opacity: 0 }}
      animate={{ scale: 1, opacity: 1 }}
      transition={{ duration: 0.3, ease: [0.16, 1, 0.3, 1] }}
      whileHover={{ scale: 1.06 }}
    >
      <span className="verdict-dot-sm"></span>
      {label}
    </motion.span>
  );
};

// ── Floating Particles ────────────────────────────────────────────────────────
const FloatingParticle = ({ x, y, delay, size }) => (
  <motion.div
    style={{
      position: 'absolute', left: x + '%', top: y + '%',
      width: size, height: size, borderRadius: '50%',
      background: 'var(--accent)', opacity: 0.08, pointerEvents: 'none',
    }}
    animate={{
      y: [0, -30, 0],
      x: [0, 10, 0],
      opacity: [0.08, 0.16, 0.08],
      scale: [1, 1.2, 1],
    }}
    transition={{
      duration: 6 + Math.random() * 4,
      delay,
      repeat: Infinity,
      ease: 'easeInOut',
    }}
  />
);

Object.assign(window, { Nav, Footer, CountUp, ScoreRing, SmallRing, Reveal, UrlInput, Verdict, showToast, MagBtn, fadeUp, fadeIn, scaleIn, slideRight, FloatingParticle });
