// CallDemo — ElevenLabs-style interactive voice demo for Voco.
// User taps "Call Sarah" → simulated mid-call with live transcript.
// Sarah's lines are generated by window.claude and spoken via speechSynthesis.
// User speaks back via webkitSpeechRecognition (or types).

const { useState, useEffect, useRef, useCallback } = React;

// ── SVG icons ─────────────────────────────────────
const PhoneIcon = ({ s = 24 }) => (
  <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
    <path d="M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07 19.5 19.5 0 01-6-6 19.79 19.79 0 01-3.07-8.67A2 2 0 014.11 2h3a2 2 0 012 1.72 12.84 12.84 0 00.7 2.81 2 2 0 01-.45 2.11L8.09 9.91a16 16 0 006 6l1.27-1.27a2 2 0 012.11-.45 12.84 12.84 0 002.81.7A2 2 0 0122 16.92z"/>
  </svg>
);
const MicIcon = ({ s = 20 }) => (
  <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
    <rect x="9" y="2" width="6" height="12" rx="3"/>
    <path d="M5 10a7 7 0 0014 0"/>
    <line x1="12" y1="19" x2="12" y2="22"/>
  </svg>
);
const EndCallIcon = ({ s = 18 }) => (
  <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round">
    <path d="M2 12.5a11 11 0 0120 0 2 2 0 01-1 1.7l-2.5 1.3a2 2 0 01-2.3-.3l-1.8-1.5a2 2 0 00-2.8 0l-1.8 1.5a2 2 0 01-2.3.3L3 14.2a2 2 0 01-1-1.7z" transform="rotate(135 12 12)"/>
  </svg>
);

// ── Waveform ──────────────────────────────────────
const Waveform = ({ active, amp = 1 }) => {
  const [t, setT] = useState(0);
  useEffect(() => {
    let raf; const loop = () => { setT(Date.now()); raf = requestAnimationFrame(loop); };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, []);
  const bars = 48;
  return (
    <div className="wave">
      {Array.from({ length: bars }).map((_, i) => {
        const phase = (t / 180) + i * 0.38;
        const base = 3;
        const h = active
          ? base + Math.abs(Math.sin(phase)) * 28 * amp + Math.abs(Math.sin(phase * 0.7)) * 6 * amp
          : base + Math.abs(Math.sin(i * 0.6)) * 2.5;
        return <span key={i} style={{ height: `${h}px`, opacity: active ? 1 : 0.35 }} />;
      })}
    </div>
  );
};

// ── Scripted Sarah lines (fallback if claude.complete fails) ──
const SARAH_OPENER = "Hi, this is Sarah, an AI assistant calling on behalf of your agency. This call may be recorded for quality purposes. Is now a good time for a quick two-minute chat?";
const SARAH_PURPOSE = "Great. I'm following up because you requested an auto insurance quote a few months back through SmartFinancial, and I don't think anyone at our agency had a chance to fully connect with you. Are you still looking at your coverage?";
const SARAH_BOOK = "Your agent is shopping multiple carriers right now and can pull fresh numbers. Let me get you 15 minutes on their calendar — does Thursday work?";
const SARAH_CONFIRM = "Perfect. Morning or afternoon?";
const SARAH_CLOSE = "You're all set for Thursday afternoon. You'll get a confirmation email shortly. Thanks so much — have a great day.";

const scriptedReply = (turn) => {
  if (turn === 0) return SARAH_OPENER;
  if (turn === 1) return SARAH_PURPOSE;
  if (turn === 2) return SARAH_BOOK;
  if (turn === 3) return SARAH_CONFIRM;
  return SARAH_CLOSE;
};

// ── Main component ────────────────────────────────
const CallDemo = () => {
  const [state, setState] = useState("idle"); // idle | connecting | live | ended
  const [transcript, setTranscript] = useState([]); // {who:'sarah'|'you', text, t}
  const [elapsed, setElapsed] = useState(0);
  const [sarahSpeaking, setSarahSpeaking] = useState(false);
  const [userInput, setUserInput] = useState("");
  const [userListening, setUserListening] = useState(false);
  const turnRef = useRef(0);
  const tBodyRef = useRef(null);
  const recRef = useRef(null);
  const timerRef = useRef(null);

  // Elapsed timer
  useEffect(() => {
    if (state !== "live") return;
    timerRef.current = setInterval(() => setElapsed(e => e + 1), 1000);
    return () => clearInterval(timerRef.current);
  }, [state]);

  // Auto-scroll transcript
  useEffect(() => {
    if (tBodyRef.current) tBodyRef.current.scrollTop = tBodyRef.current.scrollHeight;
  }, [transcript]);

  const speak = useCallback((text) => {
    return new Promise((resolve) => {
      setSarahSpeaking(true);
      try {
        const synth = window.speechSynthesis;
        if (!synth) { setTimeout(() => { setSarahSpeaking(false); resolve(); }, Math.max(1500, text.length * 50)); return; }
        synth.cancel();
        const u = new SpeechSynthesisUtterance(text);
        u.rate = 1.02; u.pitch = 1.05; u.volume = 0.9;
        const voices = synth.getVoices();
        const preferred = voices.find(v => /samantha|victoria|karen|susan|zira|female/i.test(v.name)) || voices.find(v => v.lang.startsWith("en"));
        if (preferred) u.voice = preferred;
        u.onend = () => { setSarahSpeaking(false); resolve(); };
        u.onerror = () => { setSarahSpeaking(false); resolve(); };
        synth.speak(u);
      } catch (e) {
        setTimeout(() => { setSarahSpeaking(false); resolve(); }, 2000);
      }
    });
  }, []);

  const addLine = useCallback((who, text) => {
    setTranscript(prev => [...prev, { who, text, t: Date.now() }]);
  }, []);

  const sarahSays = useCallback(async (text) => {
    addLine("sarah", text);
    await speak(text);
  }, [addLine, speak]);

  const startCall = useCallback(async () => {
    setState("connecting");
    setTranscript([]); setElapsed(0); turnRef.current = 0;
    // Connecting shimmer
    await new Promise(r => setTimeout(r, 1500));
    setState("live");
    await new Promise(r => setTimeout(r, 400));
    await sarahSays(SARAH_OPENER);
  }, [sarahSays]);

  const endCall = useCallback(() => {
    try { window.speechSynthesis.cancel(); } catch (e) {}
    try { recRef.current && recRef.current.stop(); } catch (e) {}
    setState("ended");
    setSarahSpeaking(false);
    setUserListening(false);
  }, []);

  const resetCall = useCallback(() => {
    setState("idle"); setTranscript([]); setElapsed(0);
  }, []);

  // Handle user reply → get Sarah's next line
  const handleUserReply = useCallback(async (text) => {
    if (!text.trim()) return;
    addLine("you", text);
    setUserInput("");
    turnRef.current += 1;

    // Try to use claude for a more natural response; fall back to script
    let reply = scriptedReply(turnRef.current);
    try {
      if (window.claude && window.claude.complete) {
        const sys = "You are Sarah, a bilingual AI voice assistant calling a lead who previously requested an insurance quote (via SmartFinancial, EverQuote, QuoteWizard, etc.) on behalf of an independent P&C agency. Your goal is to book a 15-minute quote appointment with a licensed agent. If the user responds in Spanish, switch to Spanish for the rest of the conversation. Be warm, concise (1–2 sentences max), and always end by asking to confirm a day or time. Never quote premiums or give policy advice. If the user confirms a day AND time, confirm the booking warmly and say goodbye.";
        const convo = transcript.map(l => `${l.who === 'sarah' ? 'Sarah' : 'User'}: ${l.text}`).join("\n") + `\nUser: ${text}\nSarah:`;
        const r = await Promise.race([
          window.claude.complete(sys + "\n\n" + convo),
          new Promise((_, rej) => setTimeout(() => rej(new Error("timeout")), 4000))
        ]);
        if (r && typeof r === "string" && r.length > 4) {
          reply = r.trim().replace(/^Sarah:\s*/i, "").split("\n")[0];
        }
      }
    } catch (e) {
      // keep scripted reply
    }
    await sarahSays(reply);
  }, [transcript, addLine, sarahSays]);

  // Voice input (Web Speech API)
  const toggleListen = useCallback(() => {
    if (userListening) {
      try { recRef.current && recRef.current.stop(); } catch (e) {}
      setUserListening(false);
      return;
    }
    const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
    if (!SR) { alert("Your browser doesn't support voice input. Type instead."); return; }
    const r = new SR();
    r.lang = "en-US"; r.interimResults = false; r.maxAlternatives = 1;
    r.onresult = (ev) => {
      const text = ev.results[0][0].transcript;
      setUserListening(false);
      handleUserReply(text);
    };
    r.onerror = () => setUserListening(false);
    r.onend = () => setUserListening(false);
    recRef.current = r;
    setUserListening(true);
    r.start();
  }, [userListening, handleUserReply]);

  const mmss = `${String(Math.floor(elapsed / 60)).padStart(2, "0")}:${String(elapsed % 60).padStart(2, "0")}`;

  return (
    <div className="demo-wrap">
      <div className="demo-card">
        {/* LEFT: call state + controls */}
        <div className="demo-left">
          <div className="demo-eyebrow">
            {state === "live" && <><span className="rec-dot"/> <span>Live call</span></>}
            {state === "idle" && <span>Demo · your phone · no signup</span>}
            {state === "connecting" && <span>Connecting…</span>}
            {state === "ended" && <span>Call ended</span>}
          </div>

          <div className="demo-hero">
            <div className={`demo-ring ${state === "live" ? "demo-ring--live" : ""}`}>
              <div className="demo-avatar">
                {state === "connecting" ? <span className="demo-spinner"/> : "S"}
              </div>
            </div>
            <div className="demo-who">
              <div className="demo-name">Sarah</div>
              <div className="demo-sub">
                Bilingual Lead Resurrection · EN + ES
                {state === "live" && <> · <span className="mono">{mmss}</span></>}
              </div>
            </div>
          </div>

          <div className="demo-wave-wrap">
            <Waveform active={sarahSpeaking || userListening} amp={sarahSpeaking ? 1 : 0.6} />
          </div>

          {state === "idle" && (
            <>
              <button className="btn btn--signal btn--lg btn--full" onClick={startCall}>
                <MicIcon s={16}/> Call Sarah now
              </button>
              <p className="demo-foot">
                She'll greet you exactly like she greets an aged lead. Reply in English or Spanish — she switches mid-call. No number required.
              </p>
            </>
          )}

          {state === "connecting" && (
            <button className="btn btn--ghost btn--lg btn--full" disabled>
              <span className="demo-spinner demo-spinner--sm"/> Dialing…
            </button>
          )}

          {state === "live" && (
            <>
              <div className="demo-input-row">
                <input
                  className="demo-input"
                  type="text"
                  placeholder={userListening ? "Listening…" : "Type your reply to Sarah"}
                  value={userInput}
                  onChange={(e) => setUserInput(e.target.value)}
                  onKeyDown={(e) => { if (e.key === "Enter") handleUserReply(userInput); }}
                  disabled={sarahSpeaking}
                />
                <button
                  className={`demo-mic-btn ${userListening ? "is-listening" : ""}`}
                  onClick={toggleListen}
                  disabled={sarahSpeaking}
                  aria-label="Talk to Sarah"
                ><MicIcon s={16}/></button>
              </div>
              <button className="btn-end" onClick={endCall}>
                <EndCallIcon s={14}/> End call
              </button>
            </>
          )}

          {state === "ended" && (
            <div className="demo-ended">
              <div className="demo-ended__stat">
                <span>Call length</span>
                <strong className="mono">{mmss}</strong>
              </div>
              <div className="demo-ended__stat">
                <span>Transcript</span>
                <strong>{transcript.length} turns</strong>
              </div>
              <div className="demo-ended__stat">
                <span>Compliance</span>
                <strong style={{ color: "#047857" }}>All 4 checks passed</strong>
              </div>
              <button className="btn btn--primary btn--full" onClick={resetCall}>Start another demo call</button>
              <a href="#pricing" className="btn btn--link" style={{ justifyContent: "center", marginTop: 4 }}>
                Or start the pay-on-bind pilot on your dead-lead list →
              </a>
            </div>
          )}
        </div>

        {/* RIGHT: transcript */}
        <div className="demo-right">
          <div className="demo-right__head">
            <div className="demo-right__title">
              <span className="demo-lock">🔒</span> Live transcript
            </div>
            <div className="demo-right__meta mono">
              {state === "live" ? <><span className="rec-dot"/> REC · {mmss}</> : "Ready"}
            </div>
          </div>
          <div className="demo-right__body" ref={tBodyRef}>
            {transcript.length === 0 && (
              <div className="demo-empty">
                <p>Tap <strong>Call Sarah now</strong> to start.</p>
                <p>You'll hear her opener, AI disclosure, and recording disclosure — exactly what your aged leads hear. Respond in Spanish if you want to hear the switch.</p>
                <ul className="demo-empty__list">
                  <li><span className="dot-live"/> AI disclosure within 10s · EN + ES</li>
                  <li><span className="dot-live"/> Recording disclosure within 15s</li>
                  <li><span className="dot-live"/> TCPA / DNC / aged-consent compliant</li>
                  <li><span className="dot-live"/> Books quote mid-call, switches EN ↔ ES</li>
                </ul>
              </div>
            )}
            {transcript.map((l, i) => (
              <div key={i} className={`tline tline--${l.who}`}>
                <div className={`tline__who ${l.who === "sarah" ? "tline__who--sarah" : ""}`}>
                  {l.who === "sarah" ? "SARAH" : "YOU"}
                </div>
                <div className="tline__text">
                  {l.text}
                  {l.who === "sarah" && i === 0 && <span className="tag">AI disclosed</span>}
                </div>
              </div>
            ))}
            {sarahSpeaking && (
              <div className="tline tline--sarah">
                <div className="tline__who tline__who--sarah">SARAH</div>
                <div className="tline__text demo-typing"><span/><span/><span/></div>
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
};

window.CallDemo = CallDemo;
