/* MY GENI — Phase 22 · Geni AI floating experience
 *
 * Two components:
 *   <GeniOrb />   — fixed bottom-right, collapsed CTA. Uses geni-ai.webp
 *                    (masked to a circle) as the primary identity.
 *   <GeniPanel /> — 420×620 floating panel with header / thread /
 *                    composer / suggestions. Minimize/close/reset.
 *
 * The response engine (window.Geni) is deterministic and reads canonical
 * MYGENI_* data. Nothing here calls a real AI backend.
 */

// -- Message ------------------------------------------------------
function GeniMessage({ role, text, sources }) {
  const isUser = role === 'user';
  // Simple **bold** parser so mock responses can emphasize numbers/names.
  function formatText(t) {
    if (!t) return null;
    const parts = t.split(/(\*\*[^*]+\*\*)/g);
    return parts.map((p, i) => {
      if (p.startsWith('**') && p.endsWith('**')) {
        return <b key={i}>{p.slice(2, -2)}</b>;
      }
      return <React.Fragment key={i}>{p}</React.Fragment>;
    });
  }
  return (
    <div className={`geni-msg geni-msg-${isUser ? 'user' : 'ai'}`}>
      {!isUser && <div className="geni-msg-mark" aria-hidden="true" />}
      <div className="geni-msg-body">
        {text.split('\n\n').map((para, i) => (
          <p key={i} className="geni-msg-p">{formatText(para)}</p>
        ))}
        {!!(sources && sources.length) && (
          <div className="geni-sources">
            {sources.map((s, i) => (
              <a key={i} className="geni-source" href={s.route} onClick={(e) => e.stopPropagation()}>
                <span className="geni-source-kind">{s.kind}</span>
                <span className="geni-source-label">{s.label}</span>
              </a>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

// -- Panel --------------------------------------------------------
function GeniPanel({ onClose, onMinimize }) {
  const [messages, setMessages] = React.useState(() => {
    try {
      const stored = localStorage.getItem('mygeni:ai:messages');
      if (stored) return JSON.parse(stored);
    } catch (e) {}
    return [];
  });
  const [input, setInput] = React.useState('');
  const [typing, setTyping] = React.useState(false);
  const [routeTick, setRouteTick] = React.useState(0);
  const scrollRef = React.useRef(null);
  const inputRef = React.useRef(null);

  // Persist thread
  React.useEffect(() => {
    try { localStorage.setItem('mygeni:ai:messages', JSON.stringify(messages)); } catch (e) {}
  }, [messages]);

  // Route awareness — re-render suggestions on hash change
  React.useEffect(() => {
    function onHash() { setRouteTick(t => t + 1); }
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);

  // Auto-scroll to newest
  React.useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [messages, typing]);

  // Autofocus composer
  React.useEffect(() => { if (inputRef.current) inputRef.current.focus(); }, []);

  function send(prompt) {
    const p = (prompt || input || '').trim();
    if (!p) return;
    setInput('');
    const userMsg = { id: 'u' + Date.now(), role: 'user', text: p };
    setMessages(m => [...m, userMsg]);
    setTyping(true);

    // Deterministic response from local brain, delivered with a
    // small delay + typewriter render so it feels alive.
    setTimeout(() => {
      let reply;
      try { reply = window.Geni.think({ prompt: p }); }
      catch (e) { reply = { text: `I hit a snag composing that reply. (${e.message || e})`, sources: [] }; }

      const aiMsg = {
        id: 'a' + Date.now(),
        role: 'ai',
        text: reply.text || '…',
        sources: reply.sources || [],
        typewriter: true,
      };
      setMessages(m => [...m, aiMsg]);
      setTyping(false);
    }, 520);
  }

  function reset() {
    setMessages([]);
    setInput('');
    try { localStorage.setItem('mygeni:ai:messages', '[]'); } catch (e) {}
  }

  const greeting = window.Geni ? window.Geni.greeting() : 'Hi.';
  const suggestions = window.Geni ? window.Geni.suggestions() : [];

  return (
    <div className="geni-panel" role="dialog" aria-label="Geni AI">
      <div className="geni-header">
        <div className="geni-header-id">
          <div className="geni-header-orb" aria-hidden="true" />
          <div className="geni-header-meta">
            <div className="geni-header-name">Geni AI</div>
            <div className="geni-header-sub">MY GENI · local prototype</div>
          </div>
        </div>
        <div className="geni-header-actions">
          <button className="geni-btn-ghost" title="New conversation" onClick={reset} aria-label="Reset">
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none">
              <path d="M4 12a8 8 0 0114-5.29M20 4v5h-5M20 12a8 8 0 01-14 5.29M4 20v-5h5" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
          </button>
          <button className="geni-btn-ghost" title="Minimize" onClick={onMinimize} aria-label="Minimize">
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none">
              <path d="M6 14h12" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round"/>
            </svg>
          </button>
          <button className="geni-btn-ghost" title="Close" onClick={onClose} aria-label="Close">
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none">
              <path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round"/>
            </svg>
          </button>
        </div>
      </div>

      <div className="geni-thread" ref={scrollRef}>
        {messages.length === 0 && (
          <div className="geni-empty">
            <div className="geni-empty-orb" aria-hidden="true" />
            <div className="geni-empty-title">Ask Geni</div>
            <div className="geni-empty-sub">{greeting}</div>
          </div>
        )}
        {messages.map(m => <GeniMessage key={m.id} role={m.role} text={m.text} sources={m.sources} />)}
        {typing && (
          <div className="geni-msg geni-msg-ai">
            <div className="geni-msg-mark" aria-hidden="true" />
            <div className="geni-msg-body">
              <div className="geni-typing"><span/><span/><span/></div>
            </div>
          </div>
        )}
      </div>

      <div className="geni-suggestions">
        {suggestions.map((s, i) => (
          <button key={i} className="geni-suggestion" onClick={() => send(s)}>{s}</button>
        ))}
      </div>

      <div className="geni-composer">
        <input
          ref={inputRef}
          className="geni-input"
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyDown={(e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); } }}
          placeholder="Ask about attention, momentum, decisions…"
        />
        <button className="geni-send" onClick={() => send()} aria-label="Send" disabled={!input.trim()}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
            <path d="M4 12h14M12 5l7 7-7 7" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </button>
      </div>
    </div>
  );
}

// -- Orb + wrapper ------------------------------------------------
function GeniAI() {
  const [open, setOpen] = React.useState(() => {
    try { return localStorage.getItem('mygeni:ai:open') === '1'; } catch (e) { return false; }
  });

  React.useEffect(() => {
    try { localStorage.setItem('mygeni:ai:open', open ? '1' : '0'); } catch (e) {}
  }, [open]);

  // Close on Escape when open
  React.useEffect(() => {
    function onKey(e) { if (e.key === 'Escape' && open) setOpen(false); }
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [open]);

  return (
    <>
      {open && (
        <GeniPanel
          onClose={() => setOpen(false)}
          onMinimize={() => setOpen(false)}
        />
      )}
      <button
        className={`geni-orb ${open ? 'geni-orb-open' : ''}`}
        onClick={() => setOpen(v => !v)}
        aria-label={open ? 'Close Geni' : 'Ask Geni'}
        data-tip={open ? null : 'Ask Geni'}
      >
        <span className="geni-orb-img" aria-hidden="true" />
      </button>
    </>
  );
}

Object.assign(window, { GeniAI, GeniPanel, GeniOrb: GeniAI });
