/* MY GENI — Phase 22 · Geni AI floating experience
 *   + Phase 24 · Prompt 5 upgrades (operating-layer polish)
 *
 * Two components:
 *   <GeniOrb />   — fixed bottom-right (rendered by <GeniAI>). Uses the
 *                    transparent gold-lamp PNG as the identity mark.
 *   <GeniPanel /> — floating panel with header / thread / composer /
 *                    suggestions. Minimize / close / reset.
 *
 * Response engine (window.Geni) is deterministic + local. No backend.
 *
 * Response contract (Prompt 5, backward-compatible):
 *   {
 *     text:    string   – markdown-lite (** bold **, blank-line paras)
 *     sources: [{ kind, label, route }]     – canonical routes (optional)
 *     blocks:  [{ kind, title, rows: [{ k, v }] }]  – structured block(s)
 *     actions: [{ label, route }]           – contextual next-step chips
 *   }
 */

// -- Route helpers -------------------------------------------------
function currentRouteBucket() {
  const h = (typeof window !== 'undefined' && window.location.hash) || '';
  const seg = h.replace(/^#\/?/, '').split('/')[0];
  return seg || 'home';
}
function routeContextLabel() {
  const b = currentRouteBucket();
  const map = {
    home: 'Home',
    projects: 'Projects',
    'my-work': 'My Work',
    decisions: 'Decisions',
    inbox: 'Inbox',
    clients: 'Clients',
    settings: 'Settings',
    'design-system': 'Design system',
    contracts: 'Commercial',
    work: 'My Work',
  };
  return map[b] || 'MY GENI';
}
function routePlaceholder() {
  const b = currentRouteBucket();
  return {
    home:        'Ask about today\'s priorities…',
    projects:    'Ask about portfolio risk or momentum…',
    'my-work':   'Ask about your work, blockers, or waiting items…',
    decisions:   'Ask about a decision or its evidence…',
    inbox:       'Ask what needs action…',
    clients:     'Ask about the current illustrative engagement…',
    settings:    'Ask Geni about workspace context…',
    contracts:   'Ask about the illustrative engagement…',
    work:        'Ask about your work, blockers, or waiting items…',
  }[b] || 'Ask about attention, momentum, decisions…';
}
function routeCapability() {
  const b = currentRouteBucket();
  return {
    home:        'Geni sees inbox, work items, decisions, and momentum on this page.',
    projects:    'Geni sees the portfolio — status, risk, momentum across every project.',
    'my-work':   'Geni sees your work items, blockers, and what you\'re waiting on.',
    decisions:   'Geni sees the decision log and the evidence linked to each record.',
    inbox:       'Geni sees your inbox and knows which items are still waiting.',
    clients:     'Geni sees the illustrative Founding Design Partner engagement.',
    settings:    'Geni doesn\'t change your settings — but can explain them.',
    contracts:   'Geni sees the current illustrative engagement + linked documents.',
    work:        'Geni sees your work items, blockers, and what you\'re waiting on.',
  }[b] || 'Geni sees the canonical MY GENI data on this page.';
}

// -- Structured block renderer -------------------------------------
function GeniBlock({ block }) {
  if (!block) return null;
  return (
    <div className="mgviz-ai-block">
      {block.kind && <div className="mgviz-ai-eyebrow">{block.kind}</div>}
      {block.title && <div className="mgviz-ai-title">{block.title}</div>}
      {Array.isArray(block.rows) && block.rows.map((r, i) => (
        <div key={i} className="mgviz-ai-row">
          <span className="k">{r.k}</span>
          <span className="v">{r.v}</span>
        </div>
      ))}
    </div>
  );
}

// -- Message -------------------------------------------------------
function GeniMessage({ role, text, sources, blocks, actions }) {
  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>
        ))}
        {!!(blocks && blocks.length) && (
          <>{blocks.map((b, i) => <GeniBlock key={i} block={b} />)}</>
        )}
        {!!(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>
        )}
        {!!(actions && actions.length) && (
          <div className="geni-actions">
            {actions.map((a, i) => (
              <a key={i} className="geni-action" href={a.route} onClick={(e) => e.stopPropagation()}>
                <span>{a.label}</span>
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 12h14M13 5l7 7-7 7" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"/></svg>
              </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 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 || [],
        blocks: reply.blocks || [],
        actions: reply.actions || [],
      };
      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() : [];
  const ctxLabel = routeContextLabel();
  const capability = routeCapability();

  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">
              <span className="geni-ctx-crumb">Context · {ctxLabel}</span>
              <span className="geni-ctx-sep">·</span>
              <span className="geni-ctx-mock">local prototype</span>
            </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 className="geni-empty-cap">{capability}</div>
            <div className="geni-empty-prompts">
              {suggestions.slice(0, 4).map((s, i) => (
                <button key={i} className="geni-empty-prompt" onClick={() => send(s)}>
                  <span>{s}</span>
                  <svg width="11" height="11" viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 12h14M13 5l7 7-7 7" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"/></svg>
                </button>
              ))}
            </div>
          </div>
        )}
        {messages.map(m => (
          <GeniMessage
            key={m.id}
            role={m.role}
            text={m.text}
            sources={m.sources}
            blocks={m.blocks}
            actions={m.actions}
          />
        ))}
        {typing && (
          <div className="geni-msg geni-msg-ai geni-msg-thinking">
            <div className="geni-msg-mark" aria-hidden="true" />
            <div className="geni-msg-body">
              <span className="geni-thinking-line">Reviewing current context…</span>
            </div>
          </div>
        )}
      </div>

      {messages.length > 0 && (
        <div className="geni-suggestions">
          {suggestions.slice(0, 4).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={routePlaceholder()}
        />
        <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, GeniBlock, GeniMessage });
