/* Skills / Tech Stack — interactive constellation + category bento.
   Tech orbits a central node; clicking a category lights up its members
   with animated connection lines. */

const GROUPS = [
  {
    id: 'ai',
    title: 'AI & Automation',
    icon: 'Brain',
    summary: 'Bespoke ML, agents, and workflows that take repetitive work off your plate.',
    items: [
      { name: 'OpenAI',     brand: 'OpenAI' },
      { name: 'Zapier',     brand: 'Zapier' },
      { name: 'LangChain',  brand: 'LangChain' },
      { name: 'Puppeteer',  brand: 'Puppeteer' },
    ],
  },
  {
    id: 'dev',
    title: 'Development',
    icon: 'Code',
    summary: 'Full-stack on Node + React, with native-feeling mobile apps.',
    items: [
      { name: 'Node.js',     brand: 'NodeJS' },
      { name: 'React',       brand: 'ReactLogo' },
      { name: 'iOS / macOS', brand: 'Apple' },
      { name: 'TypeScript',  brand: 'TypeScript' },
    ],
  },
  {
    id: 'infra',
    title: 'Infrastructure',
    icon: 'Cloud',
    summary: 'Edge-first deploys with cost-aware scaling and proper observability.',
    items: [
      { name: 'Vercel',       brand: 'Vercel' },
      { name: 'DigitalOcean', brand: 'DigitalOcean' },
      { name: 'Cloudflare',   brand: 'Cloudflare' },
      { name: 'PostgreSQL',   brand: 'Postgres' },
    ],
  },
];

// Position each tech on a ring around center (cx, cy). Three rings, one per group.
const NODES = (() => {
  const cx = 50, cy = 50;
  const out = [];
  GROUPS.forEach((g, gi) => {
    const radius = 28 + gi * 7; // % of svg viewBox
    const total = g.items.length;
    g.items.forEach((it, i) => {
      // distribute around the circle, slight offset per group so they don't align
      const angle = (i / total) * Math.PI * 2 + (gi * 0.4);
      out.push({
        ...it,
        groupId: g.id,
        x: cx + Math.cos(angle) * radius,
        y: cy + Math.sin(angle) * radius,
      });
    });
  });
  return out;
})();

const Skills = () => {
  const [active, setActive] = React.useState('all');
  const ref = React.useRef(null);
  const { scrollYProgress } = useScroll({ target: ref, offset: ['start end', 'end start'] });
  const intensity = (window.__tweaks?.motion ?? 60) / 100;
  const constellationRotate = useTransform(scrollYProgress, [0, 1], [-30 * intensity, 30 * intensity]);

  const isLit = (groupId) => active === 'all' || active === groupId;

  return (
    <Section id="stack" className="border-t hairline">
      <div className="flex flex-col md:flex-row md:items-end md:justify-between gap-6 mb-12">
        <div>
          <Eyebrow index="04">Stack</Eyebrow>
          <SectionTitle className="mt-5">
            Tools I reach for<br />
            <span style={{ fontFamily: "'Instrument Serif', serif", fontStyle: 'italic', fontWeight: 400 }}>without thinking.</span>
          </SectionTitle>
        </div>
        <p className="max-w-md text-sm leading-relaxed" style={{ color: 'var(--fg-muted)' }}>
          A connected toolkit, not a laundry list. Click a category below to see how the parts wire together.
        </p>
      </div>

      {/* Category filter pills */}
      <div className="flex flex-wrap items-center gap-2 mb-8">
        {[{ id: 'all', title: 'All', icon: 'Boxes' }, ...GROUPS].map(c => {
          const Ic = I[c.icon];
          const isActive = active === c.id;
          return (
            <motion.button
              key={c.id}
              onClick={() => setActive(c.id)}
              whileHover={{ y: -2 }}
              whileTap={{ scale: 0.97 }}
              className="relative flex items-center gap-2 px-4 h-10 rounded-full text-[13px] transition-colors"
              style={{
                border: '1px solid ' + (isActive ? 'var(--accent)' : 'var(--line-strong)'),
                color: isActive ? 'var(--accent)' : 'var(--fg-muted)',
                background: isActive ? 'var(--accent-soft)' : 'transparent',
              }}
            >
              {isActive && (
                <motion.span
                  layoutId="stack-active"
                  className="absolute inset-0 rounded-full -z-0"
                  style={{ background: 'var(--accent-soft)', border: '1px solid var(--accent)' }}
                  transition={{ type: 'spring', stiffness: 360, damping: 28 }}
                />
              )}
              <span className="relative z-10 flex items-center gap-2">
                <Ic size={14} />
                {c.title}
              </span>
            </motion.button>
          );
        })}
      </div>

      <div ref={ref} className="grid lg:grid-cols-12 gap-5">
        {/* ── Constellation ─────────────────────────────────────────── */}
        <motion.div
          {...fadeUp(0)}
          className="lg:col-span-7 card rounded-2xl relative overflow-hidden"
          style={{ minHeight: 480, background: 'var(--bg-card)' }}
        >
          {/* radial accent */}
          <div className="absolute inset-0 pointer-events-none" style={{ background: 'radial-gradient(circle at 50% 50%, var(--accent-soft) 0%, transparent 60%)' }} aria-hidden></div>
          {/* grid */}
          <div className="absolute inset-0 bg-grid opacity-30" aria-hidden></div>

          {/* Header */}
          <div className="relative px-6 py-4 border-b hairline flex items-center justify-between">
            <div className="flex items-center gap-2 font-mono text-[10px] uppercase tracking-[0.2em]" style={{ color: 'var(--fg-dim)' }}>
              <span className="w-1.5 h-1.5 rounded-full animate-pulse" style={{ background: 'var(--accent)' }}></span>
              <span>stack.constellation</span>
            </div>
            <div className="font-mono text-[10px]" style={{ color: 'var(--fg-dim)' }}>{NODES.length} nodes</div>
          </div>

          <motion.div style={{ rotate: constellationRotate }} className="relative" >
            <svg viewBox="0 0 100 100" className="block w-full" style={{ height: 'min(60vh, 420px)' }} preserveAspectRatio="xMidYMid meet">
              {/* Concentric rings */}
              {[28, 35, 42].map((r, i) => (
                <motion.circle
                  key={r}
                  cx="50" cy="50" r={r}
                  fill="none"
                  stroke="currentColor"
                  strokeOpacity={isLit(GROUPS[i].id) ? 0.5 : 0.12}
                  strokeWidth="0.15"
                  style={{ color: isLit(GROUPS[i].id) ? 'var(--accent)' : 'var(--fg-dim)' }}
                  initial={{ pathLength: 0 }}
                  whileInView={{ pathLength: 1 }}
                  viewport={{ once: true }}
                  transition={{ duration: 1.4, delay: i * 0.15 }}
                />
              ))}

              {/* Connection lines from center to lit nodes */}
              {NODES.map((n, i) => (
                <motion.line
                  key={`l-${i}`}
                  x1="50" y1="50" x2={n.x} y2={n.y}
                  stroke="var(--accent)"
                  strokeWidth="0.2"
                  strokeDasharray="0.8 0.8"
                  initial={{ pathLength: 0, opacity: 0 }}
                  animate={{
                    pathLength: isLit(n.groupId) ? 1 : 0,
                    opacity: isLit(n.groupId) ? 0.6 : 0,
                  }}
                  transition={{ duration: 0.6, delay: 0.05 * i, ease: [0.2, 0.7, 0.2, 1] }}
                />
              ))}

              {/* Center hub */}
              <motion.g
                animate={{ scale: [1, 1.05, 1] }}
                transition={{ duration: 3, repeat: Infinity, ease: 'easeInOut' }}
                style={{ transformOrigin: '50px 50px' }}
              >
                <circle cx="50" cy="50" r="6" fill="var(--bg-elev)" stroke="var(--accent)" strokeWidth="0.3" />
                <circle cx="50" cy="50" r="2.5" fill="var(--accent)" />
                <motion.circle
                  cx="50" cy="50" r="6"
                  fill="none" stroke="var(--accent)" strokeWidth="0.2"
                  animate={{ r: [6, 14], opacity: [0.6, 0] }}
                  transition={{ duration: 2.4, repeat: Infinity, ease: 'easeOut' }}
                />
              </motion.g>

              {/* Nodes */}
              {NODES.map((n, i) => {
                const lit = isLit(n.groupId);
                return (
                  <motion.g
                    key={n.name}
                    initial={{ opacity: 0, scale: 0 }}
                    whileInView={{ opacity: 1, scale: 1 }}
                    viewport={{ once: true }}
                    transition={{ delay: 0.4 + i * 0.04, duration: 0.5, ease: [0.2, 0.7, 0.2, 1] }}
                    style={{ transformOrigin: `${n.x}px ${n.y}px` }}
                  >
                    {/* Floating bob */}
                    <motion.g
                      animate={{ y: [0, -1.5, 0] }}
                      transition={{ duration: 3 + (i % 4), repeat: Infinity, ease: 'easeInOut', delay: i * 0.2 }}
                    >
                      <motion.circle
                        cx={n.x} cy={n.y} r="3.6"
                        fill="var(--bg-elev)"
                        stroke={lit ? 'var(--accent)' : 'var(--line-strong)'}
                        strokeWidth="0.25"
                        animate={{
                          opacity: lit ? 1 : 0.35,
                        }}
                        transition={{ duration: 0.4 }}
                      />
                      <foreignObject x={n.x - 2.6} y={n.y - 2.6} width="5.2" height="5.2" style={{ overflow: 'visible' }}>
                        <div xmlns="http://www.w3.org/1999/xhtml" style={{ width: '5.2px', height: '5.2px', display: 'grid', placeItems: 'center', filter: lit ? 'none' : 'grayscale(1)', opacity: lit ? 1 : 0.5, transition: 'all .3s' }}>
                          {(() => {
                            const Brand = (window.B && n.brand && window.B[n.brand]) ? window.B[n.brand] : null;
                            if (Brand) return <Brand size={4.4} />;
                            const Ic = I[n.icon] || I.Dot;
                            return <Ic size={2.4} strokeWidth={1.2} />;
                          })()}
                        </div>
                      </foreignObject>
                    </motion.g>
                  </motion.g>
                );
              })}
            </svg>
          </motion.div>

          {/* Floating tech labels (DOM, not SVG, so they read crisp) */}
          <div className="relative px-6 py-4 border-t hairline">
            <AnimatePresence mode="wait">
              <motion.div
                key={active}
                initial={{ opacity: 0, y: 6 }}
                animate={{ opacity: 1, y: 0 }}
                exit={{ opacity: 0, y: -6 }}
                transition={{ duration: 0.3 }}
                className="flex flex-wrap gap-1.5"
              >
                {NODES.filter(n => active === 'all' || n.groupId === active).map((n, i) => {
                  const Brand = (window.B && n.brand && window.B[n.brand]) ? window.B[n.brand] : null;
                  return (
                    <motion.span
                      key={n.name}
                      initial={{ opacity: 0, y: 4 }}
                      animate={{ opacity: 1, y: 0 }}
                      transition={{ delay: i * 0.03 }}
                      className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md font-mono text-[11px]"
                      style={{ background: 'var(--accent-soft)', color: 'var(--accent)' }}
                    >
                      {Brand ? <Brand size={13} /> : <I.Dot size={11} />}
                      {n.name}
                    </motion.span>
                  );
                })}
              </motion.div>
            </AnimatePresence>
          </div>
        </motion.div>

        {/* ── Category Cards ──────────────────────────────────────── */}
        <div className="lg:col-span-5 grid gap-5">
          {GROUPS.map((g, gi) => {
            const Ic = I[g.icon];
            const isFocused = active === g.id;
            return (
              <motion.button
                key={g.id}
                {...fadeUp(0.05 + gi * 0.08)}
                onClick={() => setActive(active === g.id ? 'all' : g.id)}
                whileHover={{ y: -3 }}
                className="card rounded-2xl p-5 text-left relative overflow-hidden group"
                style={{
                  borderColor: isFocused ? 'var(--accent)' : 'var(--line)',
                  background: isFocused ? 'var(--accent-soft)' : 'var(--bg-card)',
                }}
              >
                {/* shimmer line on hover */}
                <motion.div
                  className="absolute inset-x-0 top-0 h-px"
                  initial={{ scaleX: 0 }}
                  animate={{ scaleX: isFocused ? 1 : 0 }}
                  whileHover={{ scaleX: 1 }}
                  style={{ background: 'var(--accent)', transformOrigin: 'left' }}
                />
                <div className="flex items-start gap-4">
                  <motion.div
                    animate={isFocused ? { rotate: 360 } : { rotate: 0 }}
                    transition={{ duration: 0.7, ease: [0.2, 0.7, 0.2, 1] }}
                    className="grid place-items-center w-11 h-11 rounded-xl shrink-0"
                    style={{ background: isFocused ? 'var(--accent)' : 'var(--accent-soft)', color: isFocused ? '#fff' : 'var(--accent)' }}
                  >
                    <Ic size={18} />
                  </motion.div>
                  <div className="flex-1 min-w-0">
                    <div className="flex items-baseline justify-between gap-3">
                      <h3 className="text-base font-medium tracking-tight">{g.title}</h3>
                      <span className="font-mono text-[10px]" style={{ color: 'var(--fg-dim)' }}>0{gi + 1}</span>
                    </div>
                    <p className="mt-1.5 text-[13px] leading-relaxed" style={{ color: 'var(--fg-muted)', textWrap: 'pretty' }}>{g.summary}</p>

                    {/* Inline tech chips with brand logos */}
                    <div className="mt-3 flex flex-wrap gap-1.5">
                      {g.items.map((it, idx) => {
                        const Brand = (window.B && it.brand && window.B[it.brand]) ? window.B[it.brand] : null;
                        return (
                          <motion.span
                            key={it.name}
                            animate={{
                              opacity: isFocused ? 1 : 0.7,
                              scale: isFocused ? 1 : 0.96,
                            }}
                            transition={{ delay: idx * 0.04, duration: 0.3 }}
                            className="inline-flex items-center gap-1.5 px-2 py-1 rounded font-mono text-[10px]"
                            style={{
                              background: isFocused ? 'rgba(255,255,255,0.08)' : 'var(--bg-elev)',
                              color: isFocused ? 'var(--accent)' : 'var(--fg-muted)',
                              filter: isFocused ? 'none' : 'grayscale(0.6)',
                            }}
                          >
                            {Brand && <Brand size={12} />}
                            {it.name}
                          </motion.span>
                        );
                      })}
                    </div>
                  </div>
                </div>
              </motion.button>
            );
          })}
        </div>
      </div>
    </Section>
  );
};

window.Skills = Skills;
