// voicebar.jsx — the floating quick-record widget

const { useState: useV, useEffect: useVE, useRef: useVR } = React;

/* ─── VoiceBar component ──────────────────────────────────── */

// state: 'idle' | 'listening' | 'processing' | 'result'
function VoiceBar({ state, onMic, transcript, duration, wpm, modelName, styleName }) {
  return (
    <div className={'vb vb-' + state} role="region" aria-label="VoiceBar">
      {/* Left: status / mic */}
      <div className="vb-left">
        {state === 'idle' && (
          <button className="vb-mic" onClick={onMic} aria-label="Start recording">
            <Icon.Mic style={{width:18, height:18}}/>
          </button>
        )}
        {state === 'listening' && (
          <button className="vb-mic vb-mic-rec" onClick={onMic} aria-label="Stop">
            <span className="vb-pulse"/>
            <span className="vb-stop"/>
          </button>
        )}
        {state === 'processing' && (
          <div className="vb-mic vb-mic-busy" aria-label="Processing">
            <Loader/>
          </div>
        )}
        {state === 'result' && (
          <button className="vb-mic vb-mic-done" onClick={onMic} aria-label="New recording">
            <Icon.Check style={{width:18, height:18}}/>
          </button>
        )}
      </div>

      {/* Middle: content varies by state */}
      <div className="vb-mid">
        {state === 'idle' && (
          <div className="vb-stack">
            <div className="vb-line-1">Tap to record</div>
            <div className="vb-line-2">or hold <kbd>⌥</kbd> <kbd>Space</kbd></div>
          </div>
        )}
        {state === 'listening' && <LiveWaveform/>}
        {state === 'processing' && (
          <div className="vb-stack">
            <div className="vb-line-1">Transcribing<span className="vb-dots"><i/><i/><i/></span></div>
            <div className="vb-line-2">{modelName} · {duration}</div>
          </div>
        )}
        {state === 'result' && (
          <div className="vb-result-text">
            <div className="vb-result-line">{transcript}</div>
          </div>
        )}
      </div>

      {/* Right: meta / actions */}
      <div className="vb-right">
        {state === 'idle' && (
          <>
            <Chip mute>{modelName}</Chip>
            <Chip mute>{styleName}</Chip>
          </>
        )}
        {state === 'listening' && (
          <>
            <Chip rec>REC</Chip>
            <span className="vb-timer mono tnum">{duration}</span>
          </>
        )}
        {state === 'processing' && (
          <button className="vb-btn vb-btn-ghost">Cancel</button>
        )}
        {state === 'result' && (
          <>
            <span className="vb-meta mono tnum">{wpm} wpm · {duration}</span>
            <button className="vb-btn vb-btn-ghost" title="Copy"><Icon.Copy style={{width:14, height:14}}/></button>
            <button className="vb-btn vb-btn-ghost" title="Refine with AI"><Icon.Sparkle style={{width:14, height:14}}/></button>
            <button className="vb-btn vb-btn-accent" title="Insert"><Icon.Check style={{width:14, height:14}}/> Insert</button>
          </>
        )}
      </div>
    </div>
  );
}

function Chip({ children, mute, rec }) {
  return (
    <span className={'vb-chip' + (mute ? ' vb-chip-mute' : '') + (rec ? ' vb-chip-rec' : '')}>
      {rec && <span className="vb-chip-dot"/>}
      {children}
    </span>
  );
}

function Loader() {
  return (
    <svg viewBox="0 0 36 36" style={{width:22, height:22}}>
      <circle cx="18" cy="18" r="14" fill="none" stroke="rgba(255,255,255,0.12)" strokeWidth="3"/>
      <circle cx="18" cy="18" r="14" fill="none" stroke="var(--accent)" strokeWidth="3" strokeLinecap="round"
              strokeDasharray="22 88" transform="rotate(-90 18 18)">
        <animateTransform attributeName="transform" type="rotate" from="0 18 18" to="360 18 18" dur="1.1s" repeatCount="indefinite"/>
      </circle>
    </svg>
  );
}

function LiveWaveform() {
  // Animated bars driven by sin/cos with phase drift — gives organic motion.
  const N = 38;
  const [t, setT] = useV(0);
  useVE(() => {
    let raf, t0 = performance.now();
    const loop = (now) => {
      setT((now - t0) / 1000);
      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, []);
  return (
    <div className="vb-wave">
      {Array.from({length:N}).map((_, i) => {
        const phase = i * 0.34;
        const v = 0.32 + 0.42 * Math.abs(Math.sin(t * 4.2 + phase) * Math.cos(t * 1.6 + phase * 0.7));
        return <span key={i} style={{height: `${v*100}%`}}/>;
      })}
    </div>
  );
}

/* ─── Page (interactive hero + states gallery) ──────────────── */

function VoiceBarPage() {
  const [prefs] = (window.usePrefs ? window.usePrefs() : [{accent:'#dbef6a'}, ()=>{}]);
  const [state, setState] = useV('idle');
  const [duration, setDuration] = useV('00:00');
  const [transcript, setTranscript] = useV(SAMPLE);

  useVE(() => {
    const root = document.documentElement;
    root.style.setProperty('--accent', prefs.accent || '#dbef6a');
    root.style.setProperty('--accent-ink', '#1a1a1a');
  }, [prefs.accent]);

  // Cycle: idle → listening → processing → result → idle
  const onMic = () => {
    if (state === 'idle') setState('listening');
    else if (state === 'listening') setState('processing');
    else if (state === 'result') setState('idle');
  };

  // While listening, advance the timer; while processing, auto-advance
  useVE(() => {
    if (state === 'listening') {
      let s = 0;
      setDuration('00:00');
      const id = setInterval(() => {
        s += 1;
        setDuration(`00:${String(s).padStart(2,'0')}`);
      }, 1000);
      return () => clearInterval(id);
    }
    if (state === 'processing') {
      const id = setTimeout(() => setState('result'), 1700);
      return () => clearTimeout(id);
    }
  }, [state]);

  return (
    <div className="vb-page">
      {/* faux desktop backdrop hint */}
      <div className="vb-desktop"/>

      <div className="vb-hero">
        <div className="vb-eyebrow">VoiceBar</div>
        <h1 className="vb-title">The bar that <em>follows you</em>.</h1>
        <p className="vb-sub">
          A floating quick-record shortcut that lives in the background, ready to activate. Tap once for hands-free dictation, anywhere on the system — even when OpenDicta isn't open.
        </p>

        {/* Interactive hero bar */}
        <div className="vb-stage" data-state={state}>
          <VoiceBar
            state={state}
            onMic={onMic}
            transcript={transcript}
            duration={state === 'listening' ? duration : state === 'processing' ? '00:14' : '00:14'}
            wpm="156"
            modelName="Whisper Pro"
            styleName="Fix grammar"
          />
        </div>

        <div className="vb-hint">
          {state === 'idle'       && <>Click the mic to start a recording →</>}
          {state === 'listening'  && <>Click the stop button to finish →</>}
          {state === 'processing' && <>Transcribing… in a moment you'll see the result.</>}
          {state === 'result'     && <>Click the check to reset and try again.</>}
        </div>
      </div>

      {/* ─── All states gallery ─── */}
      <div className="vb-gallery">
        <div className="vb-gallery-head">
          <div>
            <div className="vb-eyebrow" style={{margin:0}}>All states</div>
            <h2 className="vb-h2">Every shape it takes.</h2>
          </div>
        </div>

        <StateRow
          label="Idle"
          caption="Resting state. Shows current model + style and the recording shortcut. Sits unobtrusively at the bottom of any screen."
        >
          <VoiceBar state="idle" onMic={()=>{}} duration="00:00" wpm="" transcript="" modelName="Whisper Pro" styleName="Fix grammar"/>
        </StateRow>

        <StateRow
          label="Listening"
          caption="Live waveform reacts to your voice. Timer counts up. Tap the chartreuse stop button — or release ⌥ Space — when done."
        >
          <VoiceBar state="listening" onMic={()=>{}} duration="00:14" wpm="" transcript="" modelName="Whisper Pro" styleName="Fix grammar"/>
        </StateRow>

        <StateRow
          label="Processing"
          caption="Local model decoding. Usually under a second for Parakeet, longer for Studio. Cancel discards and returns to idle."
        >
          <VoiceBar state="processing" onMic={()=>{}} duration="00:14" wpm="" transcript="" modelName="Whisper Pro" styleName="Fix grammar"/>
        </StateRow>

        <StateRow
          label="Result"
          caption="Transcript preview with insertion + refinement actions. Auto-dismisses after 8 seconds if you don't touch it."
        >
          <VoiceBar state="result" onMic={()=>{}} duration="00:14" wpm="156" transcript={SAMPLE} modelName="Whisper Pro" styleName="Fix grammar"/>
        </StateRow>
      </div>

      {/* Anatomy */}
      <div className="vb-gallery">
        <div className="vb-gallery-head">
          <div>
            <div className="vb-eyebrow" style={{margin:0}}>Anatomy</div>
            <h2 className="vb-h2">How it's built.</h2>
          </div>
        </div>

        <div className="vb-anatomy">
          <VoiceBar state="result" onMic={()=>{}} duration="00:14" wpm="156" transcript={SAMPLE} modelName="Whisper Pro" styleName="Fix grammar"/>
          <div className="vb-anno vb-anno-1">
            <span>State indicator · ↺ rotates through idle, listening, processing, done</span>
          </div>
          <div className="vb-anno vb-anno-2">
            <span>Content slot · waveform, transcript, or call-to-action depending on state</span>
          </div>
          <div className="vb-anno vb-anno-3">
            <span>Action cluster · inline buttons for the most likely next move</span>
          </div>
        </div>
      </div>

      <div className="vb-foot">
        <div className="vb-foot-text">
          <div style={{fontSize:13, fontWeight:600, color:'var(--ink-1)'}}>Want it on your desktop?</div>
          <div style={{fontSize:12, color:'var(--ink-3)'}}>The VoiceBar is part of the macOS app. Set the shortcut on the Settings page of OpenDicta.</div>
        </div>
        <a href="OpenDicta.html" className="btn btn-sm">← Back to app</a>
      </div>
    </div>
  );
}

const SAMPLE = "Reminder to follow up with Mark about the latency thing, and send design review notes before tomorrow's standup.";

function StateRow({ label, caption, children }) {
  return (
    <div className="vb-row">
      <div className="vb-row-meta">
        <div className="vb-row-label">{label}</div>
        <div className="vb-row-caption">{caption}</div>
      </div>
      <div className="vb-row-bar">{children}</div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<VoiceBarPage/>);
