/* global React, Icon */
// FitMyRecipe — Hero with the interactive dish-morph engine.
(function(){
const { useRef, useEffect } = React;
const hh = React.createElement;

// ingredient tokens — spread around her: top, far-left and a little to her right.
const TOKENS = [
  { x:13, y:18, sz:46, color:'var(--tomato)',    ic:'bolt',  type:'veg', depth:24 },  // left, below the calories chip
  { x:58, y:0,  sz:40, color:'var(--carrot)',    ic:'bolt',  type:'veg', depth:28 },  // top, above her
  { x:85, y:12, sz:48, color:'var(--leaf-deep)', ic:'leaf',  type:'veg', depth:22 },  // right, upper
  { x:-4, y:22, sz:50, color:'var(--citrus)',    ic:'star',  type:'veg', depth:18 },  // far-left, upper
  { x:-9, y:63, sz:36, color:'var(--leaf)',      ic:'leaf',  type:'veg', depth:24 },  // far-left, lower (below the protein chip, clear of the plate)
  // indulgent items that leave
  { x:90, y:42, sz:40, color:'#E8D9B0', ink:'#7a5a16', ic:'scale', type:'bad', depth:20 },  // right, lower
  { x:9,  y:80, sz:38, color:'#E9DCC0', ink:'#7a5a16', ic:'flame', type:'bad', depth:22 },  // bottom-left
];

// macro chips: [label, origValue, upValue, suffix, dir, icon, iconBg, iconColor]
const CHIPS = [
  { key:'cal', label:'Calories', from:560, to:430, suf:'',  dir:'down', ic:'flame',   bg:'color-mix(in srgb,var(--carrot) 16%,#fff)', ink:'var(--carrot)', cls:'chip-cal' },
  { key:'pro', label:'Protein',  from:32,  to:48,  suf:'g', dir:'up',   ic:'bolt',    bg:'color-mix(in srgb,var(--leaf) 16%,#fff)',   ink:'var(--leaf-deep)', cls:'chip-pro' },
  { key:'fib', label:'Fiber',    from:4,   to:11,  suf:'g', dir:'up',   ic:'leaf',    bg:'color-mix(in srgb,var(--leaf) 16%,#fff)',   ink:'var(--leaf-deep)', cls:'chip-fib' },
];

function Hero({ heroStyle }){
  const stageRef = useRef(null);
  const plateRef = useRef(null);
  const wrapRef  = useRef(null);
  const upRef    = useRef(null);
  const haloRef  = useRef(null);
  const tokRefs  = useRef([]);
  const chipValRefs = useRef({});
  const state = useRef({ px:0.5, py:0.5, tpx:0.5, tpy:0.5, hover:0, thover:0, raf:0, demo:0, demoActive:true });

  useEffect(()=>{
    const stage = stageRef.current, plate = plateRef.current, up = upRef.current, halo = haloRef.current;
    const hit = wrapRef.current || stage;
    const s = state.current;
    const reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
    if(reduce){ s.demoActive = false; }   // honor reduced-motion: no idle auto-sweep
    const touchMode = () => matchMedia('(hover: none)').matches || window.innerWidth <= 700;
    let last = performance.now();

    // on touch there is no cursor — the morph is driven by scroll instead
    if(touchMode()){
      s.demoActive = false;
      const hint = stage.querySelector('.morph-hint');
      if(hint && hint.lastChild) hint.lastChild.textContent = 'Scroll to see it transform';
    }

    function scrollProgress(){
      const r = plate.getBoundingClientRect();
      const vh = window.innerHeight || 800;
      const center = r.top + r.height/2;
      let p = (vh*0.82 - center) / (vh*0.82 - vh*0.36);
      return Math.min(1, Math.max(0, p));
    }
    const style0 = heroStyle || 'dissolve';

    function onMove(e){
      const r = plate.getBoundingClientRect();
      s.tpx = Math.min(1, Math.max(0, (e.clientX - r.left) / r.width));
      s.tpy = Math.min(1, Math.max(0, (e.clientY - r.top) / r.height));
      s.thover = 1; s.demoActive = false;
    }
    function onLeave(){ s.thover = 0; }
    hit.addEventListener('pointermove', onMove);
    hit.addEventListener('pointerleave', onLeave);

    function loop(now){
      const dt = Math.min(40, now - last); last = now;
      const k = 1 - Math.pow(0.0001, dt/1000); // smoothing

      // auto demo sweep until first interaction (pointer devices only)
      if(touchMode()){
        const p = scrollProgress();
        s.thover = p;
        s.tpx = (style0 === 'split') ? p : 0.5;
        s.tpy = 0.5;
      } else if(s.demoActive){
        s.demo += dt/1000;
        const t = s.demo;
        if(t > 1.1){
          const ph = (t - 1.1);
          s.thover = ph < 2.4 ? 1 : 0;
          s.tpx = 0.5 + 0.26*Math.sin(ph*1.5);
          s.tpy = 0.5 + 0.12*Math.cos(ph*1.1);
          if(ph > 4.2){ s.demo = 0; }
        }
      }

      s.px += (s.tpx - s.px)*k;
      s.py += (s.tpy - s.py)*k;
      s.hover += (s.thover - s.hover)*k*0.9;

      const style = style0;
      let morph; // 0..1 used for chips/tokens/badge
      if(style === 'split') morph = s.px;
      else morph = s.hover;

      // ---- image reveal per variant ----
      if(style === 'lens'){
        const R = (14 + s.hover*30); // % radius
        up.style.clipPath = `circle(${R}% at ${s.px*100}% ${s.py*100}%)`;
        up.style.opacity = 1;
        plate.classList.add('show-halo');
        const r = plate.getBoundingClientRect();
        halo.style.left = (s.px*100)+'%'; halo.style.top = (s.py*100)+'%';
        halo.style.boxShadow = `0 0 0 1.5px rgba(212,175,55,.9), 0 0 0 ${R/100*r.width}px rgba(212,175,55,.08), 0 0 50px 10px rgba(212,175,55,${.1+s.hover*.2})`;
      } else if(style === 'split'){
        up.style.clipPath = `inset(0 ${(1-s.px)*100}% 0 0)`;
        up.style.opacity = 1;
        plate.classList.remove('show-halo');
        halo.style.boxShadow='none';
      } else { // dissolve
        up.style.clipPath = 'none';
        up.style.opacity = s.hover;
        up.style.transform = `scale(${1.12 - s.hover*0.05})`;
        plate.classList.remove('show-halo');
        halo.style.boxShadow='none';
      }

      // ---- stage state class (chips emphasis, badge, hint) ----
      stage.classList.toggle('on', morph > 0.5);

      // ---- tokens: parallax + fly in/out ----
      const offx = (s.px - 0.5), offy = (s.py - 0.5);
      TOKENS.forEach((tk, i)=>{
        const el = tokRefs.current[i]; if(!el) return;
        const tx = offx * tk.depth, ty = offy * tk.depth;
        let sc, op;
        if(tk.type === 'veg'){ sc = 0.45 + morph*0.55; op = morph; }
        else { sc = 1 - morph*0.5; op = 1 - morph; ty2:0; }
        const floatY = reduce ? 0 : Math.sin(now/900 + i*1.3) * 5;
        el.style.transform = `translate(${tx}px, ${ty + floatY}px) scale(${sc})`;
        el.style.opacity = op;
      });

      // ---- chips: interpolate numbers ----
      CHIPS.forEach(c=>{
        const ref = chipValRefs.current[c.key]; if(!ref) return;
        const v = Math.round(c.from + (c.to - c.from)*morph);
        ref.num.textContent = v + c.suf;
        const showDelta = morph > 0.05;
        ref.delta.style.opacity = showDelta ? 1 : 0;
        const d = c.to - c.from;
        ref.delta.textContent = (d>0?'+':'') + Math.round(d*morph) + c.suf;
      });

      s.raf = requestAnimationFrame(loop);
    }
    s.raf = requestAnimationFrame(loop);
    return ()=>{ cancelAnimationFrame(s.raf); hit.removeEventListener('pointermove', onMove); hit.removeEventListener('pointerleave', onLeave); };
  }, [heroStyle]);

  return hh('section', { className:'hero container', id:'top', ref:(el)=>{ if(el) requestAnimationFrame(()=>el.classList.add('in')); } },
    hh('div', { className:'hero-grid' },
      // ---- left column ----
      hh('div', { className:'hero-copy' },
        hh('div', { className:'hero-eyebrow rise d1' }, hh('span',{className:'dot'}), hh('span',{className:'overline'},'AI Macro Chef')),
        hh('h1', { className:'rise d1' },
          'Every recipe, ', hh('br'), 'made ', hh('span',{className:'swap'},'fitter'), '.'
        ),
        hh('p', { className:'lede rise d2' },
          'Save any recipe from anywhere. FitMyRecipe rebuilds it healthier, lighter or higher-protein — ',
          'and keeps the flavor you already love.'
        ),
        hh('div', { className:'hero-actions rise d3' },
          hh('div', { className:'store-row' },
            hh('a', { className:'btn btn-primary btn-lg', href:'#download' }, 'Get early access', hh(Icon.arrowR,{size:18})),
            hh('a', { className:'btn btn-ghost btn-lg', href:'#how' }, 'See how it works')
          ),
          hh('div', { className:'hero-note' }, hh(Icon.shield,{size:16, style:{color:'var(--leaf-deep)'}}),
            hh('span', null, 'Launching soon · ', hh('b',null,'join the waitlist'), ' to be first in line.'))
        )
      ),
      // ---- right column: chef + interactive plate ----
      hh('div', { className:'hero-stage-wrap rise d2' },
        hh('div', { className:'stage chef-stage', ref:stageRef },
          hh('img', { className:'chef-hero', src:'assets/hero-chef.jpg', alt:'Sofia presenting an upgraded dish' }),
          // produce tokens drifting in the open space beside her
          hh('div', { className:'produce' },
            TOKENS.map((tk,i)=> hh('div', {
              key:i, className:'p '+tk.type, ref:(el)=>tokRefs.current[i]=el,
              style:{ left:tk.x+'%', top:tk.y+'%', '--sz':tk.sz+'px', '--pc':tk.color, color: tk.ink || '#fff' }
            }, hh(Icon[tk.ic],{size:tk.sz*0.5})))
          ),
          // the plate floats over her open palm
          hh('div', { className:'chef-plate-wrap', ref:wrapRef },
            hh('div', { className:'stage-ring' }),
            hh('div', { className:'plate', ref:plateRef },
              hh('img', { className:'img-orig', src:'assets/hero-before.jpg', alt:'Original creamy chicken pasta' }),
              hh('img', { className:'img-up', ref:upRef, src:'assets/hero-after.jpg', alt:'Upgraded high-protein chicken pasta', style:{opacity:0} }),
              hh('div', { className:'lens-halo', ref:haloRef })
            ),
            hh('div', { className:'up-badge floaty' }, hh(Icon.crown,{size:14}), 'Upgraded'),
            hh('div', { className:'morph-hint' }, hh(Icon.refresh,{size:15}), 'Move your cursor over the dish')
          ),
          // macro chips
          CHIPS.map(c=> hh('div', { key:c.key, className:'macro-chip floaty '+c.cls },
            hh('div',{className:'ic', style:{ background:c.bg, color:c.ink }}, hh(Icon[c.ic],{size:16})),
            hh('div', null,
              hh('div',{className:'mk'}, c.label),
              hh('div',{className:'mv'},
                hh('span',{ ref:(el)=>{ chipValRefs.current[c.key]=chipValRefs.current[c.key]||{}; if(el) chipValRefs.current[c.key].num=el; } }, c.from + c.suf),
                hh('span',{ className:'delta '+c.dir, style:{opacity:0}, ref:(el)=>{ chipValRefs.current[c.key]=chipValRefs.current[c.key]||{}; if(el) chipValRefs.current[c.key].delta=el; } }, '')
              )
            )
          ))
        )
      )
    )
  );
}
window.Hero = Hero;
})();
