// tacho.jsx — animated tachometer gauge + redline bar. Exports to window.
const { useState, useEffect, useRef } = React;

const REDLINE = 8000;          // max scale (x1000 -> 0..8)
const RED_FROM = 6500;         // red zone start

function angleFor(v){ return 225 + (Math.min(v,REDLINE)/REDLINE)*270; } // clockwise from north: 0->225(SW), max->495/135(SE), gap at bottom
function polar(cx,cy,r,deg){ const a=(deg-90)*Math.PI/180; return [cx+r*Math.cos(a),cy+r*Math.sin(a)]; }
function arcPath(cx,cy,r,d0,d1){
  const [x0,y0]=polar(cx,cy,r,d0), [x1,y1]=polar(cx,cy,r,d1);
  const large = (d1-d0)>180?1:0;
  return `M ${x0} ${y0} A ${r} ${r} 0 ${large} 1 ${x1} ${y1}`;
}

// count-up number hook
function useCountUp(target, run, dur=1900){
  const [val,setVal]=useState(0);
  useEffect(()=>{
    if(!run){ setVal(target); return; }
    let raf, start;
    const tick=(t)=>{ if(!start)start=t; const p=Math.min((t-start)/dur,1);
      const e=1-Math.pow(1-p,3); setVal(Math.round(target*e));
      if(p<1) raf=requestAnimationFrame(tick); };
    raf=requestAnimationFrame(tick);
    return ()=>cancelAnimationFrame(raf);
  },[target,run,dur]);
  return val;
}

function Tacho({ target=7900, animate=true, size=520 }){
  const cx=200, cy=205, R=168;
  // tick marks every 1000
  const majors=[]; const labels=[];
  for(let v=0; v<=REDLINE; v+=1000){
    const deg=angleFor(v);
    const [ox,oy]=polar(cx,cy,R,deg);
    const [ix,iy]=polar(cx,cy,R-22,deg);
    const red = v>=RED_FROM;
    majors.push(<line key={'M'+v} x1={ox} y1={oy} x2={ix} y2={iy}
      stroke={red?'var(--accent)':'#cfcfcf'} strokeWidth={3} strokeLinecap="round"/>);
    const [lx,ly]=polar(cx,cy,R-42,deg);
    labels.push(<text key={'L'+v} x={lx} y={ly} fill={red?'var(--accent)':'#bdbdbd'}
      fontFamily="var(--font-disp)" fontWeight="700" fontSize="22"
      textAnchor="middle" dominantBaseline="central">{v/1000}</text>);
  }
  // minor ticks every 500
  const minors=[];
  for(let v=0; v<=REDLINE; v+=250){
    if(v%1000===0) continue;
    const deg=angleFor(v); const [ox,oy]=polar(cx,cy,R,deg); const [ix,iy]=polar(cx,cy,R-11,deg);
    minors.push(<line key={'m'+v} x1={ox} y1={oy} x2={ix} y2={iy} stroke="#5a5a5a" strokeWidth={1.5}/>);
  }
  const endAngle = angleFor(target);
  const needleRef = useRef(null);
  useEffect(()=>{
    const g = needleRef.current; if(!g) return;
    const start = angleFor(0), end = endAngle;
    if(!animate){ g.setAttribute('transform', `rotate(${end} ${cx} ${cy})`); return; }
    g.setAttribute('transform', `rotate(${start} ${cx} ${cy})`);
    const dur=1700, delay=300;
    const ease = p => 1 - Math.pow(1-p, 3);
    let raf, t0=null;
    const step = (now)=>{
      if(t0===null) t0=now;
      const el = now - t0 - delay;
      if(el < 0){ raf=requestAnimationFrame(step); return; }
      const p = Math.min(el/dur, 1);
      const ang = start + (end-start)*ease(p);
      g.setAttribute('transform', `rotate(${ang} ${cx} ${cy})`);
      if(p<1) raf=requestAnimationFrame(step);
    };
    raf=requestAnimationFrame(step);
    return ()=>cancelAnimationFrame(raf);
  },[animate, endAngle, cx, cy]);

  return (
    <div>
      <svg className="tacho" viewBox="0 0 400 300" role="img" aria-label={`Drehzahlmesser bei ${target} Umdrehungen pro Minute`} style={{maxWidth:size}}>
        <defs>
          <radialGradient id="dial" cx="50%" cy="42%" r="70%">
            <stop offset="0%" stopColor="#333"/><stop offset="70%" stopColor="#1d1d1d"/><stop offset="100%" stopColor="#101010"/>
          </radialGradient>
          <linearGradient id="ndl" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%" stopColor="var(--accent2)"/><stop offset="100%" stopColor="var(--accent)"/>
          </linearGradient>
        </defs>
        {/* dial face */}
        <circle cx={cx} cy={cy} r={R+18} fill="url(#dial)" stroke="#3a3a3a" strokeWidth="2"/>
        {/* outer track arc */}
        <path d={arcPath(cx,cy,R,225,495)} fill="none" stroke="#3a3a3a" strokeWidth="6" strokeLinecap="round"/>
        {/* red zone arc */}
        <path d={arcPath(cx,cy,R,angleFor(RED_FROM),495)} fill="none" stroke="var(--accent)" strokeWidth="6" strokeLinecap="round"/>
        {minors}{majors}{labels}
        {/* needle */}
        <g ref={needleRef} className="needle" transform={`rotate(${animate?angleFor(0):endAngle} ${cx} ${cy})`}>
          <polygon points={`${cx-4},${cy} ${cx+4},${cy} ${cx+2.2},${cy-R+14} ${cx-2.2},${cy-R+14}`} fill="url(#ndl)"/>
          <circle cx={cx} cy={cy-R+16} r="3.5" fill="#fff"/>
        </g>
        <circle cx={cx} cy={cy} r="16" fill="#111" stroke="var(--accent)" strokeWidth="2.5"/>
        <circle cx={cx} cy={cy} r="5" fill="var(--accent)"/>
      </svg>
      <div className="tacho-readout" style={{marginTop:-6}}>
        <div className="tacho-unit">Vollgas</div>
      </div>
    </div>
  );
}

// Horizontal redline bar (hero variant C + reused)
function RedlineBar({ target=7200, animate=true }){
  const [w,setW]=useState(0);
  useEffect(()=>{
    if(!animate){ setW(target/REDLINE*100); return; }
    const id=setTimeout(()=>setW(target/REDLINE*100), 250);
    return ()=>clearTimeout(id);
  },[target,animate]);
  return (
    <div>
      <div className="redline-bar">
        <div className="redline-fill" style={{width:w+'%'}}></div>
        <div className="redline-ticks">{Array.from({length:8}).map((_,i)=><span key={i}></span>)}</div>
      </div>
      <div className="redline-scale">
        <span>0</span><span>2</span><span>4</span><span>6</span><b>8 ·　REDLINE</b>
      </div>
    </div>
  );
}

Object.assign(window, { Tacho, RedlineBar, useCountUp, angleFor });
