// 1Radar Hybrid — V1 power features rebuilt in V3 visual language
// AI Rail (right panel), Cmd+K palette, Floating AI button, Selection bar

// ---- Shared chat utilities ----

const API_BASE = (window.APP_CONFIG && window.APP_CONFIG.API_BASE) || 'http://localhost:3001/api';
const CHAT_API = `${API_BASE}/chat`;

const apiFetch = async (path, method = 'GET', body = null) => {
  const token = localStorage.getItem('1radar_token');
  const opts = { method, headers: { 'Authorization': `Bearer ${token}` } };
  if (body) { opts.headers['Content-Type'] = 'application/json'; opts.body = JSON.stringify(body); }
  const res = await fetch(`${API_BASE}${path}`, opts);
  if (!res.ok) { const e = await res.json().catch(() => ({})); throw new Error(e.error || 'Request failed'); }
  return res.json();
};

// ---- Folder utilities ----
// System folders are virtual (not stored in DB).
const SYSTEM_FOLDERS = [
  { id: 'all',   name: 'All saved', icon: 'bookmark', system: true, count: 0 },
  { id: 'trash', name: 'Trash',     icon: 'trash',    system: true, count: 0 },
];

// Fetches user folders from API, merges with system folders,
// updates window.SAVE_FOLDERS_V3 and dispatches 'folders-updated'.
const loadFolders = async () => {
  try {
    const folders = await apiFetch('/folders');
    window.SAVE_FOLDERS_V3 = [...SYSTEM_FOLDERS, ...folders];
    window.dispatchEvent(new CustomEvent('folders-updated'));
  } catch {}
};

window.loadFolders = loadFolders;

// ---- Streams a chat completion. onChunk(text), onDone(), onError(msg) ----
const streamChat = async ({ messages, model = 'gemini', conversationId, attachments, onChunk, onDone, onError, signal }) => {
  const token = localStorage.getItem('1radar_token');
  let res;
  try {
    res = await fetch(`${CHAT_API}/completions`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
      body: JSON.stringify({ messages, model, conversation_id: conversationId, attachments, stream: true }),
      signal,
    });
  } catch (err) {
    if (err.name !== 'AbortError') onError('Cannot reach the backend.');
    return;
  }

  if (!res.ok) {
    const data = await res.json().catch(() => ({}));
    onError(data.error || 'Request failed');
    return;
  }

  const reader = res.body.getReader();
  const decoder = new TextDecoder();
  let buffer = '';

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    buffer += decoder.decode(value, { stream: true });
    const lines = buffer.split('\n');
    buffer = lines.pop();
    for (const line of lines) {
      if (!line.startsWith('data: ')) continue;
      const raw = line.slice(6).trim();
      if (raw === '[DONE]') { onDone(); return; }
      try {
        const chunk = JSON.parse(raw);
        const content = chunk.choices?.[0]?.delta?.content;
        if (content) onChunk(content);
      } catch {}
    }
  }
  onDone();
};

// Render message text: handles newlines + markdown images
const MsgContent = ({ text }) => {
  const parts = text.split(/(!\[.*?\]\(https?:\/\/[^\s)]+\))/g);
  return React.createElement('span', null,
    ...parts.map((part, i) => {
      const m = part.match(/!\[(.*?)\]\((https?:\/\/[^\s)]+)\)/);
      if (m) return React.createElement('img', {
        key: i, src: m[2], alt: m[1],
        style: { display: 'block', maxWidth: '100%', borderRadius: 10, marginTop: 8 },
      });
      return React.createElement('span', { key: i, style: { whiteSpace: 'pre-wrap' } }, part);
    })
  );
};

// ---- Floating AI Button (bottom-right) ----
const FloatingAI = ({ onClick, hidden }) => {
  if (hidden) return null;
  return (
    <button onClick={onClick} title="Ask Radar AI" style={{
      position: 'fixed', bottom: 24, right: 24, zIndex: 40,
      width: 56, height: 56, borderRadius: 999,
      background: 'linear-gradient(135deg, var(--accent), #6E8BFF)',
      color: '#fff',
      border: 'none',
      boxShadow: '0 14px 32px rgba(51,92,255,0.40), 0 1px 2px rgba(37,71,208,0.6), inset 0 0 0 1px rgba(255,255,255,0.18)',
      display: 'grid', placeItems: 'center',
      cursor: 'pointer',
      transition: 'transform .18s, box-shadow .18s',
    }}
    onMouseEnter={(e) => e.currentTarget.style.transform = 'translateY(-2px) scale(1.03)'}
    onMouseLeave={(e) => e.currentTarget.style.transform = 'none'}>
      <Icon name="sparkles" size={22}/>
      <span style={{
        position: 'absolute', top: -2, right: -2,
        width: 12, height: 12, borderRadius: 999,
        background: '#10B981',
        border: '2px solid var(--bg-app)',
      }}/>
    </button>
  );
};

// ---- AI Rail — right panel ----
const AIRailV3 = ({ open, onClose, context, onPin }) => {
  const WELCOME = "Hi — I'm Radar AI. I can analyze ads, summarize brand strategy, draft hooks or generate matching images. What are we working on?";
  const [messages, setMessages] = React.useState([{ role: 'assistant', text: WELCOME }]);
  const [input, setInput] = React.useState('');
  const [loading, setLoading] = React.useState(false);
  const scrollRef = React.useRef(null);
  const abortRef = React.useRef(null);

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

  // Inject context as new user message when it changes
  React.useEffect(() => {
    if (context) {
      setMessages([{ role: 'assistant', text: WELCOME }]);
    }
  }, [context]);

  const send = (override) => {
    const text = (override ?? input).trim();
    if (!text || loading) return;
    setInput('');
    setLoading(true);

    const userMsg = { role: 'user', text };
    const apiMessages = [...messages, userMsg]
      .filter(m => m.text)
      .map(m => ({ role: m.role, content: m.role === 'user' && context && messages.length <= 1
        ? `Context: ${context}\n\n${m.text}` : m.text }));

    setMessages(m => [...m, userMsg, { role: 'assistant', text: '' }]);

    const controller = new AbortController();
    abortRef.current = controller;

    streamChat({
      messages: apiMessages,
      signal: controller.signal,
      onChunk: (chunk) => {
        setMessages(m => {
          const next = [...m];
          next[next.length - 1] = { ...next[next.length - 1], text: next[next.length - 1].text + chunk };
          return next;
        });
      },
      onDone: () => setLoading(false),
      onError: (err) => {
        setMessages(m => {
          const next = [...m];
          next[next.length - 1] = { ...next[next.length - 1], text: `Error: ${err}` };
          return next;
        });
        setLoading(false);
      },
    });
  };

  if (!open) return null;
  return (
    <aside style={{
      width: 380, flexShrink: 0,
      display: 'flex', flexDirection: 'column',
      borderLeft: '1px solid var(--border)',
      background: 'var(--bg-surface)',
      height: '100vh',
      position: 'sticky', top: 0,
      zIndex: 9,
    }}>
      {/* Header */}
      <div style={{
        height: 'var(--header-h)',
        borderBottom: '1px solid var(--border)',
        padding: '0 18px',
        display: 'flex', alignItems: 'center', gap: 12,
        flexShrink: 0,
      }}>
        <div style={{
          width: 36, height: 36, borderRadius: 10,
          background: 'linear-gradient(135deg, var(--accent), #6E8BFF)',
          display: 'grid', placeItems: 'center',
          color: '#fff',
          boxShadow: '0 4px 12px rgba(51,92,255,0.30)',
        }}>
          <Icon name="sparkles" size={18}/>
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div className="font-display" style={{ fontWeight: 600, fontSize: 15 }}>Radar AI</div>
          <div style={{ fontSize: 12, color: 'var(--text-faint)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
            {context || 'Context: workspace'}
          </div>
        </div>
        <button onClick={onPin} className="btn btn-ghost btn-icon" title="Open full chat">
          <Icon name="expand" size={16}/>
        </button>
        <button onClick={onClose} className="btn btn-ghost btn-icon" title="Close">
          <Icon name="close" size={16}/>
        </button>
      </div>

      {/* Body */}
      <div ref={scrollRef} className="scroll" style={{
        flex: 1, overflowY: 'auto',
        padding: 18,
        display: 'flex', flexDirection: 'column', gap: 14,
      }}>
        {context && (
          <div style={{
            padding: '10px 12px',
            background: 'var(--accent-soft)',
            border: '1px solid var(--accent-soft)',
            borderRadius: 12,
            display: 'flex', alignItems: 'center', gap: 8,
            fontSize: 12, color: 'var(--accent)',
            fontWeight: 500,
          }}>
            <Icon name="pin" size={14}/>
            <span style={{ flex: 1 }}>{context}</span>
          </div>
        )}
        {messages.map((m, i) => {
          const isLast = i === messages.length - 1;
          const isStreaming = loading && isLast && m.role === 'assistant';
          return (
            <div key={i} style={{
              display: 'flex', gap: 10,
              alignSelf: m.role === 'user' ? 'flex-end' : 'flex-start',
              maxWidth: '92%',
            }}>
              {m.role === 'assistant' && (
                <div style={{
                  width: 24, height: 24, borderRadius: 7, flexShrink: 0,
                  background: 'linear-gradient(135deg, var(--accent), #6E8BFF)',
                  display: 'grid', placeItems: 'center', color: '#fff',
                  marginTop: 2,
                }}>
                  <Icon name="sparkles" size={11}/>
                </div>
              )}
              <div style={{
                padding: '10px 14px',
                borderRadius: 14,
                background: m.role === 'user' ? 'var(--accent)' : 'var(--bg-soft)',
                color: m.role === 'user' ? '#fff' : 'var(--text)',
                fontSize: 13, lineHeight: 1.55,
                borderBottomRightRadius: m.role === 'user' ? 4 : 14,
                borderBottomLeftRadius: m.role === 'assistant' ? 4 : 14,
                border: m.role === 'assistant' ? '1px solid var(--border)' : 'none',
              }}>
                {m.text ? <MsgContent text={m.text}/> : isStreaming
                  ? <span style={{ display: 'inline-flex', gap: 3, alignItems: 'center', height: 16 }}>
                      {[0,1,2].map(d => <span key={d} style={{ width: 5, height: 5, borderRadius: '50%', background: 'var(--text-faint)', animation: `pulse 1s ease-in-out ${d*0.2}s infinite` }}/>)}
                    </span>
                  : null}
              </div>
            </div>
          );
        })}
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 4 }}>
          {['Find similar ads', 'Draft 5 hook variations', 'Summarize this brand', 'Generate matching image'].map(s => (
            <button key={s} className="chip" style={{ height: 28, fontSize: 12 }}
                    onClick={() => send(s)}>
              <Icon name="sparkles" size={11} style={{ color: 'var(--accent)' }}/>{s}
            </button>
          ))}
        </div>
      </div>

      {/* Input */}
      <div style={{ padding: 14, borderTop: '1px solid var(--border)' }}>
        <div className="fld" style={{
          height: 'auto', minHeight: 44, padding: '8px 8px 8px 14px',
          borderRadius: 14, alignItems: 'flex-end',
        }}>
          <Icon name="sparkles" size={14} style={{ color: 'var(--accent)', marginBottom: 6 }}/>
          <textarea
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onKeyDown={(e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); }}}
            placeholder="Ask Radar AI…"
            rows={1}
            style={{
              flex: 1, border: 0, outline: 0, background: 'transparent',
              resize: 'none', padding: '4px 0', fontSize: 13, lineHeight: '20px',
              maxHeight: 140, fontFamily: 'inherit',
            }}/>
          <div style={{ display: 'flex', gap: 4 }}>
            <button className="btn btn-ghost btn-icon" style={{ width: 28, height: 28 }} title="Attach">
              <Icon name="attach" size={14}/>
            </button>
            <button onClick={() => send()} className="btn btn-icon" style={{
              width: 28, height: 28, background: 'var(--accent)', color: '#fff',
            }}>
              <Icon name="send" size={13}/>
            </button>
          </div>
        </div>
        <div style={{
          marginTop: 8, fontSize: 11, color: 'var(--text-faint)',
          display: 'flex', justifyContent: 'space-between',
        }}>
          <span>Haiku 4.5 · 1Radar context</span>
          <span><kbd style={kbdStyle}>↵</kbd> send · <kbd style={kbdStyle}>⇧↵</kbd> new line</span>
        </div>
      </div>
    </aside>
  );
};

const kbdStyle = {
  display: 'inline-grid', placeItems: 'center',
  minWidth: 16, height: 16, padding: '0 4px',
  borderRadius: 4,
  background: 'var(--bg-soft)',
  border: '1px solid var(--border)',
  fontSize: 10, color: 'var(--text-muted)',
  fontFamily: 'var(--font-mono)',
};

// ---- Cmd+K Command palette ----
const CmdKV3 = ({ open, onClose, onNav, onAskAI }) => {
  const [q, setQ] = React.useState('');
  const [hover, setHover] = React.useState(0);

  React.useEffect(() => {
    if (open) { setQ(''); setHover(0); }
  }, [open]);

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

  if (!open) return null;

  const groups = [
    { title: 'AI Actions', items: [
      { kind: 'ai', icon: 'sparkles', label: q ? `Ask AI: "${q}"` : 'Ask AI to analyze top 10 winners this week', action: () => { onAskAI && onAskAI(q || 'Analyze top 10 winners this week'); onClose(); } },
      { kind: 'ai', icon: 'image-ai', label: q ? `Generate image: "${q}"` : 'Generate image — lifestyle product shot', action: () => { onNav('image'); onClose(); } },
      { kind: 'ai', icon: 'mic',      label: 'Transcribe a video URL',                action: () => { onNav('transcribe'); onClose(); } },
    ]},
    { title: 'Navigate', items: [
      { kind: 'page', icon: 'home',     label: 'Home',         action: () => { onNav('home'); onClose(); } },
      { kind: 'page', icon: 'compass',  label: 'Explore Ads',  action: () => { onNav('explore'); onClose(); } },
      { kind: 'page', icon: 'building', label: 'Brands',       action: () => { onNav('brands'); onClose(); } },
      { kind: 'page', icon: 'bookmark', label: 'Saved Ads / Boards', action: () => { onNav('saved'); onClose(); } },
      { kind: 'page', icon: 'chat',     label: 'AI Chat',      action: () => { onNav('chat'); onClose(); } },
      { kind: 'page', icon: 'tools',    label: 'Tools hub',    action: () => { onNav('tools'); onClose(); } },
      { kind: 'page', icon: 'gamepad',  label: 'Winner or Loser game', action: () => { onNav('game'); onClose(); } },
      { kind: 'page', icon: 'gift',     label: 'Affiliate program',    action: () => { onNav('affiliate'); onClose(); } },
      { kind: 'page', icon: 'user',     label: 'Account',      action: () => { onNav('account'); onClose(); } },
    ]},
    { title: 'Tools', items: [
      { kind: 'tool', icon: 'wallet', label: 'ROAS / Break-even calculator', action: () => { onNav('tools'); onClose(); } },
      { kind: 'tool', icon: 'shop',   label: 'Detect Shopify apps on a URL…', action: () => { onNav('tools'); onClose(); } },
      { kind: 'tool', icon: 'flame',  label: 'Reddit pain-point extractor',   action: () => { onNav('tools'); onClose(); } },
      { kind: 'tool', icon: 'mic',    label: 'Video transcriber',             action: () => { onNav('transcribe'); onClose(); } },
    ]},
    { title: 'Recent', items: [
      { kind: 'recent', icon: 'clock', label: 'Glossier — running ads',           action: () => { onNav('brands'); onClose(); } },
      { kind: 'recent', icon: 'clock', label: 'AG1 morning routine creative',     action: () => { onNav('explore'); onClose(); } },
      { kind: 'recent', icon: 'clock', label: 'Q4 winners board',                 action: () => { onNav('saved'); onClose(); } },
    ]},
  ];

  // flat filter
  const filtered = groups.map(g => ({
    ...g,
    items: g.items.filter(it => !q || it.label.toLowerCase().includes(q.toLowerCase())),
  })).filter(g => g.items.length);

  const flat = filtered.flatMap(g => g.items);

  return (
    <div onClick={onClose} style={{
      position: 'fixed', inset: 0, zIndex: 200,
      background: 'rgba(14,18,27,0.45)',
      backdropFilter: 'blur(8px)',
      display: 'flex', justifyContent: 'center', paddingTop: '12vh',
    }}>
      <div onClick={(e) => e.stopPropagation()} style={{
        width: 640, maxHeight: '70vh',
        display: 'flex', flexDirection: 'column',
        borderRadius: 16, overflow: 'hidden',
        background: 'var(--bg-surface)',
        border: '1px solid var(--border)',
        boxShadow: '0 30px 80px rgba(14,18,27,0.30)',
      }}>
        {/* Search */}
        <div style={{
          padding: '14px 18px',
          display: 'flex', alignItems: 'center', gap: 12,
          borderBottom: '1px solid var(--border)',
        }}>
          <Icon name="search" size={18} style={{ color: 'var(--text-faint)' }}/>
          <input autoFocus value={q} onChange={(e) => setQ(e.target.value)}
                 placeholder="Search ads, brands, tools — or ask AI…"
                 style={{
                   flex: 1, border: 0, outline: 0, background: 'transparent',
                   fontSize: 15, color: 'var(--text)',
                 }}/>
          <kbd style={kbdStyle}>esc</kbd>
        </div>

        <div style={{ flex: 1, overflowY: 'auto', padding: 8 }} className="scroll">
          {filtered.length === 0 && (
            <div style={{ padding: '32px 16px', textAlign: 'center', color: 'var(--text-faint)', fontSize: 13 }}>
              No results for "{q}".
            </div>
          )}
          {filtered.map((g) => (
            <div key={g.title} style={{ marginBottom: 6 }}>
              <div style={{
                fontSize: 11, color: 'var(--text-faint)', fontWeight: 600,
                padding: '8px 12px 4px', textTransform: 'uppercase', letterSpacing: 0.04,
              }}>{g.title}</div>
              {g.items.map((it, i) => {
                const idx = flat.indexOf(it);
                const isHover = idx === hover;
                return (
                  <button key={i} onClick={it.action}
                    onMouseEnter={() => setHover(idx)}
                    style={{
                      width: '100%', display: 'flex', alignItems: 'center', gap: 12,
                      padding: '10px 12px', borderRadius: 10,
                      background: isHover ? 'var(--bg-soft)' : 'transparent',
                      textAlign: 'left',
                      fontSize: 13, color: 'var(--text)',
                      cursor: 'pointer',
                    }}>
                    <div style={{
                      width: 28, height: 28, borderRadius: 8,
                      background: it.kind === 'ai' ? 'var(--accent-soft)' : 'var(--bg-soft)',
                      color: it.kind === 'ai' ? 'var(--accent)' : 'var(--text-muted)',
                      display: 'grid', placeItems: 'center',
                    }}>
                      <Icon name={it.icon} size={14}/>
                    </div>
                    <span style={{ flex: 1 }}>{it.label}</span>
                    {isHover && <Icon name="kbd-return" size={14} style={{ color: 'var(--text-faint)' }}/>}
                  </button>
                );
              })}
            </div>
          ))}
        </div>

        <div style={{
          padding: '10px 16px',
          borderTop: '1px solid var(--border)',
          display: 'flex', gap: 14, fontSize: 11, color: 'var(--text-faint)',
        }}>
          <span><kbd style={kbdStyle}>↑↓</kbd> navigate</span>
          <span><kbd style={kbdStyle}>↵</kbd> open</span>
          <span style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 4 }}>
            <Icon name="sparkles" size={11} style={{ color: 'var(--accent)' }}/>
            Ask AI from anywhere
          </span>
        </div>
      </div>
    </div>
  );
};

// ---- Multi-select selection bar (bottom center) ----
const SelectionBarV3 = ({ count, onClear, onAskAI, onSave, onExport }) => {
  if (!count) return null;
  return (
    <div style={{
      position: 'fixed', bottom: 24, left: '50%',
      transform: 'translateX(-50%)',
      zIndex: 38,
      display: 'flex', alignItems: 'center', gap: 8,
      padding: '6px 6px 6px 16px',
      background: 'var(--text)', color: '#fff',
      borderRadius: 999,
      boxShadow: '0 18px 36px rgba(14,18,27,0.30), 0 1px 2px rgba(0,0,0,0.2)',
      animation: 'rise .22s ease',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <div style={{
          width: 22, height: 22, borderRadius: 999,
          background: 'var(--accent)',
          display: 'grid', placeItems: 'center',
          fontSize: 11, fontWeight: 600,
        }}>{count}</div>
        <span style={{ fontSize: 13, fontWeight: 500 }}>selected</span>
      </div>
      <span style={{ width: 1, height: 20, background: 'rgba(255,255,255,0.16)', margin: '0 4px' }}/>
      <button onClick={onAskAI} className="btn btn-sm" style={{
        background: 'rgba(51,92,255,0.20)', color: '#cdd5ff', height: 30,
      }}>
        <Icon name="sparkles" size={13}/> Ask AI
      </button>
      <button onClick={onSave} className="btn btn-sm" style={{
        background: 'rgba(255,255,255,0.10)', color: '#fff', height: 30,
      }}>
        <Icon name="bookmark" size={13}/> Save to board
      </button>
      <button onClick={onExport} className="btn btn-sm" style={{
        background: 'rgba(255,255,255,0.10)', color: '#fff', height: 30,
      }}>
        <Icon name="export" size={13}/> Export
      </button>
      <button onClick={onClear} className="btn btn-icon" style={{
        width: 30, height: 30, background: 'rgba(255,255,255,0.06)', color: '#fff',
      }}>
        <Icon name="close" size={14}/>
      </button>
    </div>
  );
};

Object.assign(window, { FloatingAI, AIRailV3, CmdKV3, SelectionBarV3 });
