// AFTER — Coach screen with Web Speech API (voice in/out)
const { useState: useStateCoach, useRef, useEffect: useEffectCoach } = React;

const CC = {
  cream: '#fafaf8', black: '#0f0f0f', green: '#3d6b4f',
  grayLight: '#f0efed', gray: '#6b6b6b', border: '#e2e0db',
  red: '#dc2626',
};

const ccStyles = {
  screen: { background: CC.cream, height: '100%', display: 'flex', flexDirection: 'column' },
  header: { borderBottom: `1px solid ${CC.border}`, padding: '64px 20px 12px', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' },
  headerTitle: { fontFamily: '"DM Serif Display", Georgia, serif', fontSize: 24, color: CC.black },
  headerSub: { fontFamily: '"DM Sans", system-ui', fontSize: 14, color: CC.gray, marginTop: 4 },
  speakerToggle: (on) => ({
    width: 36, height: 36, borderRadius: '50%',
    border: `1px solid ${on ? CC.green : CC.border}`,
    background: on ? CC.green : 'transparent',
    color: on ? CC.cream : CC.gray,
    display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
    flexShrink: 0,
  }),
  messages: { flex: 1, overflowY: 'auto', padding: '20px 16px', display: 'flex', flexDirection: 'column', gap: 12 },
  bubbleRow: (isUser) => ({ display: 'flex', justifyContent: isUser ? 'flex-end' : 'flex-start' }),
  bubble: (isUser, speaking) => ({
    maxWidth: '82%', borderRadius: 16,
    borderBottomRightRadius: isUser ? 4 : 16,
    borderBottomLeftRadius: isUser ? 16 : 4,
    padding: '12px 16px',
    background: isUser ? CC.green : CC.grayLight,
    fontFamily: '"DM Sans", system-ui', fontSize: 16, lineHeight: 1.5,
    color: isUser ? CC.cream : CC.black,
    boxShadow: speaking ? `0 0 0 2px ${CC.green}` : 'none',
    transition: 'box-shadow .2s',
  }),
  listeningBanner: {
    background: CC.green, color: CC.cream, padding: '8px 16px',
    fontFamily: '"DM Sans", system-ui', fontSize: 13, fontWeight: 500,
    textAlign: 'center', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
  },
  pulseDot: {
    width: 8, height: 8, borderRadius: '50%', background: CC.cream,
    animation: 'coach-pulse 1s infinite',
  },
  unsupportedBanner: {
    background: '#fef2f2', color: CC.red, padding: '8px 16px',
    fontFamily: '"DM Sans", system-ui', fontSize: 12,
    borderTop: `1px solid #fecaca`, textAlign: 'center',
  },
  inputBar: {
    borderTop: `1px solid ${CC.border}`, background: CC.cream,
    padding: '12px 16px', display: 'flex', gap: 8, alignItems: 'flex-end',
  },
  textarea: {
    flex: 1, borderRadius: 16, border: `1px solid ${CC.border}`,
    background: CC.cream, padding: '12px 16px',
    fontFamily: '"DM Sans", system-ui', fontSize: 16, color: CC.black,
    outline: 'none', resize: 'none', lineHeight: 1.5, maxHeight: 120, minHeight: 48,
  },
  iconBtn: (active, disabled) => ({
    width: 48, height: 48, borderRadius: '50%',
    background: active ? CC.red : CC.green,
    border: 'none', cursor: disabled ? 'not-allowed' : 'pointer',
    opacity: disabled ? .4 : 1,
    display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
    transition: 'background .15s',
  }),
};

// Add pulse keyframes
if (typeof document !== 'undefined' && !document.getElementById('coach-anim')) {
  const s = document.createElement('style');
  s.id = 'coach-anim';
  s.textContent = `@keyframes coach-pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .4; transform: scale(1.4); } }`;
  document.head.appendChild(s);
}

const SEED_MESSAGES = [
  { id: '1', role: 'assistant', content: "Morning, Sarah. How loud is the food noise right now, on a scale of one to ten?" },
  { id: '2', role: 'user', content: "Maybe a 7? I keep thinking about the bagels in the kitchen." },
  { id: '3', role: 'assistant', content: "That's loud, but it's not you. It's a signal. When did you eat last, and was there protein in it?" },
  { id: '4', role: 'user', content: "Coffee at 7. Nothing else yet." },
  { id: '5', role: 'assistant', content: "Then this is hunger wearing a costume. Eat a real breakfast first — eggs, yogurt, anything with protein — and we'll see if the bagel is still talking in twenty minutes." },
];

function CoachScreen() {
  const [messages, setMessages] = useStateCoach(SEED_MESSAGES);
  const [input, setInput] = useStateCoach('');
  const [listening, setListening] = useStateCoach(false);
  const [speakerOn, setSpeakerOn] = useStateCoach(true);
  const [speakingId, setSpeakingId] = useStateCoach(null);
  const [error, setError] = useStateCoach(null);
  const recognitionRef = useRef(null);
  const messagesRef = useRef(null);

  const SR = typeof window !== 'undefined' && (window.SpeechRecognition || window.webkitSpeechRecognition);
  const TTS = typeof window !== 'undefined' && window.speechSynthesis;
  const speechSupported = !!SR;
  const ttsSupported = !!TTS;

  // auto-scroll
  useEffectCoach(() => {
    if (messagesRef.current) messagesRef.current.scrollTop = messagesRef.current.scrollHeight;
  }, [messages]);

  // init SpeechRecognition
  useEffectCoach(() => {
    if (!SR) return;
    const rec = new SR();
    rec.continuous = false;
    rec.interimResults = true;
    rec.lang = 'en-US';
    let finalTranscript = '';
    rec.onresult = (e) => {
      let interim = '';
      finalTranscript = '';
      for (let i = 0; i < e.results.length; i++) {
        const t = e.results[i][0].transcript;
        if (e.results[i].isFinal) finalTranscript += t;
        else interim += t;
      }
      setInput(finalTranscript || interim);
    };
    rec.onerror = (e) => {
      setError(e.error === 'not-allowed' ? 'Microphone permission denied.' : `Voice error: ${e.error}`);
      setListening(false);
    };
    rec.onend = () => {
      setListening(false);
      if (finalTranscript.trim()) {
        // auto-send when speech ends with content
        sendMessage(finalTranscript.trim());
      }
    };
    recognitionRef.current = rec;
    return () => { try { rec.stop(); } catch {} };
  }, []);

  function speak(text, id) {
    if (!TTS || !speakerOn) return;
    TTS.cancel();
    const u = new SpeechSynthesisUtterance(text);
    u.rate = 1.0; u.pitch = 1.0; u.volume = 1.0;
    // Prefer a calm female voice if available
    const voices = TTS.getVoices();
    const preferred = voices.find(v => /samantha|female|allison|joanna|karen/i.test(v.name)) || voices.find(v => v.lang.startsWith('en'));
    if (preferred) u.voice = preferred;
    u.onstart = () => setSpeakingId(id);
    u.onend = () => setSpeakingId(null);
    u.onerror = () => setSpeakingId(null);
    TTS.speak(u);
  }

  function toggleListen() {
    if (!recognitionRef.current) return;
    setError(null);
    if (listening) {
      recognitionRef.current.stop();
      setListening(false);
    } else {
      // Stop any ongoing TTS so the mic doesn't catch it
      if (TTS) TTS.cancel();
      setSpeakingId(null);
      setInput('');
      try {
        recognitionRef.current.start();
        setListening(true);
      } catch (err) {
        setError('Could not start microphone.');
      }
    }
  }

  function toggleSpeaker() {
    const next = !speakerOn;
    setSpeakerOn(next);
    if (!next && TTS) { TTS.cancel(); setSpeakingId(null); }
  }

  function sendMessage(textOverride) {
    const text = (textOverride ?? input).trim();
    if (!text) return;
    const userId = Date.now().toString();
    const replyId = (Date.now() + 1).toString();
    const reply = generateReply(text);
    setMessages(m => [
      ...m,
      { id: userId, role: 'user', content: text },
      { id: replyId, role: 'assistant', content: reply },
    ]);
    setInput('');
    // Speak the reply
    setTimeout(() => speak(reply, replyId), 100);
  }

  return (
    <div style={ccStyles.screen}>
      <div style={ccStyles.header}>
        <div>
          <div style={ccStyles.headerTitle}>Coach</div>
          <div style={ccStyles.headerSub}>A steady place for food noise and habits.</div>
        </div>
        {ttsSupported && (
          <button
            style={ccStyles.speakerToggle(speakerOn)}
            onClick={toggleSpeaker}
            title={speakerOn ? 'Mute Coach voice' : 'Unmute Coach voice'}
          >
            {speakerOn ? (
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/>
                <path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"/>
              </svg>
            ) : (
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/>
                <line x1="23" y1="9" x2="17" y2="15"/><line x1="17" y1="9" x2="23" y2="15"/>
              </svg>
            )}
          </button>
        )}
      </div>

      <div style={ccStyles.messages} ref={messagesRef}>
        {messages.map(msg => (
          <div key={msg.id} style={ccStyles.bubbleRow(msg.role === 'user')}>
            <div style={ccStyles.bubble(msg.role === 'user', speakingId === msg.id)}>{msg.content}</div>
          </div>
        ))}
      </div>

      {listening && (
        <div style={ccStyles.listeningBanner}>
          <span style={ccStyles.pulseDot}></span>
          Listening…
        </div>
      )}
      {error && <div style={ccStyles.unsupportedBanner}>{error}</div>}
      {!speechSupported && (
        <div style={ccStyles.unsupportedBanner}>Voice input not supported in this browser.</div>
      )}

      <div style={ccStyles.inputBar}>
        <textarea
          style={ccStyles.textarea}
          placeholder={listening ? "Listening…" : "Message Coach"}
          value={input}
          onChange={e => setInput(e.target.value)}
          rows={1}
          onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } }}
        />
        {speechSupported && (
          <button
            style={ccStyles.iconBtn(listening, false)}
            onClick={toggleListen}
            title={listening ? 'Stop listening' : 'Start voice input'}
          >
            {listening ? (
              <svg width="20" height="20" viewBox="0 0 24 24" fill="#fafaf8">
                <rect x="6" y="6" width="12" height="12" rx="2"/>
              </svg>
            ) : (
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#fafaf8" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                <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"/>
                <line x1="12" y1="19" x2="12" y2="23"/>
                <line x1="8" y1="23" x2="16" y2="23"/>
              </svg>
            )}
          </button>
        )}
        <button
          style={ccStyles.iconBtn(false, !input.trim())}
          onClick={() => sendMessage()}
          disabled={!input.trim()}
        >
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#fafaf8" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <line x1="22" y1="2" x2="11" y2="13"/>
            <polygon points="22 2 15 22 11 13 2 9 22 2"/>
          </svg>
        </button>
      </div>
    </div>
  );
}

// Lightweight, in-character replies — placeholder heuristics, voiced like Coach
function generateReply(text) {
  const t = text.toLowerCase();
  if (/crav|hungry|food noise|snack/.test(t)) {
    return "That sounds loud. Before we problem-solve — when did this start tonight, and how long since your last full meal?";
  }
  if (/scale|weight|gained|gain|up \d/.test(t)) {
    return "One number on one day doesn't tell us much. Your body weight can swing two or three pounds from sleep, salt, or your cycle. Let's look at the trend, not the snapshot.";
  }
  if (/anxious|panic|overwhelm|stressed/.test(t)) {
    return "Let's slow it down for sixty seconds. Want me to walk you through a quick reset?";
  }
  if (/hi|hello|hey/.test(t)) {
    return "Good to hear from you. What's coming up for you today?";
  }
  return "Tell me a little more — I'm listening.";
}

Object.assign(window, { CoachScreen });
