// NPC Chat — Azure OpenAI conversations served by the backend NpcChatService.
// Per-character history; switching the "Speaking as" dropdown reloads with that scope.
const NpcChatView = ({ npcId, campaignId, user, setNav }) => {
  const [npc, setNpc] = React.useState(null);
  const [campaign, setCampaign] = React.useState(null);
  const [myChar, setMyChar] = React.useState(null);
  const [messages, setMessages] = React.useState([]);
  const [input, setInput] = React.useState('');
  const [loading, setLoading] = React.useState(false);
  const [bootstrapping, setBootstrapping] = React.useState(true);
  const [loadError, setLoadError] = React.useState(null);
  const [speakingAs, setSpeakingAs] = React.useState(user.name);
  const bottomRef = React.useRef(null);

  // Initial load: NPC + campaign + my character (if any) — in parallel.
  React.useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const [npcRes, campaignRes, charsRes] = await Promise.all([
          api.npcs.get(campaignId, npcId),
          api.campaigns.get(campaignId),
          api.characters.list({ campaignId }),
        ]);
        if (cancelled) return;
        const augmented = api.augmentNpc(npcRes);
        const myC = (charsRes || []).map(api.augmentCharacter).find(c => c.playerId === user.id) || null;
        setNpc(augmented);
        setCampaign(campaignRes);
        setMyChar(myC);
        setSpeakingAs(myC?.name || user.name);
        // Load chat history scoped to (npc, character)
        const charId = myC?.id || null;
        const history = await api.npcs.chat.list(campaignId, npcId, charId);
        if (!cancelled) setMessages((history || []).map(m => ({
          role: m.role, character: m.characterName, content: m.content,
        })));
      } catch (err) {
        if (!cancelled) setLoadError(err.status === 404 ? 'NPC not found.' : (err.message || 'Failed to load NPC.'));
      } finally {
        if (!cancelled) setBootstrapping(false);
      }
    })();
    return () => { cancelled = true; };
  }, [campaignId, npcId, user.id, user.name]);

  React.useEffect(() => {
    if (bottomRef.current) bottomRef.current.scrollTop = bottomRef.current.scrollHeight;
  }, [messages]);

  if (bootstrapping) return <div style={{color:'#9a9793',padding:40}}>Loading conversation…</div>;
  if (loadError)     return <div style={{color:'#9a9793',padding:40}}>{loadError}</div>;
  if (!npc)          return <div style={{color:'#9a9793',padding:40}}>NPC not found.</div>;

  const speakingAsCharId = (myChar && speakingAs === myChar.name) ? myChar.id : null;

  const sendMessage = async () => {
    if (!input.trim() || loading) return;
    const userMsg = { role: 'user', character: speakingAs, content: input.trim() };
    setMessages(prev => [...prev, userMsg]);
    const message = input.trim();
    setInput('');
    setLoading(true);
    try {
      const res = await api.npcs.chat.send(campaignId, npcId, {
        message, characterId: speakingAsCharId, speakingAs,
      });
      setMessages(prev => [...prev, { role: 'npc', content: res.reply }]);
    } catch (err) {
      console.error('[NpcChatView] chat send failed:', err);
      setMessages(prev => [...prev, { role: 'npc', content: '*(The connection falters — the NPC is temporarily unreachable.)*' }]);
    }
    setLoading(false);
  };

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

  const relEntry = myChar ? npc.relationship[myChar.id] : null;

  return (
    <div style={npcStyles.page}>
      {/* Header */}
      <div style={npcStyles.header}>
        <button style={npcStyles.backBtn} onClick={() => setNav({ view: 'campaign', campaignId, tab: 'npcs' })}>
          ← Back to NPCs
        </button>
        <div style={npcStyles.headerInfo}>
          <div style={npcStyles.npcAvatarLg}>{npc.avatar}</div>
          <div>
            <div style={npcStyles.npcName}>{npc.name}</div>
            <div style={npcStyles.npcTitle}>{npc.title} · {npc.race}</div>
          </div>
          {relEntry && (
            <span style={{...npcStyles.relBadge, ...(relEntry==='grudge' ? {background:'rgba(197,48,48,0.15)',color:'#f87171'} : relEntry==='respected'||relEntry==='close' ? {background:'rgba(30,107,60,0.15)',color:'#22c55e'} : {background:'rgba(107,105,102,0.15)',color:'#9a9793'})}}>
              {relEntry}
            </span>
          )}
        </div>
        <div style={{marginLeft:'auto', display:'flex', alignItems:'center', gap:10}}>
          <span style={{fontSize:12, color:'#6b6966'}}>Speaking as:</span>
          <select style={npcStyles.select} value={speakingAs} onChange={e => setSpeakingAs(e.target.value)}>
            {myChar && <option value={myChar.name}>{myChar.name} (my character)</option>}
            <option value={user.name}>{user.name} (myself)</option>
          </select>
        </div>
      </div>

      <div style={npcStyles.body}>
        {/* Sidebar — NPC info */}
        <div style={npcStyles.sidebar}>
          <div style={npcStyles.sideSection}>
            <div style={npcStyles.sideSectionTitle}>Personality</div>
            <p style={npcStyles.sideText}>{npc.personality}</p>
          </div>
          <div style={npcStyles.sideSection}>
            <div style={npcStyles.sideSectionTitle}>Goals</div>
            <p style={npcStyles.sideText}>{npc.goals}</p>
          </div>
          <div style={npcStyles.sideSection}>
            <div style={npcStyles.sideSectionTitle}>Memory & History</div>
            <p style={npcStyles.sideText}>{npc.memoryNotes}</p>
          </div>
          <div style={{...npcStyles.sideSection, borderLeft: '3px solid #c9a227', paddingLeft:12, borderRadius:0}}>
            <div style={{fontSize:10, color:'#c9a227', fontWeight:800, textTransform:'uppercase', letterSpacing:'0.1em', marginBottom:4}}>Azure OpenAI</div>
            <div style={{fontSize:11, color:'#6b6966', lineHeight:1.5}}>In production, conversations are stored per character per NPC and injected as memory context. This NPC remembers promises, grudges, and past interactions.</div>
          </div>
        </div>

        {/* Chat area */}
        <div style={npcStyles.chatArea}>
          <div style={npcStyles.messages} ref={bottomRef}>
            {messages.length === 0 && (
              <div style={npcStyles.emptyState}>
                <div style={{fontSize:32, marginBottom:8}}>{npc.avatar}</div>
                <div style={{fontSize:14, color:'#6b6966'}}>Begin your conversation with {npc.name}.</div>
                <div style={{fontSize:12, color:'#4a4a52', marginTop:4}}>They are aware of your history together.</div>
              </div>
            )}
            {messages.map((msg, i) => (
              <div key={i} style={{...npcStyles.bubble, ...(msg.role === 'user' ? npcStyles.bubbleUser : npcStyles.bubbleNpc)}}>
                {msg.role === 'user' ? (
                  <>
                    <div style={npcStyles.bubbleSpeaker}>{msg.character}</div>
                    <div style={npcStyles.bubbleText}>{window.renderMarkdown ? window.renderMarkdown(msg.content) : msg.content}</div>
                  </>
                ) : (
                  <>
                    <div style={npcStyles.bubbleSpeaker}>{npc.name}</div>
                    <div style={{...npcStyles.bubbleText, fontStyle: msg.content.startsWith('*') ? 'italic' : 'normal'}}>{window.renderMarkdown ? window.renderMarkdown(msg.content) : msg.content}</div>
                  </>
                )}
              </div>
            ))}
            {loading && (
              <div style={{...npcStyles.bubble, ...npcStyles.bubbleNpc}}>
                <div style={npcStyles.bubbleSpeaker}>{npc.name}</div>
                <div style={npcStyles.typing}><span></span><span></span><span></span></div>
              </div>
            )}
          </div>

          {/* Input */}
          <div style={npcStyles.inputArea}>
            <textarea
              style={npcStyles.textarea}
              value={input}
              onChange={e => setInput(e.target.value)}
              onKeyDown={handleKey}
              placeholder={`Say something to ${npc.name}… (Enter to send)`}
              rows={2}
              disabled={loading}
            />
            <button style={{...npcStyles.sendBtn, opacity: loading || !input.trim() ? 0.5 : 1}} onClick={sendMessage} disabled={loading || !input.trim()}>
              Send ↵
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

const npcStyles = {
  page: { display: 'flex', flexDirection: 'column', height: '100vh', overflow: 'hidden', fontFamily: "'Nunito',sans-serif" },
  header: { padding: '14px 24px', borderBottom: '1px solid #2a2a32', display: 'flex', alignItems: 'center', gap: 16, flexShrink: 0, background: '#16161b', flexWrap: 'wrap' },
  backBtn: { background: 'none', border: 'none', color: '#9a9793', cursor: 'pointer', fontSize: 13, fontWeight: 700, padding: 0 },
  headerInfo: { display: 'flex', alignItems: 'center', gap: 12 },
  npcAvatarLg: { width: 42, height: 42, borderRadius: 8, background: '#2a2a32', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 14, fontWeight: 800, color: '#c9a227', flexShrink: 0 },
  npcName: { fontFamily: "'Cinzel',serif", fontSize: 16, fontWeight: 700, color: '#e8e6e3' },
  npcTitle: { fontSize: 12, color: '#9a9793' },
  relBadge: { fontSize: 10, fontWeight: 700, padding: '2px 8px', borderRadius: 20, textTransform: 'capitalize' },
  select: { background: '#1c1c22', border: '1px solid #3a3a42', borderRadius: 6, color: '#e8e6e3', padding: '5px 10px', fontSize: 12, cursor: 'pointer', fontFamily: "'Nunito',sans-serif" },
  body: { display: 'flex', flex: 1, overflow: 'hidden' },
  sidebar: { width: 260, borderRight: '1px solid #2a2a32', padding: 20, overflowY: 'auto', background: '#16161b', flexShrink: 0, display: 'flex', flexDirection: 'column', gap: 16 },
  sideSection: { background: '#1c1c22', border: '1px solid #2a2a32', borderRadius: 8, padding: '12px 14px' },
  sideSectionTitle: { fontSize: 10, fontWeight: 800, color: '#6b6966', textTransform: 'uppercase', letterSpacing: '0.1em', marginBottom: 6 },
  sideText: { fontSize: 12, color: '#9a9793', lineHeight: 1.6, margin: 0 },
  chatArea: { flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' },
  messages: { flex: 1, overflowY: 'auto', padding: '24px 28px', display: 'flex', flexDirection: 'column', gap: 16 },
  emptyState: { textAlign: 'center', margin: 'auto', paddingTop: 60 },
  bubble: { maxWidth: '72%', padding: '12px 16px', borderRadius: 12 },
  bubbleUser: { alignSelf: 'flex-end', background: 'rgba(197,48,48,0.15)', border: '1px solid rgba(197,48,48,0.25)' },
  bubbleNpc: { alignSelf: 'flex-start', background: '#1c1c22', border: '1px solid #2a2a32' },
  bubbleSpeaker: { fontSize: 10, fontWeight: 800, color: '#6b6966', textTransform: 'uppercase', letterSpacing: '0.1em', marginBottom: 4 },
  bubbleText: { fontSize: 14, color: '#e8e6e3', lineHeight: 1.6 },
  typing: { display: 'flex', gap: 4, alignItems: 'center', height: 20, padding: '2px 0' },
  inputArea: { borderTop: '1px solid #2a2a32', padding: '14px 20px', display: 'flex', gap: 12, background: '#16161b', flexShrink: 0 },
  textarea: { flex: 1, background: '#111116', border: '1px solid #3a3a42', borderRadius: 8, color: '#e8e6e3', padding: '10px 14px', fontSize: 14, resize: 'none', outline: 'none', fontFamily: "'Nunito',sans-serif" },
  sendBtn: { background: '#c53030', border: 'none', color: '#fff', borderRadius: 8, padding: '0 20px', fontWeight: 700, fontSize: 14, cursor: 'pointer', fontFamily: "'Nunito',sans-serif" },
};

// Add typing animation via a style tag
const typingStyle = document.createElement('style');
typingStyle.textContent = `
  .typing-dot { width:7px; height:7px; border-radius:50%; background:#6b6966; animation: typing-bounce 1s infinite; display:inline-block; }
  .typing-dot:nth-child(2) { animation-delay:0.15s; }
  .typing-dot:nth-child(3) { animation-delay:0.3s; }
  @keyframes typing-bounce { 0%,80%,100%{transform:translateY(0)} 40%{transform:translateY(-6px)} }
`;
document.head.appendChild(typingStyle);

// Patch typing dots
const TypingIndicator = () => (
  <div style={{display:'flex',gap:4,alignItems:'center',height:20}}>
    <span className="typing-dot"></span>
    <span className="typing-dot"></span>
    <span className="typing-dot"></span>
  </div>
);

Object.assign(window, { NpcChatView, npcStyles });
