/* global React, window */
/* Atlas demo flow — FAB, overlay, conversation, voice/text input.
 * Persona, questions, and proposal templates live in src/demo-data.jsx.
 * Proposal view lives in src/demo-proposal.jsx.
 */
const { useState, useEffect, useRef, useCallback } = React;

/* ---------------- FAB ---------------- */
function DemoFAB({ open, onOpen }) {
  return (
    <button
      className={`demo-fab ${open ? 'hidden' : ''}`}
      onClick={onOpen}
      aria-label="Try the demo — talk to Atlas"
    >
      <span className="demo-fab-mark">
        <img src="assets/bastion-3d-mark-cutout.png" alt="" />
      </span>
      <span className="demo-fab-body">
        <span className="demo-fab-label">Talk to Atlas</span>
        <span className="demo-fab-sub">2-minute demo · voice or text</span>
      </span>
      <span className="demo-fab-pulse" aria-hidden="true"></span>
    </button>
  );
}

/* ---------------- Atlas conversation card ---------------- */
function AtlasCard({ children, thinking, topic, idx }) {
  return (
    <div className="demo-card atlas">
      <div className="demo-card-head">
        <span className="demo-card-pip atlas-pip"></span>
        <span className="demo-card-who">Atlas</span>
        {topic && <span className="demo-card-topic">{topic}</span>}
        {idx != null && <span className="demo-card-num">Q{idx + 1}</span>}
      </div>
      <div className="demo-card-body">
        {thinking ? (
          <span className="demo-thinking">
            <span className="dot"></span><span className="dot"></span><span className="dot"></span>
            <span className="muted-text">{thinking}</span>
          </span>
        ) : children}
      </div>
    </div>
  );
}

function UserCard({ children, topic }) {
  return (
    <div className="demo-card user">
      <div className="demo-card-head">
        <span className="demo-card-who">You</span>
        {topic && <span className="demo-card-topic">{topic}</span>}
      </div>
      <div className="demo-card-body">{children}</div>
    </div>
  );
}

/* ---------------- Mic / text input ---------------- */
function VoiceTextInput({ onSubmit, placeholder, disabled }) {
  const [text, setText] = useState('');
  const [listening, setListening] = useState(false);
  const [held, setHeld] = useState(false);
  const [supported, setSupported] = useState(false);
  const [waveform, setWaveform] = useState(() => new Array(28).fill(4));
  const recRef = useRef(null);
  const interimRef = useRef('');
  const inputRef = useRef(null);
  const waveTimerRef = useRef(null);

  useEffect(() => {
    const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
    setSupported(!!SR);
  }, []);

  const startWave = () => {
    if (waveTimerRef.current) return;
    waveTimerRef.current = setInterval(() => {
      setWaveform((w) => w.map(() => 4 + Math.random() * (held ? 28 : 14)));
    }, 70);
  };
  const stopWave = () => {
    if (waveTimerRef.current) { clearInterval(waveTimerRef.current); waveTimerRef.current = null; }
    setWaveform((w) => w.map(() => 4));
  };

  const startListening = () => {
    if (disabled) return;
    setHeld(true);
    startWave();
    const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
    if (SR) {
      try {
        const r = new SR();
        r.continuous = true;
        r.interimResults = true;
        r.lang = 'en-US';
        r.onresult = (e) => {
          let final = '';
          let interim = '';
          for (let i = e.resultIndex; i < e.results.length; i++) {
            const res = e.results[i];
            if (res.isFinal) final += res[0].transcript + ' ';
            else interim += res[0].transcript;
          }
          interimRef.current = (interimRef.current + ' ' + final).trim();
          setText(((interimRef.current + ' ' + interim).trim()));
        };
        r.onerror = () => {};
        r.onend = () => { setListening(false); };
        r.start();
        recRef.current = r;
        setListening(true);
      } catch (e) {
        // permission denied or browser doesn't allow — fall back to text input
        setListening(false);
      }
    }
  };

  const stopListening = () => {
    setHeld(false);
    stopWave();
    if (recRef.current) {
      try { recRef.current.stop(); } catch (e) {}
      recRef.current = null;
    }
    setListening(false);
    // give the recognizer a beat to flush final transcript
  };

  // Handlers
  const onMicDown = (e) => { e.preventDefault(); startListening(); };
  const onMicUp = (e) => { e.preventDefault(); stopListening(); };

  const submit = () => {
    const v = (text || '').trim();
    if (!v) return;
    stopListening();
    interimRef.current = '';
    setText('');
    onSubmit(v);
  };

  const onKeyDown = (e) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      submit();
    }
  };

  return (
    <div className={`demo-input ${held ? 'recording' : ''}`}>
      <div className="demo-input-mic-wrap">
        <button
          className={`demo-mic ${held ? 'on' : ''}`}
          onMouseDown={onMicDown}
          onMouseUp={onMicUp}
          onMouseLeave={(e) => { if (held) onMicUp(e); }}
          onTouchStart={onMicDown}
          onTouchEnd={onMicUp}
          disabled={disabled}
          aria-label="Hold to speak"
          title={supported ? 'Hold to speak' : 'Voice not available in this browser — type instead'}
        >
          <svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
            <path fill="currentColor" d="M12 14a3 3 0 0 0 3-3V6a3 3 0 1 0-6 0v5a3 3 0 0 0 3 3z" />
            <path fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" d="M5 11a7 7 0 0 0 14 0M12 18v3" />
          </svg>
        </button>
        <div className="demo-wave" aria-hidden="true">
          {waveform.map((h, i) => (
            <span key={i} style={{ height: `${h}px` }}></span>
          ))}
        </div>
        <span className="demo-mic-hint">
          {held ? 'Listening…' : (supported ? 'Hold to speak' : 'Type below')}
        </span>
      </div>
      <div className="demo-text-row">
        <textarea
          ref={inputRef}
          className="demo-text"
          rows={2}
          value={text}
          onChange={(e) => setText(e.target.value)}
          onKeyDown={onKeyDown}
          placeholder={placeholder}
          disabled={disabled}
        />
        <button className="demo-send" onClick={submit} disabled={disabled || !text.trim()}>
          Send <span className="arrow"></span>
        </button>
      </div>
    </div>
  );
}

/* ---------------- Demo flow ---------------- */
function Demo() {
  const [open, setOpen] = useState(false);
  const [phase, setPhase] = useState('intro'); // intro | qN | thinking | generating | proposal
  const [qIdx, setQIdx] = useState(-1);
  const [history, setHistory] = useState([]); // {role, text, topic, idx?}
  const [answers, setAnswers] = useState({});
  const [thinkingMsg, setThinkingMsg] = useState('');
  const [proposal, setProposal] = useState(null);
  const [aiIntro, setAiIntro] = useState('');
  const scrollRef = useRef(null);

  // Auto-scroll to bottom on history change
  useEffect(() => {
    const el = scrollRef.current;
    if (!el) return;
    el.scrollTo({ top: el.scrollHeight, behavior: 'smooth' });
  }, [history, phase]);

  // Reset when closing
  const close = () => {
    setOpen(false);
    setTimeout(() => {
      setPhase('intro');
      setQIdx(-1);
      setHistory([]);
      setAnswers({});
      setProposal(null);
      setAiIntro('');
    }, 350);
  };

  // Lock body scroll while open
  useEffect(() => {
    if (open) document.body.style.overflow = 'hidden';
    else document.body.style.overflow = '';
    return () => { document.body.style.overflow = ''; };
  }, [open]);

  // Esc closes
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') close(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open]);

  // Phase transitions
  const startInterview = () => {
    window.bastionAnalytics?.track('lead_form_start', { lead_source: 'talk_to_atlas' });
    setHistory([{ role: 'atlas', text: window.ATLAS.ready }]);
    setTimeout(() => askQuestion(0), 400);
  };

  const askQuestion = (i) => {
    const q = window.QUESTIONS[i];
    if (!q) return;
    setQIdx(i);
    setPhase('q' + i);
    setHistory((h) => [...h, { role: 'atlas', text: q.prompt, topic: q.topic, idx: i }]);
  };

  // Get an Atlas follow-up via Claude (with template fallback)
  const getFollowup = useCallback(async (i, answer) => {
    const q = window.QUESTIONS[i];
    const next = window.QUESTIONS[i + 1];
    const isLast = !next;
    const fallback = (q.ack || '') + (next ? `Next — ${next.prompt}` : window.ATLAS.generating);
    if (!window.claude || !window.claude.complete) return fallback;
    try {
      const prompt = window.atlasFollowupPrompt({
        topic: q.topic, prompt: q.prompt, answer,
        nextTopic: next ? next.topic : null,
        nextPrompt: next ? next.prompt : null,
        isLast,
      });
      const text = await window.claude.complete(prompt);
      const cleaned = (text || '').trim().replace(/^"|"$/g, '');
      return cleaned.length > 8 ? cleaned : fallback;
    } catch (e) {
      return fallback;
    }
  }, []);

  const onAnswer = async (text) => {
    const q = window.QUESTIONS[qIdx];
    if (!q) return;
    const newAnswers = { ...answers, [q.id]: text };
    setAnswers(newAnswers);
    setHistory((h) => [...h, { role: 'user', text, topic: q.topic }]);

    // Thinking state
    setPhase('thinking');
    const tLine = window.ATLAS.thinkingLines[Math.floor(Math.random() * window.ATLAS.thinkingLines.length)];
    setThinkingMsg(tLine);

    // Get the follow-up
    const followup = await getFollowup(qIdx, text);

    // Brief thinking pause for realism
    await new Promise((r) => setTimeout(r, 700));
    setThinkingMsg('');

    if (qIdx + 1 < window.QUESTIONS.length) {
      // Append Atlas's follow-up + next question prompt as ONE Atlas card
      const next = window.QUESTIONS[qIdx + 1];
      setHistory((h) => [...h, { role: 'atlas', text: followup, topic: next.topic, idx: qIdx + 1 }]);
      setQIdx(qIdx + 1);
      setPhase('q' + (qIdx + 1));
    } else {
      // Final — generate proposal
      setHistory((h) => [...h, { role: 'atlas', text: followup }]);
      setPhase('generating');
      const template = window.buildProposalTemplate(newAnswers);
      // Optional AI intro line for the proposal
      let intro = "Here's how we'd shape a Bastion sprint for what you described.";
      if (window.claude && window.claude.complete) {
        try {
          const promptIntro = window.atlasProposalIntroPrompt(newAnswers, template);
          const text = await window.claude.complete(promptIntro);
          if (text && text.trim().length > 12) intro = text.trim().replace(/^"|"$/g, '');
        } catch (e) {}
      }
      // Simulate building time
      await new Promise((r) => setTimeout(r, 1400));
      window.bastionAnalytics?.track('lead_form_submit_success', {
        lead_source: 'talk_to_atlas',
        tools_used: newAnswers.tools,
        budget_range: newAnswers.budget,
      });
      setProposal(template);
      setAiIntro(intro);
      setPhase('proposal');
    }
  };

  const prefillContact = () => {
    // Stash answers for the contact form to pick up
    try {
      window.__bastionAnswers = answers;
      window.bastionAnalytics?.primaryCtaClick('Send a longer note instead', 'talk_to_atlas_proposal');
      window.dispatchEvent(new CustomEvent('bastion:prefill-contact', { detail: answers }));
    } catch (e) {}
    close();
    setTimeout(() => {
      const el = document.getElementById('contact');
      if (el) {
        const y = el.getBoundingClientRect().top + window.scrollY - 30;
        window.scrollTo({ top: y, behavior: 'smooth' });
      }
    }, 350);
  };

  const inProposal = phase === 'proposal' && proposal;
  const showInput = phase.startsWith('q') && !phase.startsWith('generating');

  return (
    <>
      <DemoFAB open={open} onOpen={() => { window.bastionAnalytics?.leadFormView('talk_to_atlas'); setOpen(true); }} />
      <div className={`demo-overlay ${open ? 'open' : ''}`} onClick={(e) => { if (e.target === e.currentTarget) close(); }}>
        <div className="demo-modal">
          <header className="demo-header">
            <div className="demo-header-left">
              <span className="demo-header-mark">
                <img src="assets/bastion-3d-mark-cutout.png" alt="" />
              </span>
              <div>
                <div className="demo-header-title">Atlas · Bastion AI</div>
                <div className="demo-header-sub">Quick AI sprint sketch — voice or text</div>
              </div>
            </div>
            <div className="demo-header-right">
              {phase !== 'intro' && !inProposal && (
                <div className="demo-progress">
                  <span className="demo-progress-label">
                    {phase === 'generating' ? 'Drafting proposal' : `Question ${Math.min(qIdx + 1, 5)} of 5`}
                  </span>
                  <div className="demo-progress-bar">
                    <div className="demo-progress-fill" style={{ width: `${Math.min(100, ((qIdx + (phase === 'thinking' ? 1 : 0)) / 5) * 100)}%` }}></div>
                  </div>
                </div>
              )}
              <button className="demo-close" onClick={close} aria-label="Close demo">
                <svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true">
                  <path d="M3 3 L13 13 M13 3 L3 13" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
                </svg>
              </button>
            </div>
          </header>

          <div ref={scrollRef} className="demo-scroll">
            {phase === 'intro' ? (
              <div className="demo-intro">
                <AtlasCard>{window.ATLAS.intro}</AtlasCard>
                <div className="demo-intro-actions">
                  <button className="btn btn-primary" onClick={startInterview}>
                    Start the demo <span className="arrow"></span>
                  </button>
                  <span className="demo-intro-meta">Takes about 2 minutes · 5 short questions</span>
                </div>
              </div>
            ) : (
              <>
                {history.map((m, i) => (
                  m.role === 'atlas'
                    ? <AtlasCard key={i} topic={m.topic} idx={m.idx}>{m.text}</AtlasCard>
                    : <UserCard key={i} topic={m.topic}>{m.text}</UserCard>
                ))}
                {phase === 'thinking' && thinkingMsg && (
                  <AtlasCard thinking={thinkingMsg} />
                )}
                {phase === 'generating' && (
                  <AtlasCard thinking="Drafting your proposal…" />
                )}
                {inProposal && (
                  <window.DemoProposal
                    intro={aiIntro}
                    proposal={proposal}
                    answers={answers}
                    onPrefillContact={prefillContact}
                    onClose={close}
                  />
                )}
              </>
            )}
          </div>

          {showInput && (
            <VoiceTextInput
              onSubmit={onAnswer}
              placeholder={window.QUESTIONS[qIdx]?.placeholder || 'Type your answer…'}
              disabled={phase === 'thinking'}
            />
          )}
        </div>
      </div>
    </>
  );
}

Object.assign(window, { Demo, DemoFAB, AtlasCard, UserCard, VoiceTextInput });
