// tech.jsx - "Your solution, our stack". Faithful port of the original: a Solutions
// column, six tech-category columns, and a Results column, with an SVG neural path
// that weaves from the active solution → through each tech in its stack → to its result.
// Nodes activate in sequence with a traveling signal pulse. Rebuilt on-brand (Violet Blue).

const CATEGORIES = [
  { name: 'Frontend', techs: ['Next.js', 'React', 'Dashboards', 'React Native'] },
  { name: 'Backend', techs: ['Node.js', 'Django', 'Python', 'Go'] },
  { name: 'Cloud', techs: ['AWS', 'Azure', 'Google Cloud'] },
  { name: 'Data', techs: ['PostgreSQL', 'Redis', 'Analytics', 'Elasticsearch', 'Data Lake'] },
  { name: 'AI/ML', techs: ['Recommendations', 'Claude AI', 'LLM Agents', 'Predictive ML', 'Process AI', 'On-device AI'] },
  { name: 'DevOps', techs: ['CI/CD', 'GitLab CI', 'LLMOps', 'Pipelines', 'Auto-scaling', 'Fastlane'] },
];

const PROJECTS = [
  { name: 'Operations Hub', stack: ['React', 'Node.js', 'Azure', 'Data Lake', 'Process AI', 'Auto-scaling'], result: '−70–80% manual tasks in 30 days' },
  { name: 'AI Support Agent', stack: ['React', 'Python', 'Google Cloud', 'Analytics', 'LLM Agents', 'LLMOps'], result: '−60–70% tickets · 24/7 coverage' },
  { name: 'Business Intelligence', stack: ['Dashboards', 'Python', 'Google Cloud', 'Elasticsearch', 'Predictive ML', 'Pipelines'], result: 'Decisions in minutes, not days' },
  { name: 'Online Store', stack: ['Next.js', 'Node.js', 'AWS', 'PostgreSQL', 'Recommendations', 'CI/CD'], result: '+40–50% sales · Zero downtime' },
  { name: 'Custom SaaS', stack: ['React', 'Django', 'Azure', 'Redis', 'Claude AI', 'GitLab CI'], result: 'Idea to production in 6–8 weeks' },
  { name: 'Mobile App', stack: ['React Native', 'Go', 'AWS', 'PostgreSQL', 'On-device AI', 'Fastlane'], result: 'Your brand in every pocket' },
];

const ROTATE_MS = 3600;
const STEP_MS = 110;
const RESUME_MS = 2000;

function Tech() {
  const [ref, inView] = useInView({ threshold: 0.25 });
  const containerRef = React.useRef(null);
  const solRefs = React.useRef(new Map());
  const techRefs = React.useRef(new Map());
  const resRefs = React.useRef(new Map());

  const [active, setActive] = React.useState(0);
  const [auto, setAuto] = React.useState(true);
  const [pathD, setPathD] = React.useState('');
  const [pathKey, setPathKey] = React.useState(0);
  const [activated, setActivated] = React.useState(() => new Set());
  const [showPulse, setShowPulse] = React.useState(true);
  const pulseTimer = React.useRef(null);
  const [pos, setPos] = React.useState(null);
  const resumeRef = React.useRef(null);
  const stepTimers = React.useRef([]);

  const proj = PROJECTS[active];

  // measure node positions relative to the container
  const measure = React.useCallback(() => {
    const c = containerRef.current;
    if (!c) return;
    const cr = c.getBoundingClientRect();
    const m = new Map();
    const add = (key, el) => { if (el) { const r = el.getBoundingClientRect(); m.set(key, { left: r.left - cr.left, top: r.top - cr.top, w: r.width, h: r.height }); } };
    solRefs.current.forEach((el, k) => add('sol-' + k, el));
    techRefs.current.forEach((el, k) => add(k, el));
    resRefs.current.forEach((el, k) => add('res-' + k, el));
    setPos(m);
  }, []);

  React.useEffect(() => {
    measure();
    const t = setTimeout(measure, 200);
    window.addEventListener('resize', measure);
    return () => { clearTimeout(t); window.removeEventListener('resize', measure); };
  }, [measure, inView]);

  // build the weaving path for the active project
  React.useEffect(() => {
    if (!pos) { setPathD(''); return; }
    const sol = pos.get('sol-' + active);
    if (!sol) { setPathD(''); return; }
    let d = `M ${sol.left + sol.w} ${sol.top + sol.h / 2}`;
    let prevExit = sol.left + sol.w, prevY = sol.top + sol.h / 2;
    proj.stack.forEach((tech) => {
      const r = pos.get(tech);
      if (!r) return;
      const enterX = r.left, exitX = r.left + r.w, y = r.top + r.h / 2;
      const midX = (prevExit + enterX) / 2;
      d += ` C ${midX} ${prevY}, ${midX} ${y}, ${enterX} ${y} L ${exitX} ${y}`;
      prevExit = exitX; prevY = y;
    });
    const res = pos.get('res-' + active);
    if (res) {
      const rx = res.left, ry = res.top + res.h / 2, midX = (prevExit + rx) / 2;
      d += ` C ${midX} ${prevY}, ${midX} ${ry}, ${rx} ${ry}`;
    }
    setPathD(d);
    setPathKey((k) => k + 1);
  }, [active, pos]);

  // pulse plays ONCE per change then unmounts, so the SVG stops repainting when
  // idle (avoids constant backdrop-filter re-raster behind it = the main jank).
  React.useEffect(() => {
    setShowPulse(true);
    if (pulseTimer.current) clearTimeout(pulseTimer.current);
    pulseTimer.current = setTimeout(() => setShowPulse(false), 1700);
    return () => { if (pulseTimer.current) clearTimeout(pulseTimer.current); };
  }, [active]);

  // sequential node activation, TIMED so each chip reaches full opacity/blur exactly
  // as the drawing line arrives at it (lead by the 300ms chip transition).
  const DRAW_MS = 1000, CHIP_TRANS = 300;
  React.useEffect(() => {
    stepTimers.current.forEach(clearTimeout);
    stepTimers.current = [];
    setActivated(new Set());
    const sol = pos && pos.get('sol-' + active);
    const res = pos && pos.get('res-' + active);
    proj.stack.forEach((tech, i) => {
      let delay = i * 110; // fallback before positions are measured
      if (sol && res) {
        const tr = pos.get(tech);
        if (tr) {
          const solR = sol.left + sol.w, resL = res.left, span = resL - solR;
          const f = span > 0 ? Math.min(1, Math.max(0, (tr.left - solR) / span)) : 0;
          delay = Math.max(0, DRAW_MS * f - CHIP_TRANS);
        }
      }
      const id = setTimeout(() => setActivated((prev) => new Set(prev).add(tech)), delay);
      stepTimers.current.push(id);
    });
    return () => stepTimers.current.forEach(clearTimeout);
  }, [active, pos]);

  // auto-rotate
  React.useEffect(() => {
    if (!inView || !auto) return;
    const id = setInterval(() => setActive((a) => (a + 1) % PROJECTS.length), ROTATE_MS);
    return () => clearInterval(id);
  }, [inView, auto]);

  const pick = (i) => {
    if (resumeRef.current) clearTimeout(resumeRef.current);
    setAuto(false); setActive(i);
  };
  const scheduleResume = () => {
    if (resumeRef.current) clearTimeout(resumeRef.current);
    resumeRef.current = setTimeout(() => setAuto(true), RESUME_MS);
  };

  const activeStack = new Set(proj.stack);

  const SideBtn = ({ i, label, refMap, keyPrefix }) => {
    const on = i === active;
    return (
      <button
        ref={(el) => refMap.current.set(i, el)}
        onMouseEnter={() => pick(i)} onMouseLeave={scheduleResume} onClick={() => pick(i)}
        aria-pressed={on}
        style={{
          all: 'unset', boxSizing: 'border-box', cursor: 'pointer', textAlign: 'center',
          padding: 'clamp(7px, 1vh, 10px) 12px', borderRadius: 12, fontSize: 13, fontWeight: on ? 600 : 500, lineHeight: 1.25,
          minHeight: 'clamp(34px, 4.8vh, 42px)', display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: on ? 'var(--accent)' : 'var(--fg-muted)',
          background: on
            ? 'linear-gradient(0deg, var(--accent-bg), var(--accent-bg)), rgba(var(--glass-rgb,255,255,255), var(--tech-op,0.58))'
            : 'rgba(var(--glass-rgb,255,255,255), 0.3)',
          WebkitBackdropFilter: on ? 'blur(var(--tech-blur,6px))' : 'none', backdropFilter: on ? 'blur(var(--tech-blur,6px))' : 'none',
          border: `1px solid ${on ? 'var(--accent)' : 'var(--hairline)'}`,
          boxShadow: on ? '0 0 20px color-mix(in srgb, var(--accent) 30%, transparent)' : 'none',
          transform: on ? 'scale(1.02)' : 'scale(1)', transition: 'all 300ms ease',
        }}>{label}</button>
    );
  };

  return (
    <section id="tech" data-screen-label="Tech" className="sec" aria-labelledby="tech-h"
      style={{ minHeight: 'calc(100svh - 72px)', display: 'flex', flexDirection: 'column', justifyContent: 'center', paddingBlock: 'clamp(24px, 3.5vh, 56px) clamp(48px, 6.5vh, 80px)' }}>
      <div className="sec-wrap" ref={ref} style={{ maxWidth: 1480 }} onMouseLeave={scheduleResume}>
        <SectionHead eyebrow="The stack" align="center" max={640} style={{ marginBottom: 'clamp(20px, 3vh, 34px)' }}
          sub="Every project gets a purpose-built stack. Pick a solution to see how it comes together.">
          <span id="tech-h">Your solution, our <span className="accent">stack</span></span>
        </SectionHead>

        {/* desktop: full neural grid */}
        <div className="tech-stage" ref={containerRef} style={{ position: 'relative' }}>
          <svg className="tech-svg" aria-hidden="true">
            <defs>
              <linearGradient id="neuralGrad" x1="0%" y1="0%" x2="100%" y2="0%">
                <stop offset="0%" stopColor="var(--accent)" />
                <stop offset="55%" stopColor="var(--violet-soft)" />
                <stop offset="100%" stopColor="var(--fg)" />
              </linearGradient>
              <linearGradient id="signalPulse" x1="0%" y1="0%" x2="100%" y2="0%">
                <stop offset="0%" stopColor="var(--accent)" stopOpacity="0"><animate attributeName="offset" values="-0.2;1" dur="1.5s" repeatCount="indefinite" /></stop>
                <stop offset="20%" stopColor="var(--violet-soft)" stopOpacity="1"><animate attributeName="offset" values="0;1.2" dur="1.5s" repeatCount="indefinite" /></stop>
                <stop offset="40%" stopColor="var(--accent)" stopOpacity="0"><animate attributeName="offset" values="0.2;1.4" dur="1.5s" repeatCount="indefinite" /></stop>
              </linearGradient>
              <filter id="neuralGlow" x="-20%" y="-20%" width="140%" height="140%">
                <feGaussianBlur stdDeviation="3.5" result="b" /><feMerge><feMergeNode in="b" /><feMergeNode in="SourceGraphic" /></feMerge>
              </filter>
            </defs>
            {pathD && (
              <g key={pathKey}>
                <path d={pathD} pathLength="1" fill="none" stroke="url(#neuralGrad)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" opacity="0.32"
                  style={{ strokeDasharray: 1, strokeDashoffset: 1, animation: 'drawLine 1s linear both' }} />
                {showPulse && (
                  <React.Fragment>
                    {/* cheap glow: a wide low-opacity underlay instead of an feGaussianBlur filter */}
                    <path d={pathD} pathLength="1" fill="none" stroke="url(#signalPulse)" strokeWidth="8" strokeLinecap="round" strokeLinejoin="round" opacity="0.35"
                      style={{ strokeDasharray: 1, strokeDashoffset: 1, animation: 'drawLine 0.85s ease-out both' }} />
                    <path d={pathD} pathLength="1" fill="none" stroke="url(#signalPulse)" strokeWidth="3.5" strokeLinecap="round" strokeLinejoin="round"
                      style={{ strokeDasharray: 1, strokeDashoffset: 1, animation: 'drawLine 0.85s ease-out both' }} />
                  </React.Fragment>
                )}
              </g>
            )}
          </svg>

          <div className="tech-grid">
            {/* Solutions */}
            <div className="tech-side">
              <h4 className="tech-colhead" style={{ color: 'var(--accent)' }}>Solutions</h4>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 8, flex: 1, justifyContent: 'center' }}>
                {PROJECTS.map((p, i) => <SideBtn key={p.name} i={i} label={p.name} refMap={solRefs} keyPrefix="sol" />)}
              </div>
            </div>

            <div className="tech-divider" />

            {/* Categories */}
            <div className="tech-cats">
              {CATEGORIES.map((cat) => (
                <div key={cat.name} style={{ display: 'flex', flexDirection: 'column' }}>
                  <h4 className="tech-colhead" style={{ color: 'var(--fg-faint)' }}>{cat.name}</h4>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 6, flex: 1, justifyContent: 'center' }}>
                    {cat.techs.map((tech) => {
                      const inPath = activeStack.has(tech);
                      const lit = activated.has(tech);
                      return (
                        <div key={tech} ref={(el) => techRefs.current.set(tech, el)} className={lit ? 'tk-surface on' : ''} style={{
                          padding: '7px 6px', borderRadius: 9, fontSize: 11.5, textAlign: 'center', lineHeight: 1.2,
                          color: lit ? 'var(--accent)' : (inPath ? 'var(--fg-muted)' : 'var(--fg-faint)'),
                          background: lit ? undefined : 'transparent',
                          border: `1px solid ${lit ? 'var(--accent)' : (inPath ? 'var(--eyebrow-bd)' : 'var(--hairline)')}`,
                          transform: lit ? 'scale(1.05)' : 'scale(1)',
                          boxShadow: lit ? '0 0 16px color-mix(in srgb, var(--accent) 30%, transparent)' : 'none',
                          transition: 'all 300ms ease',
                        }}>{tech}</div>
                      );
                    })}
                  </div>
                </div>
              ))}
            </div>

            <div className="tech-divider" />

            {/* Results */}
            <div className="tech-side">
              <h4 className="tech-colhead" style={{ color: 'var(--accent)' }}>Results</h4>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 8, flex: 1, justifyContent: 'center' }}>
                {PROJECTS.map((p, i) => <SideBtn key={p.name} i={i} label={p.result} refMap={resRefs} keyPrefix="res" />)}
              </div>
            </div>
          </div>

          {/* auto-cycle indicator - inside .tech-stage at its bottom edge, no layout impact */}
          <div style={{
            position: 'absolute', left: '50%', bottom: 4, transform: 'translateX(-50%)',
            display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
            fontSize: 12, color: auto ? 'var(--accent)' : 'var(--fg-faint)', whiteSpace: 'nowrap', pointerEvents: 'none',
          }}>
            <span style={{ width: 7, height: 7, borderRadius: 999, background: auto ? 'var(--accent)' : 'var(--fg-faint)', animation: auto ? 'breathe 1.6s ease-in-out infinite' : 'none' }} />
            <span>{auto ? 'Auto-cycling. Hover any solution to pause' : 'Paused • resumes shortly'}</span>
          </div>
        </div>

        {/* mobile fallback */}
        <div className="tech-mobile">
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, justifyContent: 'center', marginBottom: 18 }}>
            {PROJECTS.map((p, i) => {
              const on = i === active;
              return (
                <button key={p.name} onClick={() => pick(i)} style={{
                  all: 'unset', cursor: 'pointer', padding: '9px 14px', borderRadius: 999, fontSize: 13, fontWeight: on ? 600 : 500,
                  color: on ? 'var(--accent)' : 'var(--fg-muted)', background: on ? 'var(--accent-bg)' : 'color-mix(in srgb, var(--fg) 4%, transparent)',
                  border: `1px solid ${on ? 'var(--accent)' : 'var(--hairline)'}`,
                }}>{p.name}</button>
              );
            })}
          </div>
          <div className="glass" style={{ borderRadius: 16, padding: 20 }}>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 7, justifyContent: 'center', marginBottom: 16 }}>
              {proj.stack.map((t) => (
                <span key={t} style={{ fontSize: 12, padding: '5px 11px', borderRadius: 999, color: 'var(--accent)', background: 'var(--accent-bg)', border: '1px solid var(--eyebrow-bd)' }}>{t}</span>
              ))}
            </div>
            <p style={{ textAlign: 'center', margin: 0, fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: '1.1rem', color: 'var(--fg)' }}>
              <span style={{ color: 'var(--accent)' }}>→ </span>{proj.result}
            </p>
          </div>
        </div>
      </div>
    </section>
  );
}

window.Tech = Tech;
