/* AudioEffectsShowcase.jsx — 5-band EQ + compressor/reverb showcase */
(function () {
  'use strict';

  const ADS = {
    bg:'#0f0f0f', panel:'#1a1a1a', surface:'#252525',
    border:'#2e2e2e', border2:'#333333',
    text:'#f5f5f5', dim:'#999999', muted:'#666666',
    accent:'#00FF00',
  };

  const EQ_BANDS = [
    { id:'sub',  label:'Sub',  freq:'60 Hz',   min:-12, max:12 },
    { id:'low',  label:'Low',  freq:'250 Hz',  min:-12, max:12 },
    { id:'mid',  label:'Mid',  freq:'1 kHz',   min:-12, max:12 },
    { id:'hi',   label:'Hi',   freq:'4 kHz',   min:-12, max:12 },
    { id:'air',  label:'Air',  freq:'16 kHz',  min:-12, max:12 },
  ];

  const EQ_PRESETS = [
    { name:'Flat',       vals:[0,0,0,0,0] },
    { name:'Bass Boost', vals:[8,5,0,-2,-1] },
    { name:'Vocal',      vals:[-2,-1,4,3,2] },
    { name:'Podcast',    vals:[2,0,3,2,1] },
    { name:'Cinematic',  vals:[3,2,-1,1,3] },
    { name:'Rock',       vals:[4,3,1,2,3] },
  ];

  const CSS = `
    @keyframes aeq-bar { 0%,100%{height:40%} 50%{height:85%} }
    @keyframes aeq-bar2 { 0%,100%{height:55%} 50%{height:20%} }
    @keyframes aeq-bar3 { 0%,100%{height:65%} 40%{height:25%} }
    @keyframes aeq-bar4 { 0%,100%{height:30%} 60%{height:70%} }
    .aeq-b:hover { border-color:rgba(0,255,0,0.4) !important; color:#f5f5f5 !important; }
    .aeq-b.active { border-color:rgba(0,255,0,0.6) !important; color:#00FF00 !important; background:#1f261f !important; }
  `;

  function EqCanvas({ gains }) {
    const canvasRef = React.useRef(null);

    React.useEffect(() => {
      const c = canvasRef.current;
      if (!c) return;
      const ctx = c.getContext('2d');
      const W = c.width, H = c.height;
      ctx.clearRect(0, 0, W, H);

      // Grid
      ctx.strokeStyle = '#1e1e1e'; ctx.lineWidth = 1;
      for (let i = 1; i < 4; i++) {
        const y = (i / 4) * H;
        ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(W, y); ctx.stroke();
      }
      for (let i = 1; i < 5; i++) {
        const x = (i / 5) * W;
        ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, H); ctx.stroke();
      }
      // Zero line
      ctx.strokeStyle = '#2e2e2e'; ctx.lineWidth = 1.5;
      ctx.beginPath(); ctx.moveTo(0, H/2); ctx.lineTo(W, H/2); ctx.stroke();

      // EQ curve — catmull-rom through 5 band points + two anchor endpoints
      const pts = [];
      const bandXs = [0.1, 0.25, 0.5, 0.72, 0.9];
      for (let i = 0; i < 5; i++) {
        const x = bandXs[i] * W;
        const norm = gains[i] / 12; // -1 to +1
        const y = H/2 - norm * (H/2 - 10);
        pts.push([x, y]);
      }
      // Add anchors
      const all = [[0, pts[0][1]], ...pts, [W, pts[pts.length-1][1]]];

      ctx.beginPath();
      ctx.moveTo(all[0][0], all[0][1]);
      for (let i = 1; i < all.length - 1; i++) {
        const p0 = all[Math.max(0, i-1)];
        const p1 = all[i];
        const p2 = all[Math.min(all.length-1, i+1)];
        const p3 = all[Math.min(all.length-1, i+2)];
        const cp1x = p1[0] + (p2[0] - p0[0]) / 6;
        const cp1y = p1[1] + (p2[1] - p0[1]) / 6;
        const cp2x = p2[0] - (p3[0] - p1[0]) / 6;
        const cp2y = p2[1] - (p3[1] - p1[1]) / 6;
        ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, p2[0], p2[1]);
      }

      // Fill below
      ctx.lineTo(W, H); ctx.lineTo(0, H); ctx.closePath();
      const grd = ctx.createLinearGradient(0, 0, 0, H);
      grd.addColorStop(0, 'rgba(0,255,0,0.22)');
      grd.addColorStop(1, 'rgba(0,255,0,0.02)');
      ctx.fillStyle = grd;
      ctx.fill();

      // Curve line
      ctx.beginPath();
      ctx.moveTo(all[0][0], all[0][1]);
      for (let i = 1; i < all.length - 1; i++) {
        const p0 = all[Math.max(0, i-1)];
        const p1 = all[i];
        const p2 = all[Math.min(all.length-1, i+1)];
        const p3 = all[Math.min(all.length-1, i+2)];
        const cp1x = p1[0] + (p2[0] - p0[0]) / 6;
        const cp1y = p1[1] + (p2[1] - p0[1]) / 6;
        const cp2x = p2[0] - (p3[0] - p1[0]) / 6;
        const cp2y = p2[1] - (p3[1] - p1[1]) / 6;
        ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, p2[0], p2[1]);
      }
      ctx.strokeStyle = '#00FF00'; ctx.lineWidth = 2; ctx.stroke();

      // Control points
      for (let i = 0; i < pts.length; i++) {
        const [x, y] = pts[i];
        ctx.beginPath(); ctx.arc(x, y, 5, 0, Math.PI*2);
        ctx.fillStyle = '#00FF00'; ctx.fill();
        ctx.strokeStyle = '#000'; ctx.lineWidth = 1.5; ctx.stroke();
      }
    }, [gains]);

    return <canvas ref={canvasRef} width={440} height={110} style={{ display:'block', width:'100%', height:110 }}/>;
  }

  function BandSlider({ band, gain, onGain, userDid, onInteract }) {
    const pct = ((gain + 12) / 24) * 100;
    return (
      <div style={{ flex:1, display:'flex', flexDirection:'column', alignItems:'center', gap:4, padding:'0 4px' }}>
        <div style={{ fontSize:10, color: Math.abs(gain) > 0.5 ? ADS.accent : ADS.muted, fontWeight: Math.abs(gain)>0.5 ? 700 : 400 }}>
          {gain >= 0 ? '+' : ''}{gain.toFixed(1)}
        </div>
        {/* Vertical fader track */}
        <div style={{ position:'relative', width:24, height:90, display:'flex', alignItems:'center', justifyContent:'center' }}
          onPointerDown={e => {
            onInteract();
            e.currentTarget.setPointerCapture(e.pointerId);
            const rect = e.currentTarget.getBoundingClientRect();
            const onMove = me => {
              const rel = 1 - (me.clientY - rect.top) / rect.height;
              const db = Math.round((rel * 24 - 12) * 2) / 2;
              onGain(Math.max(-12, Math.min(12, db)));
            };
            onMove(e);
            const onUp = () => {
              e.currentTarget.removeEventListener('pointermove', onMove);
              e.currentTarget.removeEventListener('pointerup', onUp);
            };
            e.currentTarget.addEventListener('pointermove', onMove);
            e.currentTarget.addEventListener('pointerup', onUp);
          }}>
          <div style={{ position:'absolute', width:3, height:'100%', background:'#2a2a2a', borderRadius:2 }}/>
          {/* Zero marker */}
          <div style={{ position:'absolute', width:10, height:1, background:'#444', top:'50%' }}/>
          {/* Thumb */}
          <div style={{ position:'absolute', bottom: `${pct}%`, left:'50%', transform:'translate(-50%, 50%)', width:16, height:8, background:ADS.accent, borderRadius:2, cursor:'ns-resize', boxShadow:`0 0 6px rgba(0,255,0,0.5)` }}/>
        </div>
        <div style={{ fontSize:9, color:ADS.muted, textAlign:'center' }}>{band.label}</div>
        <div style={{ fontSize:8, color:'#555' }}>{band.freq}</div>
      </div>
    );
  }

  function AccordionRow({ title, children, defaultOpen = false }) {
    const [open, setOpen] = React.useState(defaultOpen);
    return (
      <div style={{ borderTop:`1px solid ${ADS.border}` }}>
        <div onClick={() => setOpen(o => !o)}
          style={{ padding:'9px 14px', display:'flex', alignItems:'center', justifyContent:'space-between', cursor:'pointer', userSelect:'none' }}>
          <span style={{ fontSize:11, color:ADS.text, fontWeight:600 }}>{title}</span>
          <span style={{ fontSize:11, color:ADS.muted, transition:'transform 0.2s', transform: open ? 'rotate(180deg)' : 'none' }}>▾</span>
        </div>
        <div style={{ maxHeight: open ? 200 : 0, overflow:'hidden', transition:'max-height 0.25s ease' }}>
          <div style={{ padding:'4px 14px 12px' }}>
            {children}
          </div>
        </div>
      </div>
    );
  }

  function KnobSvg({ value, label, min=0, max=100, color='#00FF00', size=46, onChange }) {
    const pct = (value - min) / (max - min);
    const startAngle = 210 * (Math.PI/180);
    const totalSweep = 300 * (Math.PI/180);
    const angle = startAngle + pct * totalSweep;
    const cx = size/2, cy = size/2, r = size/2 - 4;
    const trackStart = { x: cx + r*Math.cos(startAngle), y: cy + r*Math.sin(startAngle) };
    const trackEnd   = { x: cx + r*Math.cos(startAngle + totalSweep), y: cy + r*Math.sin(startAngle + totalSweep) };
    const arcEnd     = { x: cx + r*Math.cos(angle), y: cy + r*Math.sin(angle) };
    const largeArc = pct * totalSweep > Math.PI ? 1 : 0;
    const dotR = (r-6);
    const dotX = cx + dotR * Math.cos(angle);
    const dotY = cy + dotR * Math.sin(angle);

    return (
      <div style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:3 }}>
        <svg width={size} height={size} style={{ cursor:'ns-resize', userSelect:'none' }}
          onPointerDown={e => {
            if (onChange) {
              e.currentTarget.setPointerCapture(e.pointerId);
              const startY = e.clientY;
              const startVal = value;
              const onM = me => { const dy = startY - me.clientY; const nv = Math.round(Math.max(min, Math.min(max, startVal + dy * (max-min)/80))); onChange(nv); };
              const onU = () => { e.currentTarget.removeEventListener('pointermove', onM); e.currentTarget.removeEventListener('pointerup', onU); };
              e.currentTarget.addEventListener('pointermove', onM);
              e.currentTarget.addEventListener('pointerup', onU);
            }
          }}>
          {/* Track */}
          <path d={`M ${trackStart.x} ${trackStart.y} A ${r} ${r} 0 1 1 ${trackEnd.x} ${trackEnd.y}`} fill="none" stroke="#2a2a2a" strokeWidth="3" strokeLinecap="round"/>
          {/* Value arc */}
          {pct > 0.01 && <path d={`M ${trackStart.x} ${trackStart.y} A ${r} ${r} 0 ${largeArc} 1 ${arcEnd.x} ${arcEnd.y}`} fill="none" stroke={color} strokeWidth="3" strokeLinecap="round"/>}
          {/* Center circle */}
          <circle cx={cx} cy={cy} r={r-6} fill="#1e1e1e" stroke="#333" strokeWidth="1"/>
          {/* Indicator dot */}
          <circle cx={dotX} cy={dotY} r={1.8} fill={color}/>
        </svg>
        <span style={{ fontSize:9, color:ADS.muted }}>{label}</span>
        <span style={{ fontSize:9, color: value !== Math.round((max+min)/2) ? color : ADS.muted }}>{value}%</span>
      </div>
    );
  }

  function AudioEffectsShowcase({ scale = 1, style = {}, className = '' }) {
    const [gains, setGains]       = React.useState([0, 0, 0, 0, 0]);
    const [preset, setPreset]     = React.useState(null);
    const [comp, setComp]         = React.useState({ threshold:40, ratio:40, attack:20, release:60 });
    const [reverb, setReverb]     = React.useState({ mix:25, decay:40, predelay:15 });
    const [userDid, setUserDid]   = React.useState(false);
    const [toast, setToast]       = React.useState(null);

    const interact = () => setUserDid(true);

    const applyPreset = (p, i) => {
      interact();
      setPreset(i);
      setGains([...p.vals]);
      setToast(`Preset "${p.name}" applied`);
      setTimeout(() => setToast(null), 2000);
    };

    const setGain = (idx, val) => { interact(); setGains(gs => gs.map((g,i) => i===idx ? val : g)); setPreset(null); };

    return (
      <div onMouseDown={interact} className={className}
        style={{
          width:480, background:ADS.bg, border:`1px solid ${ADS.border}`,
          borderRadius:8, overflow:'hidden',
          fontFamily:"'Inter',-apple-system,sans-serif", position:'relative',
          transform: scale !== 1 ? `scale(${scale})` : undefined,
          transformOrigin:'top left',
          ...style,
        }}>
        <style>{CSS}</style>

        {/* ── Header ── */}
        <div style={{ height:36, background:'#111', borderBottom:`1px solid ${ADS.border}`, display:'flex', alignItems:'center', padding:'0 14px', gap:10 }}>
          <span style={{ fontSize:11, fontWeight:700, color:ADS.text, letterSpacing:2, textTransform:'uppercase' }}>Audio Effects</span>
          <div style={{ flex:1 }}/>
          {/* Mini VU meters */}
          <div style={{ display:'flex', gap:2, alignItems:'flex-end', height:20 }}>
            {[0,1,2,3,4,5,6,7].map(i => (
              <div key={i} style={{ width:3, background:ADS.border, borderRadius:1, height:20, position:'relative', overflow:'hidden' }}>
                <div style={{ position:'absolute', bottom:0, width:'100%', borderRadius:1,
                  background:`linear-gradient(to top, ${ADS.accent}, #88ff44, #ffdd00)`,
                  animation:`aeq-bar${(i%4)+1} ${0.6+i*0.09}s ease-in-out infinite`,
                  animationDelay:`${i*0.07}s` }}/>
              </div>
            ))}
          </div>
        </div>

        {/* ── EQ Curve canvas ── */}
        <div style={{ background:'#0d0d0d', borderBottom:`1px solid ${ADS.border}`, padding:'10px 14px 8px' }}>
          <div style={{ fontSize:10, color:ADS.muted, letterSpacing:1, textTransform:'uppercase', marginBottom:6 }}>Equalizer</div>
          <EqCanvas gains={gains}/>
        </div>

        {/* ── Band sliders ── */}
        <div style={{ background:'#111', borderBottom:`1px solid ${ADS.border}`, padding:'8px 10px' }}>
          <div style={{ display:'flex', gap:0 }}>
            {EQ_BANDS.map((b, i) => (
              <BandSlider key={b.id} band={b} gain={gains[i]}
                onGain={val => setGain(i, val)}
                onInteract={interact} userDid={userDid}/>
            ))}
          </div>
        </div>

        {/* ── Presets ── */}
        <div style={{ background:'#0f0f0f', borderBottom:`1px solid ${ADS.border}`, padding:'8px 14px', display:'flex', gap:5, flexWrap:'wrap' }}>
          <span style={{ fontSize:10, color:ADS.muted, alignSelf:'center', marginRight:4 }}>Presets:</span>
          {EQ_PRESETS.map((p, i) => (
            <button key={p.name} className={`aeq-b${preset===i?' active':''}`}
              onClick={() => applyPreset(p, i)}
              style={{ background:'transparent', border:`1px solid ${ADS.border}`, color:ADS.muted, borderRadius:3, padding:'3px 9px', fontSize:10, cursor:'pointer', fontFamily:'inherit', transition:'all 0.1s' }}>
              {p.name}
            </button>
          ))}
        </div>

        {/* ── Compressor accordion ── */}
        <AccordionRow title="Compressor" defaultOpen={true}>
          <div style={{ display:'flex', gap:12, justifyContent:'center', paddingTop:8 }}>
            {[
              { key:'threshold', label:'Threshold', min:0, max:100 },
              { key:'ratio',     label:'Ratio',     min:0, max:100 },
              { key:'attack',    label:'Attack',    min:0, max:100 },
              { key:'release',   label:'Release',   min:0, max:100 },
            ].map(k => (
              <KnobSvg key={k.key} value={comp[k.key]} label={k.label} min={k.min} max={k.max}
                color="#00bbff"
                onChange={v => { interact(); setComp(c => ({...c, [k.key]: v})); }}/>
            ))}
          </div>
        </AccordionRow>

        {/* ── Reverb accordion ── */}
        <AccordionRow title="Reverb / Space" defaultOpen={false}>
          <div style={{ display:'flex', gap:12, justifyContent:'center', paddingTop:8 }}>
            {[
              { key:'mix',      label:'Mix',      min:0, max:100 },
              { key:'decay',    label:'Decay',    min:0, max:100 },
              { key:'predelay', label:'Pre-Delay', min:0, max:100 },
            ].map(k => (
              <KnobSvg key={k.key} value={reverb[k.key]} label={k.label} min={k.min} max={k.max}
                color="#cc88ff"
                onChange={v => { interact(); setReverb(r => ({...r, [k.key]: v})); }}/>
            ))}
          </div>
        </AccordionRow>

        {/* Toast */}
        {toast && (
          <div style={{ position:'absolute', bottom:12, left:'50%', transform:'translateX(-50%)', background:ADS.accent, color:'#000', padding:'6px 14px', borderRadius:6, fontSize:11, fontWeight:700, whiteSpace:'nowrap', zIndex:20, boxShadow:'0 0 14px rgba(0,255,0,0.4)', pointerEvents:'none' }}>
            {toast}
          </div>
        )}
      </div>
    );
  }

  window.AudioEffectsShowcase = AudioEffectsShowcase;
})();
