import React, { useState, useRef, useEffect } from 'react';
import { PipelineTrace } from '../components/ui/index';

interface Props { aiStatus: any; }
interface Msg { id: string; role: 'user' | 'assistant' | 'system'; text: string; pipeline?: any[]; actions?: any[]; ts: Date; }

const SUGGESTIONS = ['What is my balance?', 'Send 5 SOL to alice.sol', 'Show recent transactions', 'Help me understand gas fees'];

export default function VoicePage({ aiStatus }: Props) {
  const [msgs, setMsgs] = useState<Msg[]>([
    { id: '0', role: 'assistant', text: "I'm your SolVox AI assistant — running 100% locally via 6 QVAC modules. Ask me to send tokens, check balances, search transactions, or explain anything about Solana.", pipeline: [], actions: [], ts: new Date() },
  ]);
  const [input, setInput] = useState('');
  const [recording, setRecording] = useState(false);
  const [processing, setProcessing] = useState(false);
  const [wave, setWave] = useState<number[]>(new Array(40).fill(1));
  const recRef = useRef<MediaRecorder | null>(null);
  const chunks = useRef<Blob[]>([]);
  const endRef = useRef<HTMLDivElement>(null);
  const analyser = useRef<AnalyserNode | null>(null);
  const raf = useRef<number | null>(null);

  useEffect(() => { endRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [msgs]);

  const startRec = async () => {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: { sampleRate: 16000, channelCount: 1, echoCancellation: true, noiseSuppression: true } });
      const ctx = new AudioContext(); const src = ctx.createMediaStreamSource(stream); const a = ctx.createAnalyser(); a.fftSize = 128; src.connect(a); analyser.current = a;
      const tick = () => { if (!analyser.current) return; const d = new Uint8Array(analyser.current.frequencyBinCount); analyser.current.getByteFrequencyData(d); setWave(Array.from(d).slice(0, 40).map(v => Math.max(1, v / 8))); raf.current = requestAnimationFrame(tick); }; tick();
      const rec = new MediaRecorder(stream, { mimeType: 'audio/webm' }); chunks.current = [];
      rec.ondataavailable = e => { if (e.data.size > 0) chunks.current.push(e.data); };
      rec.onstop = async () => { stream.getTracks().forEach(t => t.stop()); if (raf.current) cancelAnimationFrame(raf.current); setWave(new Array(40).fill(1)); const b = new Blob(chunks.current, { type: 'audio/webm' }); processVoice(await b.arrayBuffer()); };
      recRef.current = rec; rec.start(); setRecording(true);
    } catch { add('system', 'Microphone access denied.'); }
  };

  const stopRec = () => { if (recRef.current && recording) { recRef.current.stop(); setRecording(false); } };

  const processVoice = async (data: ArrayBuffer) => {
    setProcessing(true);
    try {
      if (window.solvox) {
        const r = await window.solvox.ai.processVoice(data);
        if (r.success) {
          add('user', r.transcription || '[voice]');
          add('assistant', r.agentResult?.response || 'Done.', r.pipelineSteps, r.agentResult?.actions);
          if (r.responseAudio) { const u = URL.createObjectURL(new Blob([r.responseAudio], { type: 'audio/wav' })); new Audio(u).play().catch(() => {}); }
        } else add('system', r.error || 'Voice processing failed');
      } else { add('user', '[voice — dev]'); add('assistant', 'QVAC models needed. Type commands instead.'); }
    } catch (e: any) { add('system', e.message); }
    setProcessing(false);
  };

  const handleSend = async () => {
    if (!input.trim()) return; const text = input.trim(); setInput(''); add('user', text); setProcessing(true);
    try {
      if (window.solvox) {
        const r = await window.solvox.ai.chat(text);
        if (r.success) add('assistant', r.response || '', r.pipelineSteps, r.actions);
        else add('assistant', r.error || 'Could not process.');
      } else add('assistant', `[Dev] "${text}" — needs QVAC models.`);
    } catch (e: any) { add('system', e.message); }
    setProcessing(false);
  };

  const add = (role: Msg['role'], text: string, pipeline?: any[], actions?: any[]) => {
    setMsgs(p => [...p, { id: Date.now().toString(36), role, text, pipeline, actions, ts: new Date() }]);
  };

  const mods = aiStatus ? [aiStatus.llm, aiStatus.transcription, aiStatus.tts, aiStatus.embed, aiStatus.translation, aiStatus.ocr].filter(Boolean).length : 0;

  return (
    <div className="flex flex-col h-full max-w-content mx-auto px-8 py-6">
      {/* Header */}
      <div className="flex items-center justify-between mb-4">
        <div>
          <h2 className="text-title-lg display-text text-ink">Voice AI Assistant</h2>
          <p className="text-body-sm text-body">Powered by 6 QVAC packages · All inference local</p>
        </div>
        <span className={`badge-pill ${mods >= 4 ? 'badge-pill-green' : mods > 0 ? 'badge-pill-blue' : ''}`}>
          {mods >= 4 ? 'AI ONLINE' : mods > 0 ? 'PARTIAL' : 'LOADING'}
        </span>
      </div>

      {/* Chat */}
      <div className="flex-1 overflow-y-auto card mb-4 space-y-4" style={{ padding: '24px' }}>
        {msgs.map(m => (
          <div key={m.id} className={`flex ${m.role === 'user' ? 'justify-end' : 'justify-start'} page-enter`}>
            <div className={`max-w-[75%] ${
              m.role === 'user' ? 'bg-primary text-on-primary rounded-xl rounded-br-sm px-4 py-3' :
              m.role === 'system' ? 'bg-surface-soft text-muted border border-hairline rounded-xl px-4 py-3' :
              'bg-surface-soft text-ink rounded-xl rounded-bl-sm px-4 py-3'
            }`}>
              {m.role === 'assistant' && <div className="text-caption-strong text-primary mb-1">SolVox AI</div>}
              <p className="text-body-sm whitespace-pre-wrap">{m.text}</p>
              {m.actions && m.actions.length > 0 && (
                <div className="flex flex-wrap gap-1 mt-2">
                  {m.actions.map((a: any, i: number) => (
                    <span key={i} className="badge-pill-blue badge-pill text-[10px]">{a.tool}</span>
                  ))}
                </div>
              )}
              {m.pipeline && m.pipeline.length > 0 && <PipelineTrace steps={m.pipeline} />}
              <div className="text-caption text-muted-soft mt-1.5">{m.ts.toLocaleTimeString()}</div>
            </div>
          </div>
        ))}
        {processing && (
          <div className="flex justify-start">
            <div className="bg-surface-soft rounded-xl px-4 py-3 flex items-center gap-2">
              <div className="w-2 h-2 rounded-full bg-primary animate-pulse" />
              <span className="text-body-sm text-muted">Processing locally…</span>
            </div>
          </div>
        )}
        <div ref={endRef} />
      </div>

      {/* Suggestions */}
      {msgs.length <= 2 && !recording && (
        <div className="flex flex-wrap gap-2 mb-3">
          {SUGGESTIONS.map(s => (
            <button key={s} onClick={() => setInput(s)} className="btn-secondary text-body-sm py-1.5 px-3">{s}</button>
          ))}
        </div>
      )}

      {/* Waveform */}
      {recording && (
        <div className="bg-surface-soft rounded-xl p-3 mb-3 flex items-center justify-center gap-px h-12">
          {wave.map((h, i) => (
            <div key={i} className="w-[3px] rounded-full bg-primary transition-all duration-75" style={{ height: `${h}px`, opacity: 0.3 + h / 40 }} />
          ))}
        </div>
      )}

      {/* Input */}
      <div className="flex items-center gap-3">
        <button onMouseDown={startRec} onMouseUp={stopRec} onMouseLeave={stopRec} onTouchStart={startRec} onTouchEnd={stopRec} disabled={processing}
          className={`w-11 h-11 rounded-pill flex items-center justify-center transition-colors ${recording ? 'bg-semantic-down' : 'bg-primary'} disabled:opacity-40`}>
          <svg width="18" height="18" viewBox="0 0 24 24" fill="white">
            {recording ? <rect x="6" y="6" width="12" height="12" rx="2" /> : <><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round"/><line x1="12" y1="19" x2="12" y2="23" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round"/></>}
          </svg>
        </button>
        <div className="flex-1 relative">
          <input value={input} onChange={e => setInput(e.target.value)} onKeyDown={e => e.key === 'Enter' && handleSend()}
            placeholder={recording ? 'Listening…' : 'Type a command or hold mic…'} className="input-field pr-20" disabled={processing || recording} />
          <button onClick={handleSend} disabled={!input.trim() || processing} className="absolute right-1.5 top-1/2 -translate-y-1/2 btn-text text-body-sm disabled:opacity-20">Send</button>
        </div>
      </div>
    </div>
  );
}
