// Primus IQ — Minimalist tagging modal
// Triggered after files land via "Add sources".
// Layout: file queue on the LEFT, tag panel on the RIGHT, single "Save" CTA.

const SAMPLE_DROPPED = [
  { id: 'd1',  name: 'GCC_Market_Sizing_v4.pptx',     size: '12.0 MB', ext: 'pptx', suggest: 'strict',   pages: 28, tags: ['GCC', 'Sizing'] },
  { id: 'd2',  name: 'Acme_Financial_Model.xlsx',     size: '4.2 MB',  ext: 'xlsx', suggest: 'strict',   pages: 12, tags: ['Acme', 'Finance'] },
  { id: 'd3',  name: 'IndustryReport_Q4.pdf',         size: '8.6 MB',  ext: 'pdf',  suggest: 'public',   pages: 64, tags: ['Research'] },
  { id: 'd4',  name: 'Interview_Notes_CFO.docx',      size: '120 KB',  ext: 'docx', suggest: 'client',   pages: 4,  tags: ['Acme', 'Interview'] },
  { id: 'd5',  name: 'ESG_Compliance_Brief.pdf',      size: '2.1 MB',  ext: 'pdf',  suggest: 'internal', pages: 18, tags: ['ESG'] },
  { id: 'd6',  name: 'Pitch_Storyline_draft.pptx',    size: '6.8 MB',  ext: 'pptx', suggest: 'internal', pages: 22, tags: ['Pitch'] },
  { id: 'd7',  name: 'Supply_chain_diagram.png',      size: '880 KB',  ext: 'png',  suggest: 'internal', pages: 1,  tags: ['Diagram'] },
  { id: 'd8',  name: 'Bid_Cost_Calculator.xlsx',      size: '1.4 MB',  ext: 'xlsx', suggest: 'strict',   pages: 8,  tags: ['RFP'] },
  { id: 'd9',  name: 'Client_brief_v2.docx',          size: '340 KB',  ext: 'docx', suggest: 'client',   pages: 6,  tags: ['Acme', 'Brief'] },
  { id: 'd10', name: 'Site_visit_video.mp4',          size: '48.2 MB', ext: 'mp4',  suggest: 'internal', pages: 0,  tags: ['Field'] },
];

const CONF_OPTIONS = [
  { id: 'public',   label: 'Public',   desc: 'Anyone in firm' },
  { id: 'internal', label: 'Internal', desc: 'Logged-in users' },
  { id: 'client',   label: 'Client',   desc: 'Project members' },
  { id: 'strict',   label: 'Strict',   desc: 'Named ACL only' },
];

const SUGGESTED_TAGS = ['GCC', 'KSA', 'UAE', 'Fintech', 'Climate', 'Policy', 'Healthcare', 'TCFD', 'CSRD', 'Acme', 'Globex'];

const TaggingModal = ({ open, onClose, onCommit, pendingFiles = [] }) => {
  const [files, setFiles] = React.useState([]);
  const [active, setActive] = React.useState(0);
  const [tagInput, setTagInput] = React.useState('');

  React.useEffect(() => {
    if (open) {
      // Use real files when provided; fall back to sample only for demo/empty state
      setFiles(pendingFiles.length > 0
        ? pendingFiles
        : SAMPLE_DROPPED.map(f => ({ ...f, conf: f.suggest })));
      setActive(0);
      setTagInput('');
    }
  }, [open, pendingFiles]);

  const f = files[active];

  const updateFile = (idx, patch) => {
    setFiles(prev => prev.map((file, i) => i === idx ? { ...file, ...patch } : file));
  };
  const addTag = (t) => {
    const tag = t.trim();
    if (!tag) return;
    if (f.tags.includes(tag)) return;
    updateFile(active, { tags: [...f.tags, tag] });
    setTagInput('');
  };
  const removeTag = (t) => updateFile(active, { tags: f.tags.filter(x => x !== t) });
  const applyAllConf = (confId) => setFiles(prev => prev.map(file => ({ ...file, conf: confId })));

  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === 'Escape') onClose();
      if (e.key === 'ArrowDown') setActive(a => Math.min(a + 1, files.length - 1));
      if (e.key === 'ArrowUp')   setActive(a => Math.max(a - 1, 0));
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, files]);

  if (!open) return null;

  // Guard: nothing to tag yet
  if (files.length === 0) return (
    <div onClick={onClose} style={{
      position: 'absolute', inset: 0, zIndex: 60,
      background: 'rgba(26,22,20,0.42)', backdropFilter: 'blur(4px)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      <div onClick={e => e.stopPropagation()} style={{
        padding: '40px 48px', background: 'var(--bg-card)', borderRadius: 18,
        boxShadow: '0 30px 80px rgba(26,22,20,0.30)', textAlign: 'center',
      }}>
        <div style={{ fontSize: 32, marginBottom: 12 }}>📂</div>
        <div className="t-h3" style={{ marginBottom: 8 }}>No files selected</div>
        <div style={{ fontSize: 13, color: 'var(--mute)', marginBottom: 20 }}>Drop files on the zone or use the Upload button.</div>
        <button className="btn-secondary" onClick={onClose}>Close</button>
      </div>
    </div>
  );

  const tagged = files.filter(x => x.conf).length;

  return (
    <div onClick={onClose} style={{
      position: 'absolute', inset: 0, zIndex: 60,
      background: 'rgba(26,22,20,0.42)', backdropFilter: 'blur(4px)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      animation: 'fadein 0.18s ease-out',
    }}>
      <div onClick={e => e.stopPropagation()} style={{
        width: 1040, maxWidth: '94%', height: 640, maxHeight: '92%',
        background: 'var(--bg-card)', borderRadius: 18,
        boxShadow: '0 30px 80px rgba(26,22,20,0.30), 0 0 0 1px var(--line)',
        animation: 'rise 0.22s ease-out',
        display: 'flex', flexDirection: 'column', overflow: 'hidden',
      }}>
        {/* Header */}
        <div style={{
          padding: '18px 24px', display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          borderBottom: '1px solid var(--line)',
        }}>
          <div>
            <h2 className="serif" style={{ fontSize: 18, fontWeight: 500, margin: 0, letterSpacing: '-0.01em' }}>Tag your files</h2>
            <div style={{ fontSize: 13, color: 'var(--mute)', marginTop: 3 }}>
              {files.length} files · pick visibility and add tags · {tagged}/{files.length} ready
            </div>
          </div>
          <button onClick={onClose} style={{
            width: 30, height: 30, borderRadius: 8, background: 'transparent', border: 'none',
            cursor: 'pointer', display: 'grid', placeItems: 'center', color: 'var(--mute)',
          }}>
            <svg width="14" height="14" viewBox="0 0 14 14"><path d="M2 2l10 10M12 2L2 12" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>
          </button>
        </div>

        {/* Body */}
        <div style={{ display: 'grid', gridTemplateColumns: '320px 1fr', flex: 1, minHeight: 0 }}>
          {/* LEFT — file queue */}
          <div style={{
            borderRight: '1px solid var(--line)', background: 'var(--bg-soft)',
            display: 'flex', flexDirection: 'column', minHeight: 0,
          }}>
            <div style={{ padding: '12px 14px', borderBottom: '1px solid var(--line)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
              <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--mute)', letterSpacing: '0.08em', textTransform: 'uppercase' }}>Files</span>
              <span style={{ fontSize: 11, color: 'var(--mute)' }}>{active + 1} / {files.length}</span>
            </div>
            <div style={{ flex: 1, overflow: 'auto', padding: 8, display: 'flex', flexDirection: 'column', gap: 4 }}>
              {files.map((file, i) => {
                const isActive = i === active;
                return (
                  <div key={file.id} onClick={() => setActive(i)} style={{
                    padding: 10, borderRadius: 9, cursor: 'pointer',
                    background: isActive ? 'white' : 'transparent',
                    border: isActive ? '1px solid var(--maroon-20)' : '1px solid transparent',
                    boxShadow: isActive ? '0 2px 8px rgba(60,30,20,0.06)' : 'none',
                    display: 'flex', alignItems: 'center', gap: 10,
                    transition: 'all 0.12s',
                  }}>
                    <FileBadge ext={file.ext} />
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--ink)',
                                    whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{file.name}</div>
                      <div style={{ fontSize: 10, color: 'var(--mute)', marginTop: 2, display: 'flex', alignItems: 'center', gap: 6 }}>
                        <span>{file.size}</span>
                        {file.conf && <span className={`conf ${file.conf}`} style={{ padding: '1px 5px', fontSize: 9 }}>{file.conf}</span>}
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>

          {/* RIGHT — tag panel */}
          <div style={{ display: 'flex', flexDirection: 'column', overflow: 'auto' }}>
            <div style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 22, flex: 1, minHeight: 0 }}>
              {/* File header */}
              <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
                <FileBadge ext={f.ext} size="lg" />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{
                    fontSize: 18, fontWeight: 600, color: 'var(--ink)',
                    whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                  }}>{f.name}</div>
                  <div style={{ fontSize: 12, color: 'var(--mute)', marginTop: 4, display: 'flex', gap: 10 }}>
                    <span>{f.size}</span>
                    {f.pages > 0 && <span>· {f.pages} pages</span>}
                    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, color: 'var(--gold)', fontWeight: 600 }}>
                      <svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><path d="M5 1l1.18 2.4L8.83 3.78l-1.92 1.87.45 2.65L5 7.05 2.64 8.3l.45-2.65L1.17 3.78l2.65-.38L5 1z"/></svg>
                      Suggested: {f.suggest}
                    </span>
                  </div>
                </div>
              </div>

              {/* Visibility */}
              <div>
                <div style={sectionLabel}>
                  Visibility
                  <button onClick={() => applyAllConf(f.conf)} style={miniBtn}>Apply to all</button>
                </div>
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8 }}>
                  {CONF_OPTIONS.map(opt => {
                    const sel = f.conf === opt.id;
                    return (
                      <button key={opt.id} onClick={() => updateFile(active, { conf: opt.id })} style={{
                        padding: '10px 12px', borderRadius: 10, textAlign: 'left',
                        background: sel ? 'var(--ink)' : 'white',
                        color: sel ? 'white' : 'var(--ink)',
                        border: sel ? '1px solid var(--ink)' : '1px solid var(--line-2)',
                        cursor: 'pointer', fontFamily: 'inherit',
                        display: 'flex', flexDirection: 'column', gap: 4,
                        transition: 'all 0.12s',
                      }}>
                        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                          <span style={{ fontSize: 13, fontWeight: 600 }}>{opt.label}</span>
                          {sel && (
                            <svg width="12" height="12" viewBox="0 0 12 12">
                              <path d="M2 6.5l2.5 2.5L10 3.5" stroke="white" fill="none" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
                            </svg>
                          )}
                        </div>
                        <span style={{ fontSize: 11, opacity: sel ? 0.75 : 0.55 }}>{opt.desc}</span>
                      </button>
                    );
                  })}
                </div>
              </div>

              {/* Tags */}
              <div>
                <div style={sectionLabel}>Tags</div>
                <div style={{
                  padding: '8px 10px', borderRadius: 10,
                  border: '1px solid var(--line-2)', background: 'white',
                  display: 'flex', flexWrap: 'wrap', gap: 6, alignItems: 'center',
                  minHeight: 44,
                }}>
                  {f.tags.map(t => (
                    <span key={t} style={chipTagStyle}>
                      {t}
                      <button onClick={() => removeTag(t)} style={chipRemoveBtn}>
                        <svg width="9" height="9" viewBox="0 0 9 9"><path d="M2 2l5 5M7 2L2 7" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/></svg>
                      </button>
                    </span>
                  ))}
                  <input
                    value={tagInput}
                    onChange={e => setTagInput(e.target.value)}
                    onKeyDown={e => {
                      if (e.key === 'Enter') { e.preventDefault(); addTag(tagInput); }
                      if (e.key === 'Backspace' && !tagInput && f.tags.length > 0) removeTag(f.tags[f.tags.length - 1]);
                    }}
                    placeholder={f.tags.length === 0 ? 'Add a tag…' : ''}
                    style={{
                      flex: 1, minWidth: 100, border: 'none', outline: 'none',
                      fontSize: 13, fontFamily: 'inherit', color: 'var(--ink)', background: 'transparent',
                      padding: '4px 2px',
                    }}
                  />
                </div>
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 10 }}>
                  <span style={{ fontSize: 11, color: 'var(--mute)', padding: '4px 4px 4px 0' }}>Suggested:</span>
                  {SUGGESTED_TAGS.filter(t => !f.tags.includes(t)).slice(0, 7).map(t => (
                    <button key={t} onClick={() => addTag(t)} style={suggestedTagBtn}>+ {t}</button>
                  ))}
                </div>
              </div>

              <div style={{ flex: 1 }} />

              {/* Footer banner */}
              <div style={{
                padding: '10px 12px', borderRadius: 9,
                background: 'var(--maroon-wash)', border: '1px solid var(--maroon-10)',
                fontSize: 12, color: 'var(--ink-2)', lineHeight: 1.5,
              }}>
                <strong style={{ color: 'var(--maroon)' }}>Tip:</strong> {' '}
                Use <kbd style={kbdStyle}>↑</kbd> <kbd style={kbdStyle}>↓</kbd> to move between files, <kbd style={kbdStyle}>Enter</kbd> to add a tag.
              </div>
            </div>

            {/* Footer */}
            <div style={{
              padding: '14px 24px', borderTop: '1px solid var(--line)',
              display: 'flex', alignItems: 'center', justifyContent: 'space-between',
              background: 'var(--bg-card)',
            }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <button onClick={() => setActive(Math.max(0, active - 1))} disabled={active === 0} style={navBtn}>← Prev</button>
                <button onClick={() => setActive(Math.min(files.length - 1, active + 1))} disabled={active === files.length - 1} style={navBtn}>Next →</button>
              </div>
              <div style={{ display: 'flex', gap: 8 }}>
                <button onClick={onClose} className="btn-secondary" style={{ height: 36 }}>Cancel</button>
                <button onClick={() => onCommit(files)} className="btn-primary" style={{ height: 36 }}>
                  Save {files.length} files
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

const sectionLabel = {
  display: 'flex', alignItems: 'center', justifyContent: 'space-between',
  fontSize: 10, fontWeight: 700, color: 'var(--mute)',
  letterSpacing: '0.08em', textTransform: 'uppercase',
  marginBottom: 8,
};
const miniBtn = {
  background: 'none', border: 'none', cursor: 'pointer',
  fontSize: 11, color: 'var(--maroon)', fontFamily: 'inherit', fontWeight: 600,
  textTransform: 'none', letterSpacing: 0,
};
const chipTagStyle = {
  display: 'inline-flex', alignItems: 'center', gap: 6,
  padding: '4px 4px 4px 10px', borderRadius: 6,
  background: 'var(--maroon-06)', color: 'var(--maroon)',
  fontSize: 12, fontWeight: 500, fontFamily: 'inherit',
};
const chipRemoveBtn = {
  width: 16, height: 16, borderRadius: 4, border: 'none', cursor: 'pointer',
  background: 'transparent', color: 'var(--maroon)',
  display: 'grid', placeItems: 'center',
};
const suggestedTagBtn = {
  padding: '4px 10px', borderRadius: 999,
  background: 'white', border: '1px dashed var(--line-2)',
  fontSize: 11, color: 'var(--mute)', fontFamily: 'inherit', cursor: 'pointer',
};
const navBtn = {
  height: 32, padding: '0 12px', borderRadius: 7,
  background: 'transparent', border: '1px solid var(--line-2)',
  fontSize: 12, fontFamily: 'inherit', color: 'var(--ink-2)', cursor: 'pointer',
};
const kbdStyle = {
  display: 'inline-block', padding: '1px 6px', borderRadius: 4,
  background: 'white', border: '1px solid var(--line-2)',
  fontSize: 10, fontFamily: 'ui-monospace, monospace', color: 'var(--ink)',
};

// ─────────────────────────────────────────────────────────────────────────────
// SharePoint / OneDrive picker — cascading source → library → file browse.
// On confirm, returns selected files shaped for TaggingModal (sharepoint metadata,
// no fileObject). The backend downloads each file from Graph and stores it in GCS.
// ─────────────────────────────────────────────────────────────────────────────

const spFmtSize = (bytes) => {
  const b = bytes || 0;
  return b < 1024 ? `${b} B`
       : b < 1048576 ? `${(b / 1024).toFixed(1)} KB`
       : `${(b / 1048576).toFixed(1)} MB`;
};

const SharePointPickerModal = ({ open, onClose, onConfirm }) => {
  const [tab, setTab] = React.useState('onedrive');     // 'onedrive' | 'sharepoint'
  const [siteQuery, setSiteQuery] = React.useState('');
  const [sites, setSites] = React.useState([]);
  const [selectedSite, setSelectedSite] = React.useState(null);
  const [drives, setDrives] = React.useState([]);
  const [drive, setDrive] = React.useState(null);        // active drive being browsed
  const [path, setPath] = React.useState([]);            // breadcrumb: [{id, name}]
  const [items, setItems] = React.useState([]);
  const [selected, setSelected] = React.useState({});    // itemId -> {drive_id, item_id, name, size}
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState('');

  const reset = () => {
    setTab('onedrive'); setSiteQuery(''); setSites([]); setSelectedSite(null);
    setDrives([]); setDrive(null); setPath([]); setItems([]); setSelected({});
    setLoading(false); setError('');
  };

  React.useEffect(() => { if (open) reset(); }, [open]);

  const fail = (ex) => { setError(ex && ex.message ? ex.message : 'Something went wrong'); setLoading(false); };

  // ── OneDrive: open the user's drive directly ──
  const openOneDrive = async () => {
    setTab('onedrive'); setSelectedSite(null); setDrives([]); setError('');
    setLoading(true);
    try {
      const d = await PrimusAPI.spOneDrive();
      setDrive(d);
      setPath([{ id: null, name: d.name || 'OneDrive' }]);
      const its = await PrimusAPI.spListItems(d.id, null);
      setItems(its || []); setLoading(false);
    } catch (ex) { fail(ex); }
  };

  // ── SharePoint: search sites ──
  const runSiteSearch = async () => {
    setLoading(true); setError('');
    try {
      const res = await PrimusAPI.spSearchSites(siteQuery);
      setSites(res || []); setLoading(false);
    } catch (ex) { fail(ex); }
  };

  const pickSite = async (site) => {
    setSelectedSite(site); setDrive(null); setPath([]); setItems([]); setError('');
    setLoading(true);
    try {
      const ds = await PrimusAPI.spListDrives(site.id);
      setDrives(ds || []); setLoading(false);
    } catch (ex) { fail(ex); }
  };

  const pickDrive = async (d) => {
    setDrive(d); setPath([{ id: null, name: d.name }]); setError('');
    setLoading(true);
    try {
      const its = await PrimusAPI.spListItems(d.id, null);
      setItems(its || []); setLoading(false);
    } catch (ex) { fail(ex); }
  };

  const openFolder = async (folder) => {
    setError(''); setLoading(true);
    try {
      const its = await PrimusAPI.spListItems(drive.id, folder.id);
      setPath(prev => [...prev, { id: folder.id, name: folder.name }]);
      setItems(its || []); setLoading(false);
    } catch (ex) { fail(ex); }
  };

  const goToCrumb = async (idx) => {
    const crumb = path[idx];
    setError(''); setLoading(true);
    try {
      const its = await PrimusAPI.spListItems(drive.id, crumb.id);
      setPath(prev => prev.slice(0, idx + 1));
      setItems(its || []); setLoading(false);
    } catch (ex) { fail(ex); }
  };

  const toggleFile = (item) => {
    setSelected(prev => {
      const next = { ...prev };
      if (next[item.id]) delete next[item.id];
      else next[item.id] = { drive_id: drive.id, item_id: item.id, name: item.name, size: item.size };
      return next;
    });
  };

  const selectedList = Object.values(selected);

  const confirm = () => {
    if (selectedList.length === 0) return;
    onConfirm(selectedList);
  };

  if (!open) return null;

  const showBrowser = !!drive;
  const showSiteList = tab === 'sharepoint' && !selectedSite;
  const showDriveList = tab === 'sharepoint' && selectedSite && !drive;

  return (
    <div onClick={onClose} style={{
      position: 'absolute', inset: 0, zIndex: 70,
      background: 'rgba(26,22,20,0.42)', backdropFilter: 'blur(4px)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      animation: 'fadein 0.18s ease-out',
    }}>
      <div onClick={e => e.stopPropagation()} style={{
        width: 920, maxWidth: '94%', height: 620, maxHeight: '92%',
        background: 'var(--bg-card)', borderRadius: 18,
        boxShadow: '0 30px 80px rgba(26,22,20,0.30), 0 0 0 1px var(--line)',
        animation: 'rise 0.22s ease-out',
        display: 'flex', flexDirection: 'column', overflow: 'hidden',
      }}>
        {/* Header */}
        <div style={{
          padding: '18px 24px', display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          borderBottom: '1px solid var(--line)',
        }}>
          <div>
            <h2 className="serif" style={{ fontSize: 18, fontWeight: 500, margin: 0, letterSpacing: '-0.01em' }}>Add from Microsoft 365</h2>
            <div style={{ fontSize: 13, color: 'var(--mute)', marginTop: 3 }}>
              Browse your OneDrive or SharePoint and pick files to import.
            </div>
          </div>
          <button onClick={onClose} style={{
            width: 30, height: 30, borderRadius: 8, background: 'transparent', border: 'none',
            cursor: 'pointer', display: 'grid', placeItems: 'center', color: 'var(--mute)',
          }}>
            <svg width="14" height="14" viewBox="0 0 14 14"><path d="M2 2l10 10M12 2L2 12" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>
          </button>
        </div>

        {/* Source tabs */}
        <div style={{ display: 'flex', gap: 8, padding: '12px 24px 0' }}>
          <button onClick={openOneDrive} style={spTabStyle(tab === 'onedrive')}>OneDrive</button>
          <button onClick={() => { setTab('sharepoint'); setDrive(null); setSelectedSite(null); }} style={spTabStyle(tab === 'sharepoint')}>SharePoint sites</button>
        </div>

        {/* Body */}
        <div style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', padding: '14px 24px' }}>
          {/* Site search */}
          {showSiteList && (
            <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>
              <input
                value={siteQuery}
                onChange={e => setSiteQuery(e.target.value)}
                onKeyDown={e => { if (e.key === 'Enter') runSiteSearch(); }}
                placeholder="Search SharePoint sites by name…"
                style={{
                  flex: 1, height: 38, padding: '0 12px', borderRadius: 9,
                  border: '1px solid var(--line-2)', fontSize: 13, fontFamily: 'inherit',
                  outline: 'none', color: 'var(--ink)', background: 'white',
                }}
              />
              <button onClick={runSiteSearch} className="btn-primary" style={{ height: 38 }}>Search</button>
            </div>
          )}

          {/* Breadcrumbs when browsing */}
          {showBrowser && (
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap', marginBottom: 12, fontSize: 13 }}>
              {selectedSite && (
                <>
                  <button onClick={() => { setDrive(null); setItems([]); setPath([]); }} style={spCrumbBtn}>{selectedSite.display_name}</button>
                  <span style={{ color: 'var(--mute-2)' }}>/</span>
                </>
              )}
              {path.map((c, i) => (
                <React.Fragment key={`${c.id || 'root'}-${i}`}>
                  {i > 0 && <span style={{ color: 'var(--mute-2)' }}>/</span>}
                  <button onClick={() => goToCrumb(i)} style={{ ...spCrumbBtn, color: i === path.length - 1 ? 'var(--ink)' : 'var(--maroon)', fontWeight: i === path.length - 1 ? 600 : 500 }}>{c.name}</button>
                </React.Fragment>
              ))}
            </div>
          )}

          {error && (
            <div style={{ padding: '10px 12px', borderRadius: 9, background: 'var(--maroon-wash)', border: '1px solid var(--maroon-10)', color: 'var(--maroon)', fontSize: 12, marginBottom: 12 }}>
              {error}
            </div>
          )}

          {/* List area */}
          <div style={{ flex: 1, overflow: 'auto', border: '1px solid var(--line)', borderRadius: 12, background: 'white' }}>
            {loading && <div style={spEmpty}>Loading…</div>}

            {/* Site results */}
            {!loading && showSiteList && sites.length === 0 && <div style={spEmpty}>Search for a site to begin.</div>}
            {!loading && showSiteList && sites.map(s => (
              <div key={s.id} onClick={() => pickSite(s)} style={spRow}>
                <SpIcon kind="site" />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={spName}>{s.display_name}</div>
                  {s.web_url && <div style={spSub}>{s.web_url}</div>}
                </div>
                <span style={{ color: 'var(--mute-2)' }}>›</span>
              </div>
            ))}

            {/* Drive (library) list */}
            {!loading && showDriveList && drives.length === 0 && <div style={spEmpty}>No document libraries on this site.</div>}
            {!loading && showDriveList && drives.map(d => (
              <div key={d.id} onClick={() => pickDrive(d)} style={spRow}>
                <SpIcon kind="library" />
                <div style={{ flex: 1, minWidth: 0 }}><div style={spName}>{d.name}</div></div>
                <span style={{ color: 'var(--mute-2)' }}>›</span>
              </div>
            ))}

            {/* File / folder browser */}
            {!loading && showBrowser && items.length === 0 && <div style={spEmpty}>This folder is empty.</div>}
            {!loading && showBrowser && items.map(it => {
              const checked = !!selected[it.id];
              if (it.is_folder) {
                return (
                  <div key={it.id} onClick={() => openFolder(it)} style={spRow}>
                    <SpIcon kind="folder" />
                    <div style={{ flex: 1, minWidth: 0 }}><div style={spName}>{it.name}</div></div>
                    <span style={{ color: 'var(--mute-2)' }}>›</span>
                  </div>
                );
              }
              return (
                <div key={it.id} onClick={() => toggleFile(it)} style={{ ...spRow, background: checked ? 'var(--maroon-06)' : 'transparent' }}>
                  <div style={{
                    width: 18, height: 18, borderRadius: 5, flexShrink: 0,
                    border: `1.5px solid ${checked ? 'var(--maroon)' : 'var(--line-2)'}`,
                    background: checked ? 'var(--maroon)' : 'white',
                    display: 'grid', placeItems: 'center',
                  }}>
                    {checked && <svg width="11" height="11" viewBox="0 0 12 12"><path d="M2 6.5l2.5 2.5L10 3.5" stroke="white" fill="none" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>}
                  </div>
                  <SpIcon kind="file" />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={spName}>{it.name}</div>
                    <div style={spSub}>{spFmtSize(it.size)}</div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        {/* Footer */}
        <div style={{
          padding: '14px 24px', borderTop: '1px solid var(--line)',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between', background: 'var(--bg-card)',
        }}>
          <span style={{ fontSize: 13, color: 'var(--mute)' }}>
            {selectedList.length > 0 ? `${selectedList.length} file${selectedList.length > 1 ? 's' : ''} selected` : 'No files selected'}
          </span>
          <div style={{ display: 'flex', gap: 8 }}>
            <button onClick={onClose} className="btn-secondary" style={{ height: 36 }}>Cancel</button>
            <button onClick={confirm} disabled={selectedList.length === 0} className="btn-primary" style={{ height: 36, opacity: selectedList.length === 0 ? 0.5 : 1 }}>
              Add {selectedList.length || ''} file{selectedList.length === 1 ? '' : 's'}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

const SpIcon = ({ kind }) => {
  const color = kind === 'site' ? 'var(--maroon)' : kind === 'library' ? 'var(--gold)' : kind === 'folder' ? 'var(--gold)' : 'var(--mute)';
  const paths = {
    site:    <path d="M3 21V7l9-4 9 4v14M3 21h18M9 21v-6h6v6" stroke={color} strokeWidth="1.6" fill="none" strokeLinejoin="round"/>,
    library: <path d="M4 5h16v14H4zM4 9h16M9 5v14" stroke={color} strokeWidth="1.6" fill="none" strokeLinejoin="round"/>,
    folder:  <path d="M3 6a1 1 0 0 1 1-1h5l2 2h8a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1z" stroke={color} strokeWidth="1.6" fill="none" strokeLinejoin="round"/>,
    file:    <path d="M6 2h8l4 4v16H6zM14 2v4h4" stroke={color} strokeWidth="1.6" fill="none" strokeLinejoin="round"/>,
  };
  return <svg width="20" height="20" viewBox="0 0 24 24" style={{ flexShrink: 0 }}>{paths[kind]}</svg>;
};

const spTabStyle = (active) => ({
  height: 34, padding: '0 16px', borderRadius: '9px 9px 0 0', cursor: 'pointer',
  fontFamily: 'inherit', fontSize: 13, fontWeight: 600,
  border: '1px solid var(--line)', borderBottom: active ? '1px solid var(--bg-card)' : '1px solid var(--line)',
  background: active ? 'var(--bg-card)' : 'var(--bg-soft)',
  color: active ? 'var(--maroon)' : 'var(--mute)',
  position: 'relative', top: 1,
});
const spRow = {
  display: 'flex', alignItems: 'center', gap: 12, padding: '11px 14px',
  borderBottom: '1px solid var(--line)', cursor: 'pointer',
};
const spName = { fontSize: 13, fontWeight: 600, color: 'var(--ink)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' };
const spSub = { fontSize: 11, color: 'var(--mute)', marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' };
const spCrumbBtn = { background: 'none', border: 'none', cursor: 'pointer', fontFamily: 'inherit', fontSize: 13, color: 'var(--maroon)', padding: 0 };
const spEmpty = { padding: '48px 20px', textAlign: 'center', color: 'var(--mute)', fontSize: 13 };

// ─────────────────────────────────────────────────────────────────────────────
// Lightweight entry modals — Text input and URL. Each collects raw content then
// hands off to the TaggingModal (confidentiality + tags) via onConfirm.
// ─────────────────────────────────────────────────────────────────────────────

const spInputShell = (children, onClose) => (
  <div onClick={onClose} style={{
    position: 'absolute', inset: 0, zIndex: 70,
    background: 'rgba(26,22,20,0.42)', backdropFilter: 'blur(4px)',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    animation: 'fadein 0.18s ease-out',
  }}>
    {children}
  </div>
);

const spFieldLabel = {
  fontSize: 11, fontWeight: 700, color: 'var(--mute)',
  letterSpacing: '0.08em', textTransform: 'uppercase', marginBottom: 6, display: 'block',
};
const spTextField = {
  width: '100%', height: 40, padding: '0 12px', borderRadius: 9,
  border: '1px solid var(--line-2)', fontSize: 13, fontFamily: 'inherit',
  outline: 'none', color: 'var(--ink)', background: 'white', boxSizing: 'border-box',
};

const TextInputModal = ({ open, onClose, onConfirm }) => {
  const [title, setTitle] = React.useState('');
  const [content, setContent] = React.useState('');
  React.useEffect(() => { if (open) { setTitle(''); setContent(''); } }, [open]);
  if (!open) return null;
  const ready = content.trim().length > 0;
  const submit = () => { if (ready) onConfirm({ title: title.trim() || 'Untitled note', content }); };

  return spInputShell((
    <div onClick={e => e.stopPropagation()} style={{
      width: 560, maxWidth: '94%', background: 'var(--bg-card)', borderRadius: 18,
      boxShadow: '0 30px 80px rgba(26,22,20,0.30), 0 0 0 1px var(--line)',
      animation: 'rise 0.22s ease-out', display: 'flex', flexDirection: 'column', overflow: 'hidden',
    }}>
      <div style={{ padding: '18px 24px', borderBottom: '1px solid var(--line)' }}>
        <h2 className="serif" style={{ fontSize: 18, fontWeight: 500, margin: 0, letterSpacing: '-0.01em' }}>Add text</h2>
        <div style={{ fontSize: 13, color: 'var(--mute)', marginTop: 3 }}>Paste notes or any text — it’s saved as a document you can tag.</div>
      </div>
      <div style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 16 }}>
        <div>
          <label style={spFieldLabel}>Title</label>
          <input value={title} onChange={e => setTitle(e.target.value)} placeholder="e.g. CFO interview notes" style={spTextField} />
        </div>
        <div>
          <label style={spFieldLabel}>Content</label>
          <textarea
            value={content}
            onChange={e => setContent(e.target.value)}
            placeholder="Paste or type your text here…"
            style={{ ...spTextField, height: 200, padding: '10px 12px', resize: 'vertical', lineHeight: 1.5 }}
          />
        </div>
      </div>
      <div style={{ padding: '14px 24px', borderTop: '1px solid var(--line)', display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
        <button onClick={onClose} className="btn-secondary" style={{ height: 36 }}>Cancel</button>
        <button onClick={submit} disabled={!ready} className="btn-primary" style={{ height: 36, opacity: ready ? 1 : 0.5 }}>Continue</button>
      </div>
    </div>
  ), onClose);
};

const UrlInputModal = ({ open, onClose, onConfirm }) => {
  const [url, setUrl] = React.useState('');
  const [title, setTitle] = React.useState('');
  React.useEffect(() => { if (open) { setUrl(''); setTitle(''); } }, [open]);
  if (!open) return null;
  const trimmed = url.trim();
  const ready = /^https?:\/\/.+/i.test(trimmed);
  const submit = () => { if (ready) onConfirm({ url: trimmed, title: title.trim() }); };

  return spInputShell((
    <div onClick={e => e.stopPropagation()} style={{
      width: 560, maxWidth: '94%', background: 'var(--bg-card)', borderRadius: 18,
      boxShadow: '0 30px 80px rgba(26,22,20,0.30), 0 0 0 1px var(--line)',
      animation: 'rise 0.22s ease-out', display: 'flex', flexDirection: 'column', overflow: 'hidden',
    }}>
      <div style={{ padding: '18px 24px', borderBottom: '1px solid var(--line)' }}>
        <h2 className="serif" style={{ fontSize: 18, fontWeight: 500, margin: 0, letterSpacing: '-0.01em' }}>Add a URL</h2>
        <div style={{ fontSize: 13, color: 'var(--mute)', marginTop: 3 }}>The link is saved as a reference for the research pipeline to fetch.</div>
      </div>
      <div style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 16 }}>
        <div>
          <label style={spFieldLabel}>URL</label>
          <input
            value={url}
            onChange={e => setUrl(e.target.value)}
            onKeyDown={e => { if (e.key === 'Enter') submit(); }}
            placeholder="https://example.com/report"
            style={spTextField}
          />
          {trimmed && !ready && <div style={{ fontSize: 11, color: 'var(--maroon)', marginTop: 5 }}>Enter a full URL starting with http:// or https://</div>}
        </div>
        <div>
          <label style={spFieldLabel}>Title <span style={{ textTransform: 'none', fontWeight: 400, color: 'var(--mute-2)' }}>(optional)</span></label>
          <input value={title} onChange={e => setTitle(e.target.value)} placeholder="e.g. World Bank GDP outlook" style={spTextField} />
        </div>
      </div>
      <div style={{ padding: '14px 24px', borderTop: '1px solid var(--line)', display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
        <button onClick={onClose} className="btn-secondary" style={{ height: 36 }}>Cancel</button>
        <button onClick={submit} disabled={!ready} className="btn-primary" style={{ height: 36, opacity: ready ? 1 : 0.5 }}>Continue</button>
      </div>
    </div>
  ), onClose);
};

Object.assign(window, { TaggingModal, SharePointPickerModal, TextInputModal, UrlInputModal, SAMPLE_DROPPED, CONF_OPTIONS, SUGGESTED_TAGS });
