// 1Radar v3 — Shell: sidebar + page header + filter strip
// Matches the EUSpy / Monarch Figma vocabulary

// ---- Folder tree helpers ----

// Returns folders in depth-first order with a _depth field added.
// Used by SaveToFolderPopup to show an always-expanded indented list.
const flattenFolderTree = (folders, parentId = null, depth = 0) =>
  folders
    .filter(f => (f.parentId ?? null) === parentId && !f.system)
    .flatMap(f => [{ ...f, _depth: depth }, ...flattenFolderTree(folders, f.id, depth + 1)]);

// Inline creation form reused by FolderTreeItem (subfolder) and the sidebar
// boards footer (root folder). depth sets left indentation to match tree level.
const InlineFolderCreateForm = ({ depth = 0, onCommit, onCancel }) => {
  const [newName, setNewName] = React.useState('');
  const [pickerOpen, setPickerOpen] = React.useState(false);
  const [iconChoice, setIconChoice] = React.useState({ icon: 'folder', color: 'var(--text-faint)' });

  const commit = () => {
    const trimmed = newName.trim();
    if (!trimmed) { onCancel(); return; }
    onCommit(trimmed, iconChoice);
  };

  return (
    <div style={{ paddingLeft: depth * 12 + 18, paddingRight: 6, paddingTop: 4, paddingBottom: 4 }}>
      {pickerOpen && (
        <div style={{
          marginBottom: 6, padding: 8, borderRadius: 8,
          background: 'var(--bg-soft)', border: '1px solid var(--border)',
        }}>
          <div style={{ display: 'flex', gap: 5, marginBottom: 7 }}>
            {FOLDER_COLOR_OPTIONS.map(c => (
              <button key={c} onClick={() => setIconChoice(s => ({ ...s, color: c }))} style={{
                width: 18, height: 18, borderRadius: 999, flexShrink: 0,
                border: iconChoice.color === c ? '2px solid var(--text)' : '1px solid var(--border)',
                background: c, padding: 0, cursor: 'pointer',
                boxShadow: iconChoice.color === c ? '0 0 0 2px var(--bg-soft)' : 'none',
              }}/>
            ))}
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 3 }}>
            {FOLDER_ICON_OPTIONS.map(ic => {
              const on = iconChoice.icon === ic;
              return (
                <button key={ic} onClick={() => setIconChoice(s => ({ ...s, icon: ic }))} style={{
                  height: 26, borderRadius: 5,
                  border: on ? '1px solid var(--text)' : '1px solid transparent',
                  background: on ? 'var(--bg-surface)' : 'transparent',
                  color: on ? iconChoice.color : 'var(--text-muted)',
                  cursor: 'pointer',
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                }}>
                  <Icon name={ic} size={12}/>
                </button>
              );
            })}
          </div>
        </div>
      )}
      <div style={{ display: 'flex', gap: 4 }}>
        <div className="fld" style={{ flex: 1, minWidth: 0, height: 28, borderRadius: 7, padding: '0 6px 0 4px' }}>
          <button onClick={() => setPickerOpen(v => !v)} style={{
            width: 20, height: 20, borderRadius: 4, border: 0, flexShrink: 0,
            background: pickerOpen ? 'var(--bg-soft)' : 'transparent',
            color: iconChoice.color, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <Icon name={iconChoice.icon} size={12}/>
          </button>
          <input
            autoFocus
            value={newName}
            onChange={e => setNewName(e.target.value)}
            placeholder="Name…"
            style={{ fontSize: 12, minWidth: 0 }}
            onKeyDown={e => { if (e.key === 'Enter') commit(); else if (e.key === 'Escape') onCancel(); }}
          />
        </div>
        {/* Icon-only buttons to stay within the narrow sidebar */}
        <button
          onClick={commit}
          disabled={!newName.trim()}
          className="btn btn-primary btn-icon"
          title="Create folder"
          style={{ height: 28, width: 28, flexShrink: 0, padding: 0 }}>
          <Icon name="check" size={13} stroke={2.5}/>
        </button>
        <button
          onClick={onCancel}
          title="Cancel"
          className="btn btn-icon"
          style={{ height: 28, width: 28, flexShrink: 0, padding: 0, background: '#E5484D', color: '#fff', borderColor: '#E5484D', borderRadius: 8 }}>
          <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" strokeLinecap="round" strokeWidth="2" d="m8 8l4 4m0 0l4 4m-4-4l4-4m-4 4l-4 4"/></svg>
        </button>
      </div>
    </div>
  );
};

// Recursive sidebar row with expand/collapse chevron.
// depth drives left indentation; activeId highlights the selected folder.
// Auto-expands when it is an ancestor of the active folder.
// onCreateFolder(name, iconChoice, parentId) — omit to hide the hover "+" action.
// defaultOpen — start expanded (useful on the dedicated Saved Ads page).
const FolderTreeItem = ({ folder, allFolders, depth = 0, activeId, onSelect, onCreateFolder, onDelete, onRename, defaultOpen = false }) => {
  const children = allFolders.filter(f => f.parentId === folder.id && !f.system);
  const hasKids = children.length > 0;

  const isAncestorActive = React.useMemo(() => {
    let cur = allFolders.find(f => f.id === activeId);
    while (cur?.parentId) {
      if (cur.parentId === folder.id) return true;
      cur = allFolders.find(f => f.id === cur.parentId);
    }
    return false;
  }, [activeId, folder.id, allFolders]);

  const [open, setOpen] = React.useState(defaultOpen);
  const [hovered, setHovered] = React.useState(false);
  const [creatingChild, setCreatingChild] = React.useState(false);
  const [menuOpen, setMenuOpen] = React.useState(false);
  const [renaming, setRenaming] = React.useState(false);
  const [renameVal, setRenameVal] = React.useState(folder.name);

  React.useEffect(() => {
    if (isAncestorActive) setOpen(true);
  }, [isAncestorActive]);

  const isActive = activeId === folder.id;
  const showChildren = open || creatingChild;
  const hasToggle = hasKids || creatingChild;

  const handleAddChild = (e) => {
    e.stopPropagation();
    setOpen(true);
    setCreatingChild(true);
  };

  const handleCommitChild = (name, iconChoice) => {
    onCreateFolder && onCreateFolder(name, iconChoice, folder.id);
    setCreatingChild(false);
  };

  return (
    <>
      <div
        style={{ display: 'flex', alignItems: 'center' }}
        onMouseEnter={() => setHovered(true)}
        onMouseLeave={() => setHovered(false)}
      >
        <div style={{ width: depth * 12, flexShrink: 0 }}/>
        {/* Expand / collapse chevron */}
        <button
          onClick={(e) => { e.stopPropagation(); if (hasToggle) setOpen(v => !v); }}
          style={{
            width: 16, height: 30, flexShrink: 0,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            background: 'none', border: 'none', padding: 0, borderRadius: 4,
            color: 'var(--text-faint)',
            cursor: hasToggle ? 'pointer' : 'default',
            opacity: hasToggle ? 1 : 0,
          }}>
          {hasToggle && <Icon name={showChildren ? 'chevron-down' : 'chevron-right'} size={11}/>}
        </button>
        {/* Folder label / rename input */}
        {renaming ? (
          <input autoFocus value={renameVal}
            onChange={e => setRenameVal(e.target.value)}
            onBlur={() => { setRenaming(false); if (renameVal.trim() && renameVal !== folder.name) onRename && onRename(folder.id || folder._id, renameVal.trim()); }}
            onKeyDown={e => { if (e.key === 'Enter') e.target.blur(); if (e.key === 'Escape') { setRenaming(false); setRenameVal(folder.name); } }}
            style={{ flex: 1, height: 28, fontSize: 13, padding: '0 6px', borderRadius: 6, border: '1px solid var(--accent)', background: 'var(--bg-soft)', color: 'var(--text)', outline: 'none', fontFamily: 'inherit' }}
            onClick={e => e.stopPropagation()}
          />
        ) : (
          <button onClick={() => onSelect(folder.id)} className={`nav-item ${isActive ? 'active' : ''}`} style={{ flex: 1, gap: 8, minWidth: 0 }}>
            <span style={{ color: folder.color || 'var(--text-faint)', flexShrink: 0, display: 'flex' }}>
              <Icon name={folder.icon} size={16} stroke={1.6}/>
            </span>
            <span className="nav-label" style={{ flex: 1, textAlign: 'left', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
              {folder.name}
            </span>
            {!hovered && (
              <span style={{ fontSize: 11, color: 'var(--text-faint)', fontVariantNumeric: 'tabular-nums', flexShrink: 0 }}>
                {folder.count}
              </span>
            )}
          </button>
        )}
        {/* Hover actions: add subfolder + context menu */}
        {hovered && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 1, flexShrink: 0, marginRight: 2 }}>
            {onCreateFolder && (
              <button onClick={handleAddChild} title={`New subfolder`}
                style={{ width: 20, height: 20, borderRadius: 5, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', background: 'none', border: 'none', cursor: 'pointer', color: 'var(--text-faint)' }}
                onMouseEnter={e => { e.currentTarget.style.background = 'var(--bg-soft)'; e.currentTarget.style.color = 'var(--text)'; }}
                onMouseLeave={e => { e.currentTarget.style.background = 'none'; e.currentTarget.style.color = 'var(--text-faint)'; }}>
                <Icon name="plus" size={12}/>
              </button>
            )}
            {(onDelete || onRename) && (
              <div style={{ position: 'relative' }}>
                <button onClick={(e) => { e.stopPropagation(); setMenuOpen(v => !v); }}
                  style={{ width: 20, height: 20, borderRadius: 5, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', background: menuOpen ? 'var(--bg-soft)' : 'none', border: 'none', cursor: 'pointer', color: 'var(--text-faint)' }}
                  onMouseEnter={e => { if (!menuOpen) e.currentTarget.style.background = 'var(--bg-soft)'; }}
                  onMouseLeave={e => { if (!menuOpen) e.currentTarget.style.background = 'none'; }}>
                  <Icon name="more" size={12}/>
                </button>
                {menuOpen && (
                  <>
                    <div onClick={() => setMenuOpen(false)} style={{ position: 'fixed', inset: 0, zIndex: 50 }}/>
                    <div style={{ position: 'absolute', left: 0, top: '100%', zIndex: 51, minWidth: 140, background: 'var(--bg-surface)', border: '1px solid var(--border)', borderRadius: 10, boxShadow: '0 8px 24px rgba(14,18,27,0.18)', padding: 4 }}>
                      {onRename && (
                        <button onClick={() => { setMenuOpen(false); setRenaming(true); setRenameVal(folder.name); }}
                          style={{ display: 'flex', alignItems: 'center', gap: 8, width: '100%', padding: '7px 10px', background: 'none', border: 'none', borderRadius: 6, color: 'var(--text)', fontSize: 13, fontFamily: 'inherit', cursor: 'pointer', textAlign: 'left' }}
                          onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-soft)'}
                          onMouseLeave={e => e.currentTarget.style.background = 'none'}>
                          <Icon name="edit" size={13} style={{ color: 'var(--text-faint)' }}/> Renommer
                        </button>
                      )}
                      {onDelete && (
                        <button onClick={() => { setMenuOpen(false); onDelete(folder.id || folder._id); }}
                          style={{ display: 'flex', alignItems: 'center', gap: 8, width: '100%', padding: '7px 10px', background: 'none', border: 'none', borderRadius: 6, color: 'var(--danger)', fontSize: 13, fontFamily: 'inherit', cursor: 'pointer', textAlign: 'left' }}
                          onMouseEnter={e => e.currentTarget.style.background = 'rgba(220,53,69,0.08)'}
                          onMouseLeave={e => e.currentTarget.style.background = 'none'}>
                          <Icon name="trash" size={13}/> Supprimer
                        </button>
                      )}
                    </div>
                  </>
                )}
              </div>
            )}
          </div>
        )}
      </div>
      {/* Children + inline creation form */}
      {showChildren && (
        <>
          {children.map(child => (
            <FolderTreeItem
              key={child.id}
              folder={child}
              allFolders={allFolders}
              depth={depth + 1}
              activeId={activeId}
              onSelect={onSelect}
              onCreateFolder={onCreateFolder}
              onDelete={onDelete}
              onRename={onRename}
              defaultOpen={defaultOpen}
            />
          ))}
          {creatingChild && (
            <InlineFolderCreateForm
              depth={depth + 1}
              onCommit={handleCommitChild}
              onCancel={() => setCreatingChild(false)}
            />
          )}
        </>
      )}
    </>
  );
};

const SidebarV3 = ({ active, onChange, collapsed, onToggleCollapse, theme, onToggleTheme, onCmdK, onFolderNav, activeFolderId, user, onLogout }) => {
  const W = collapsed ? 80 : 264;
  const [boardsOpen, setBoardsOpen] = React.useState(true);
  const [boardsSearch, setBoardsSearch] = React.useState('');

  const [sidebarFolders, setSidebarFolders] = React.useState(window.SAVE_FOLDERS_V3 || SAVE_FOLDERS_V3);
  const [creatingRoot, setCreatingRoot] = React.useState(false);

  // Sync with API folders on mount and whenever folders-updated fires
  React.useEffect(() => {
    const sync = () => setSidebarFolders(window.SAVE_FOLDERS_V3 || []);
    window.addEventListener('folders-updated', sync);
    // Trigger initial load (loadFolders is defined in hybrid-extras.jsx)
    if (window.loadFolders) window.loadFolders();
    return () => window.removeEventListener('folders-updated', sync);
  }, []);

  const handleCreateFolder = async (name, iconChoice, parentId) => {
    try {
      await apiFetch('/folders', 'POST', {
        name,
        icon: iconChoice?.icon || 'folder',
        color: iconChoice?.color || null,
        parentId: parentId || null,
      });
      if (window.loadFolders) window.loadFolders();
    } catch {
      // Fallback: optimistic local-only add
      setSidebarFolders(prev => [...prev, {
        id: 'f_' + Date.now(), name,
        icon: iconChoice?.icon || 'folder',
        color: iconChoice?.color || null,
        count: 0,
        ...(parentId ? { parentId } : {}),
      }]);
    }
  };

  const handleDeleteFolder = async (folderId) => {
    try {
      await apiFetch(`/folders/${folderId}`, 'DELETE');
      if (window.loadFolders) window.loadFolders();
    } catch {}
  };

  const handleRenameFolder = async (folderId, newName) => {
    try {
      await apiFetch(`/folders/${folderId}`, 'PATCH', { name: newName });
      if (window.loadFolders) window.loadFolders();
    } catch {}
  };

  const NavItem = ({ item }) => {
    const isActive = active === item.id;
    return (
      <button
        onClick={() => onChange(item.id)}
        title={collapsed ? item.label : undefined}
        className={`nav-item ${isActive ? 'active' : ''} ${collapsed ? 'collapsed' : ''}`}
        style={{ flexShrink: 0 }}
      >
        <Icon name={item.icon} size={20} stroke={1.6}/>
        {!collapsed && <span className="nav-label">{item.label}</span>}
      </button>
    );
  };

  return (
    <aside style={{
      width: W, flexShrink: 0,
      background: 'var(--bg-surface)',
      borderRight: '1px solid var(--border)',
      display: 'flex', flexDirection: 'column',
      height: '100vh',
      position: 'sticky', top: 0,
      zIndex: 10,
    }}>
      <div style={{
        height: 'var(--header-h)',
        borderBottom: '1px solid var(--border)',
        padding: collapsed ? '0' : '0 16px',
        display: 'flex', alignItems: 'center', justifyContent: collapsed ? 'center' : 'space-between',
        flexShrink: 0,
      }}>
        {collapsed ? (
          <button onClick={onToggleCollapse} className="btn btn-ghost btn-icon" title="Expand sidebar">
            <Icon name="sidebar" size={18}/>
          </button>
        ) : (
          <>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <Icon name="logo" size={36}/>
              <div style={{ lineHeight: 1.15 }}>
                <div style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 16 }}>1Radar</div>
                <div style={{ fontSize: 11, color: 'var(--text-faint)', letterSpacing: 0.04, textTransform: 'uppercase' }}>Ads Intelligence</div>
              </div>
            </div>
            <button onClick={onToggleCollapse} className="btn btn-ghost btn-icon" title="Collapse">
              <Icon name="sidebar" size={18}/>
            </button>
          </>
        )}
      </div>

      <div style={{
        flex: 1, minHeight: 0, overflow: 'auto',
        padding: '20px 12px',
        display: 'flex', flexDirection: 'column', gap: 24,
        alignItems: collapsed ? 'center' : 'stretch',
      }} className="scroll">
        {/* Search bar — opens ⌘K palette */}
        {collapsed ? (
          <button onClick={onCmdK} className="btn btn-ghost btn-icon" title="Search (⌘K)" style={{ width: 40, height: 40 }}>
            <Icon name="search" size={18}/>
          </button>
        ) : (
          <button onClick={onCmdK} style={{
            display: 'flex', alignItems: 'center', gap: 10,
            padding: '0 12px 0 10px', height: 36,
            background: 'var(--bg-soft)',
            border: '1px solid var(--border)',
            borderRadius: 10,
            color: 'var(--text-faint)',
            fontSize: 13, cursor: 'pointer',
            width: '100%', textAlign: 'left',
            transition: 'border-color .15s, background .15s',
          }}
          onMouseEnter={(e) => e.currentTarget.style.borderColor = 'var(--text-faint)'}
          onMouseLeave={(e) => e.currentTarget.style.borderColor = 'var(--border)'}>
            <Icon name="search" size={15}/>
            <span style={{ flex: 1 }}>Search…</span>
            <span style={{
              display: 'inline-flex', alignItems: 'center', gap: 2,
              padding: '2px 6px', borderRadius: 5,
              background: 'var(--bg-surface)', border: '1px solid var(--border)',
              fontSize: 11, fontFamily: 'var(--font-mono)', color: 'var(--text-muted)',
            }}>⌘K</span>
          </button>
        )}

        {NAV_V3.slice(0, 2).map((g) => (
          <div key={g.group} style={{ display: 'flex', flexDirection: 'column', gap: 4, width: '100%', alignItems: collapsed ? 'center' : 'stretch' }}>
            {!collapsed && (
              <div style={{
                fontSize: 11, color: 'var(--text-faint)', letterSpacing: 0.06, textTransform: 'uppercase',
                padding: '4px 10px 6px', fontWeight: 600,
              }}>{g.group === 'main' ? 'Workspace' : 'AI Tools'}</div>
            )}
            {g.items.map((item) => <NavItem key={item.id} item={item}/>)}
          </div>
        ))}

        {/* Boards / Folders */}
        {collapsed ? (
          // Collapsed: root-level icons only
          <div style={{ display: 'flex', flexDirection: 'column', gap: 4, alignItems: 'center', width: '100%' }}>
            {sidebarFolders.filter(f => !f.system && !f.parentId).map(folder => {
              const isActive = active === 'saved' && activeFolderId === folder.id;
              return (
                <button
                  key={folder.id}
                  onClick={() => onFolderNav?.(folder.id)}
                  title={folder.name}
                  className={`nav-item collapsed ${isActive ? 'active' : ''}`}
                  style={{ flexShrink: 0, color: folder.color || 'var(--text-muted)' }}
                >
                  <Icon name={folder.icon} size={18} stroke={1.6}/>
                </button>
              );
            })}
          </div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
            {/* Header row — "Boards" label + chevron */}
            <button
              onClick={() => setBoardsOpen(o => !o)}
              style={{
                display: 'flex', alignItems: 'center', gap: 4, background: 'none', border: 'none',
                cursor: 'pointer', width: '100%', padding: '4px 10px 6px',
              }}
            >
              <span style={{ fontSize: 11, color: 'var(--text-faint)', letterSpacing: 0.06, textTransform: 'uppercase', fontWeight: 600, flex: 1, textAlign: 'left' }}>Boards</span>
              <Icon name={boardsOpen ? 'chevron-down' : 'chevron-right'} size={12} style={{ color: 'var(--text-faint)' }}/>
            </button>
            {boardsOpen && <>
              {/* Search */}
              <div style={{ padding: '0 10px 4px' }}>
                <div style={{
                  display: 'flex', alignItems: 'center', gap: 6,
                  height: 28, padding: '0 8px',
                  background: 'var(--bg-soft)', border: '1px solid var(--border)',
                  borderRadius: 7,
                }}>
                  <Icon name="search" size={12} style={{ color: 'var(--text-faint)', flexShrink: 0 }}/>
                  <input
                    value={boardsSearch}
                    onChange={e => setBoardsSearch(e.target.value)}
                    placeholder="Search boards…"
                    style={{ flex: 1, background: 'none', border: 'none', outline: 'none', fontSize: 12, color: 'var(--text)', minWidth: 0 }}
                    onKeyDown={e => { if (e.key === 'Escape') setBoardsSearch(''); }}
                  />
                  {boardsSearch && (
                    <button onClick={() => setBoardsSearch('')} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, color: 'var(--text-faint)', display: 'flex' }}>
                      <Icon name="x" size={12}/>
                    </button>
                  )}
                </div>
              </div>

              {/* Folder tree — flat search results OR interactive nested tree */}
              {(() => {
                const q = boardsSearch.trim().toLowerCase();
                if (q) {
                  const matches = sidebarFolders.filter(f => !f.system && f.name.toLowerCase().includes(q));
                  if (matches.length === 0) return (
                    <div style={{ padding: '6px 12px', fontSize: 12, color: 'var(--text-faint)' }}>No results</div>
                  );
                  return matches.map(folder => {
                    const isActive = active === 'saved' && activeFolderId === folder.id;
                    return (
                      <button key={folder.id} onClick={() => onFolderNav?.(folder.id)}
                        className={`nav-item ${isActive ? 'active' : ''}`} style={{ flexShrink: 0, gap: 8 }}>
                        <span style={{ color: folder.color || 'var(--text-muted)', flexShrink: 0, display: 'flex' }}>
                          <Icon name={folder.icon} size={16} stroke={1.6}/>
                        </span>
                        <span className="nav-label" style={{ flex: 1, textAlign: 'left' }}>{folder.name}</span>
                        <span style={{ fontSize: 11, color: 'var(--text-faint)', fontVariantNumeric: 'tabular-nums', marginLeft: 'auto' }}>{folder.count}</span>
                      </button>
                    );
                  });
                }
                const roots = sidebarFolders.filter(f => !f.system && !f.parentId);
                if (roots.length === 0 && !creatingRoot) return (
                  <div style={{ padding: '6px 12px', fontSize: 12, color: 'var(--text-faint)' }}>No boards yet</div>
                );
                return roots.map(folder => (
                  <FolderTreeItem
                    key={folder.id}
                    folder={folder}
                    allFolders={sidebarFolders}
                    depth={0}
                    activeId={active === 'saved' ? activeFolderId : null}
                    onSelect={(id) => onFolderNav?.(id)}
                    onCreateFolder={handleCreateFolder}
                    onDelete={handleDeleteFolder}
                    onRename={handleRenameFolder}
                  />
                ));
              })()}

              {/* Inline root-folder creation form */}
              {creatingRoot && (
                <InlineFolderCreateForm
                  depth={0}
                  onCommit={(name, iconChoice) => { handleCreateFolder(name, iconChoice, null); setCreatingRoot(false); }}
                  onCancel={() => setCreatingRoot(false)}
                />
              )}

              {/* "+ New board" footer button */}
              {!creatingRoot && !boardsSearch && (
                <button
                  onClick={() => setCreatingRoot(true)}
                  style={{
                    display: 'flex', alignItems: 'center', gap: 8,
                    width: '100%', padding: '6px 10px',
                    background: 'transparent', border: 0, borderRadius: 8,
                    color: 'var(--text-faint)', fontSize: 12, cursor: 'pointer',
                    marginTop: 2,
                  }}
                  onMouseEnter={e => { e.currentTarget.style.color = 'var(--accent)'; e.currentTarget.style.background = 'var(--accent-soft)'; }}
                  onMouseLeave={e => { e.currentTarget.style.color = 'var(--text-faint)'; e.currentTarget.style.background = 'transparent'; }}>
                  <Icon name="plus" size={13}/>
                  <span>New board</span>
                </button>
              )}
            </>}
          </div>
        )}

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

        <div style={{ display: 'flex', flexDirection: 'column', gap: 4, width: '100%', alignItems: collapsed ? 'center' : 'stretch' }}>
          {NAV_V3[2].items.map((item) => <NavItem key={item.id} item={item}/>)}
        </div>
      </div>

      <div style={{
        borderTop: '1px solid var(--border)',
        padding: collapsed ? '12px 0' : '12px 16px',
        display: 'flex', flexDirection: 'column',
        flexShrink: 0, gap: 4,
      }}>
        {collapsed ? (
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6 }}>
            <div className="avatar avatar-sm" style={{ width: 36, height: 36, fontSize: 13 }}>
              {user ? user.name.slice(0,1).toUpperCase() : '?'}
            </div>
            <button className="btn btn-ghost btn-icon" onClick={onToggleTheme} title="Toggle theme" style={{ width: 32, height: 32 }}>
              <Icon name={theme === 'dark' ? 'sun' : 'moon'} size={16}/>
            </button>
          </div>
        ) : (
          <>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 0 }}>
              <div className="avatar avatar-sm" style={{ width: 36, height: 36, fontSize: 13, flexShrink: 0 }}>
                {user ? user.name.slice(0,1).toUpperCase() : '?'}
              </div>
              <div style={{ minWidth: 0, flex: 1 }}>
                <div style={{ fontWeight: 500, fontSize: 14, letterSpacing: '-0.006em', color: 'var(--text)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                  {user ? user.name : '—'}
                </div>
                <div style={{ fontSize: 12, color: 'var(--text-faint)', textTransform: 'capitalize' }}>
                  {user ? `${user.plan} plan` : ''}
                </div>
              </div>
              <button className="btn btn-ghost btn-icon" onClick={onToggleTheme} title="Toggle theme" style={{ flexShrink: 0 }}>
                <Icon name={theme === 'dark' ? 'sun' : 'moon'} size={16}/>
              </button>
            </div>
          </>
        )}
      </div>
    </aside>
  );
};

const PageHeader = ({ icon = 'home', title, subtitle, center, right }) => (
  <div className="app-header">
    <div style={{ display: 'flex', alignItems: 'center', gap: 14, minWidth: 0 }}>
      <div className="tab-icon">
        <Icon name={icon} size={22} stroke={1.6}/>
      </div>
      <div style={{ minWidth: 0 }}>
        <div className="tb-title font-display">{title}</div>
        <div className="tb-subtitle">{subtitle}</div>
      </div>
    </div>
    {center && (
      <div style={{ flex: 1, display: 'flex', justifyContent: 'center' }}>{center}</div>
    )}
    <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
      {right}
    </div>
  </div>
);

const SegToggle = ({ value, onChange, options }) => (
  <div className="seg">
    {options.map(o => (
      <button key={o.value} className={value === o.value ? 'on' : ''} onClick={() => onChange(o.value)}>
        {o.icon && <Icon name={o.icon} size={14} style={{ marginRight: 6, verticalAlign: '-2px' }}/>}
        {o.label}
      </button>
    ))}
  </div>
);

// ---- Filter strip — matches Figma "Horizontal Filter [1.0]" ----

// Saved-filter pill (top row): colored square + label, optional close
const SavedFilterPill = ({ label, color, active, closeable, onClick, onClose }) => (
  <button onClick={onClick} className="chip" style={{
    height: 32, padding: '0 12px', gap: 8,
    background: active ? 'var(--accent-soft)' : 'var(--bg-surface)',
    border: `1px solid ${active ? 'var(--accent-soft)' : 'var(--border)'}`,
    color: active ? 'var(--accent)' : 'var(--text)',
    borderRadius: 999,
    fontWeight: 500, fontSize: 13,
  }}>
    <span style={{
      width: 14, height: 14, borderRadius: 4,
      background: color, flexShrink: 0,
      boxShadow: 'inset 0 0 0 1px rgba(0,0,0,0.05)',
    }}/>
    {label}
    {closeable && (
      <span onClick={(e) => { e.stopPropagation(); onClose && onClose(); }}
            style={{ display: 'inline-flex', color: 'var(--text-faint)', marginLeft: 2 }}>
        <Icon name="close" size={12}/>
      </span>
    )}
  </button>
);

// Active-filter pill (search row): icon + value, with close.
// Clicking the pill body opens the editor for that filter type.
const ActiveFilterPill = ({ filter, onCommit, onClose }) => {
  const [open, setOpen] = React.useState(false);
  return (
    <div style={{ position: 'relative' }}>
      <button onClick={() => setOpen(v => !v)} className="chip" style={{
        height: 32, padding: '0 8px 0 10px', gap: 6,
        borderRadius: 999, fontSize: 13, fontWeight: 500,
        color: 'var(--text)',
        background: open ? 'var(--accent-soft)' : 'var(--bg-surface)',
        border: `1px solid ${open ? 'var(--accent-soft)' : 'var(--border)'}`,
      }}>
        <Icon name={filter.icon} size={14} style={{ color: open ? 'var(--accent)' : 'var(--text-muted)' }}/>
        {filter.label}
        <span onClick={(e) => { e.stopPropagation(); onClose && onClose(); }}
              style={{
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                width: 16, height: 16, borderRadius: 999,
                color: 'var(--text-faint)', marginLeft: 2,
              }}>
          <Icon name="close" size={12}/>
        </span>
      </button>
      {open && (
        <>
          <div onClick={() => setOpen(false)} style={{ position: 'fixed', inset: 0, zIndex: 60 }}/>
          <FilterEditor
            filter={filter}
            onCommit={(value, label) => onCommit({ ...filter, value, label: label ?? FILTER_DEFS[filter.id].label(value) })}
            onClose={() => setOpen(false)}
          />
        </>
      )}
    </div>
  );
};

// Catalog of every available filter the user can add.
// Each entry has a default value used when the user picks it from "Add Filter".
const FILTER_CATALOG = [
  { id: 'date',     icon: 'calendar',     name: 'Date range',          defaultLabel: 'Sep 7, 2024 – Sep 2…' },
  { id: 'reach',    icon: 'users',        name: 'Reach',               defaultLabel: '1.5M – 5M' },
  { id: 'spend',    icon: 'wallet',       name: 'Daily spend',         defaultLabel: 'Daily 100 – 10K+' },
  { id: 'format',   icon: 'play-circle',  name: 'Ad format',           defaultLabel: 'Carousel, Video' },
  { id: 'cta',      icon: 'link',         name: 'Call to action',      defaultLabel: 'Buy Now, Buy' },
  { id: 'geo',      icon: 'globe',        name: 'Country',             defaultLabel: 'France, Suisse, Bel…' },
  { id: 'shop',     icon: 'shop',         name: 'Shop type',           defaultLabel: 'Is dropshipping' },
  { id: 'language', icon: 'message',      name: 'Language',            defaultLabel: 'English, French' },
  { id: 'platform', icon: 'sparkles',     name: 'Platform',            defaultLabel: 'Facebook, Instagram' },
  { id: 'industry', icon: 'tag',          name: 'Industry',            defaultLabel: 'Fashion, Beauty' },
  { id: 'creator',  icon: 'star',         name: 'Verified creator',    defaultLabel: 'Verified only' },
];

const AddFilterPopover = ({ available, onPick, onClose }) => {
  const [q, setQ] = React.useState('');
  const filtered = available.filter(f => f.name.toLowerCase().includes(q.toLowerCase()));
  return (
    <>
      <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 60 }}/>
      <div role="menu" style={{
        position: 'absolute', top: 'calc(100% + 6px)', left: 0,
        zIndex: 61,
        width: 260,
        background: 'var(--bg-surface)',
        border: '1px solid var(--border)',
        borderRadius: 12,
        boxShadow: '0 12px 32px rgba(14,18,27,0.12)',
        padding: 6,
      }}>
        <div className="fld" style={{ height: 32, borderRadius: 8, padding: '0 10px', margin: 4, marginBottom: 6 }}>
          <Icon name="search" size={14} style={{ color: 'var(--text-faint)' }}/>
          <input autoFocus value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search filters…"
                 style={{ fontSize: 13 }}/>
        </div>
        <div style={{ maxHeight: 280, overflow: 'auto' }} className="scroll">
          {filtered.length === 0 ? (
            <div style={{ padding: '14px 12px', color: 'var(--text-faint)', fontSize: 13 }}>No filters match.</div>
          ) : filtered.map((f) => (
            <button key={f.id} onClick={() => onPick(f)} style={{
              display: 'flex', alignItems: 'center', gap: 10,
              width: '100%', padding: '8px 10px',
              background: 'transparent', border: 0, borderRadius: 8,
              color: 'var(--text)', fontSize: 13, textAlign: 'left',
              cursor: 'pointer',
            }}
            onMouseEnter={(e) => e.currentTarget.style.background = 'var(--bg-muted)'}
            onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
              <Icon name={f.icon} size={14} style={{ color: 'var(--text-muted)' }}/>
              <span style={{ flex: 1 }}>{f.name}</span>
              <Icon name="plus" size={14} style={{ color: 'var(--text-faint)' }}/>
            </button>
          ))}
        </div>
      </div>
    </>
  );
};

const FilterStripV3 = ({ filterMode, onFilterMode, search, onSearch, chips, activeChip, onChip, onApply, activeFilters: ctrlFilters, onActiveFiltersChange }) => {
  const [savedFilter, setSavedFilter] = React.useState('trending');
  const makeFilter = (id, icon) => {
    const value = FILTER_DEFS[id]?.initial;
    const label = FILTER_DEFS[id]?.label(value) ?? '';
    return { id, icon, value, label };
  };
  const [internalFilters, setInternalFilters] = React.useState(() => [
    makeFilter('date',   'calendar'),
    makeFilter('reach',  'users'),
    makeFilter('spend',  'wallet'),
    makeFilter('format', 'play-circle'),
    makeFilter('cta',    'link'),
    makeFilter('geo',    'globe'),
    makeFilter('shop',   'shop'),
  ]);
  const isControlled = ctrlFilters !== undefined;
  const activeFilters = isControlled ? ctrlFilters : internalFilters;
  const setActiveFilters = (next) => {
    const value = typeof next === 'function' ? next(activeFilters) : next;
    if (isControlled) onActiveFiltersChange?.(value);
    else setInternalFilters(value);
  };
  const [addOpen, setAddOpen] = React.useState(false);
  // Filter being configured before being added — only commits to activeFilters on Apply.
  const [pendingFilter, setPendingFilter] = React.useState(null);
  const removeFilter = (id) => setActiveFilters(a => a.filter(f => f.id !== id));
  const updateFilter = (next) => setActiveFilters(a => a.map(f => f.id === next.id ? next : f));
  const startAddingFilter = (def) => {
    setPendingFilter(makeFilter(def.id, def.icon));
    setAddOpen(false);
  };
  const commitPendingFilter = (value, label) => {
    setActiveFilters(a => [...a, {
      ...pendingFilter,
      value,
      label: label ?? FILTER_DEFS[pendingFilter.id].label(value),
    }]);
    setPendingFilter(null);
  };
  const available = FILTER_CATALOG.filter(c => !activeFilters.some(a => a.id === c.id));

  const savedFilters = [
    { id: 'trending',  label: 'Trending',                    color: 'var(--accent)' },
    { id: 'dropship',  label: 'New dropshipping',            color: '#0E121B' },
    { id: 'q4',        label: '2023’ Q4 winners',            color: '#0E121B' },
    { id: 'secret',    label: 'Secret sauce',                color: '#0E121B' },
    { id: 'personal',  label: 'Personal filter for my brand', closeable: true },
  ];

  return (
    <div className="filter-strip">
      {/* Row 1 — saved filters */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
        {savedFilters.map((f) => (
          <SavedFilterPill key={f.id}
            label={f.label}
            color={f.color || 'transparent'}
            active={savedFilter === f.id}
            closeable={f.closeable}
            onClick={() => setSavedFilter(f.id)}
            onClose={() => {}}
          />
        ))}
      </div>

      <div className="divider-dashed" style={{ margin: '14px 0' }}/>

      {/* Row 2 — search + add filter + active filter pills */}
      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10, flexWrap: 'wrap' }}>
        <div className="fld" style={{ width: 200, height: 32, borderRadius: 999, padding: '0 12px' }}>
          <Icon name="search" size={14} style={{ color: 'var(--text-faint)' }}/>
          <input value={search} onChange={(e) => onSearch(e.target.value)} placeholder="Portable Mixer…"
                 style={{ fontSize: 13 }}/>
        </div>
        <div style={{ position: 'relative' }}>
          <button className="chip" onClick={() => setAddOpen(v => !v)}
                  style={{
                    height: 32, borderRadius: 999,
                    color: addOpen ? 'var(--accent)' : 'var(--text-muted)',
                    border: 0,
                    background: addOpen ? 'var(--accent-soft)' : 'transparent',
                  }}>
            <Icon name="filter" size={14}/> Add Filter
          </button>
          {addOpen && (
            <AddFilterPopover available={available} onPick={startAddingFilter} onClose={() => setAddOpen(false)}/>
          )}
          {pendingFilter && (
            <>
              <div onClick={() => setPendingFilter(null)} style={{ position: 'fixed', inset: 0, zIndex: 60 }}/>
              <FilterEditor
                filter={pendingFilter}
                onCommit={commitPendingFilter}
                onClose={() => setPendingFilter(null)}
              />
            </>
          )}
        </div>
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', flex: 1 }}>
          {activeFilters.map((f) => (
            <ActiveFilterPill key={f.id} filter={f}
                              onCommit={updateFilter}
                              onClose={() => removeFilter(f.id)}/>
          ))}
        </div>
      </div>

      {/* Row 3 — clear / save / apply (right-aligned) */}
      <div style={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', gap: 14, marginTop: 14 }}>
        <button onClick={() => setActiveFilters([])}
                style={{ background: 'transparent', border: 0, color: 'var(--text-muted)', fontSize: 13, fontWeight: 500, cursor: 'pointer' }}>
          Clear all
        </button>
        <span style={{ width: 4, height: 4, borderRadius: 999, background: 'var(--text-faint)' }}/>
        <button style={{ background: 'transparent', border: 0, color: 'var(--accent)', fontSize: 13, fontWeight: 500, cursor: 'pointer' }}>
          Save filters
        </button>
        <button className="btn btn-primary btn-sm" onClick={onApply}>Apply filters</button>
      </div>
    </div>
  );
};

// Curated icon set + color palette used by the "+ New folder" picker.
// Kept here (next to the popup) so the popup is self-contained.
const FOLDER_ICON_OPTIONS = [
  'folder', 'sparkles', 'play', 'user', 'image',
  'bookmark', 'star', 'heart', 'flame', 'flag',
  'shop', 'pin', 'gift', 'tag', 'package',
];
const FOLDER_COLOR_OPTIONS = [
  'var(--text-faint)', '#FFB35B', '#5B7BFF', '#E5484D',
  '#10B981', '#7B5BFF', '#EC4899', '#F59E0B',
];

// Save-to-folder popover — multi-select list of swipe-file folders, with
// inline "+ New folder" creation. `selected` is a Set of folder IDs.
const SaveToFolderPopup = ({ folders, selected, onToggle, onCreateFolder, onClose, onConfirm, anchor = 'left' }) => {
  const [search, setSearch] = React.useState('');
  const [creating, setCreating] = React.useState(false);
  const [newName, setNewName] = React.useState('');
  const [pickerOpen, setPickerOpen] = React.useState(false);
  const [iconChoice, setIconChoice] = React.useState({ icon: 'folder', color: 'var(--text-faint)' });
  const [hovered, setHovered] = React.useState(null);
  // Build depth-first flat tree (system folders excluded), then apply search.
  const tree = flattenFolderTree(folders);
  const list = search
    ? folders.filter(f => !f.system && f.name.toLowerCase().includes(search.toLowerCase())).map(f => ({ ...f, _depth: 0 }))
    : tree;

  const commitNew = () => {
    const trimmed = newName.trim();
    if (!trimmed) { setCreating(false); return; }
    onCreateFolder && onCreateFolder(trimmed, iconChoice);
    setNewName(''); setCreating(false); setPickerOpen(false);
    setIconChoice({ icon: 'folder', color: 'var(--text-faint)' });
  };
  const cancelNew = () => {
    setCreating(false); setNewName(''); setPickerOpen(false);
    setIconChoice({ icon: 'folder', color: 'var(--text-faint)' });
  };

  const confirm = () => {
    onConfirm && onConfirm();
    onClose && onClose();
  };

  return (
    <>
      <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 60, cursor: 'default' }}/>
      <div role="menu" style={{
        position: 'absolute', bottom: 'calc(100% + 6px)', [anchor]: 0,
        zIndex: 61, width: 296,
        background: 'var(--bg-surface)',
        border: '1px solid var(--border)',
        borderRadius: 12,
        boxShadow: '0 12px 32px rgba(14,18,27,0.12)',
        padding: 6,
        cursor: 'default',
      }}>
        {/* Header — title + close */}
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '4px 6px 4px 10px',
        }}>
          <div style={{
            fontSize: 11, fontWeight: 600, color: 'var(--text-faint)',
            letterSpacing: 0.06, textTransform: 'uppercase',
          }}>Save to folder</div>
          <button onClick={onClose} aria-label="Close" style={{
            width: 22, height: 22, borderRadius: 6,
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            border: 0, background: 'transparent', color: 'var(--text-faint)',
            cursor: 'pointer',
          }}
          onMouseEnter={(e) => { e.currentTarget.style.background = 'var(--bg-soft)'; e.currentTarget.style.color = 'var(--text)'; }}
          onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = 'var(--text-faint)'; }}>
            <Icon name="close" size={13}/>
          </button>
        </div>

        <div style={{ padding: '0 6px 6px' }}>
          <div className="fld" style={{ height: 32, borderRadius: 8, padding: '0 10px' }}>
            <Icon name="search" size={13} style={{ color: 'var(--text-faint)' }}/>
            <input value={search} onChange={(e) => setSearch(e.target.value)}
                   placeholder="Search folders…" style={{ fontSize: 13 }}/>
          </div>
        </div>

        <div style={{ maxHeight: 240, overflow: 'auto', padding: '2px 0' }} className="scroll">
          {list.length === 0 ? (
            <div style={{ padding: '14px 12px', color: 'var(--text-faint)', fontSize: 13 }}>No folders match.</div>
          ) : list.map((f, i) => {
            const on = selected.has(f.id);
            const isActive = (id) => selected.has(id) || hovered === id;
            const active   = isActive(f.id);
            const mergeTop = active && i > 0 && isActive(list[i - 1].id);
            const mergeBot = active && i < list.length - 1 && isActive(list[i + 1].id);
            const topR = mergeTop ? 0 : 8;
            const botR = mergeBot ? 0 : 8;
            const indent = (f._depth || 0) * 16;
            return (
              <button key={f.id} onClick={(e) => { e.stopPropagation(); onToggle(f.id); }}
                onMouseEnter={() => setHovered(f.id)}
                onMouseLeave={() => setHovered(prev => prev === f.id ? null : prev)}
                style={{
                  display: 'flex', alignItems: 'center', gap: 10,
                  width: '100%', padding: `7px 10px 7px ${10 + indent}px`,
                  background: active ? 'var(--bg-soft)' : 'transparent',
                  border: 0,
                  borderRadius: `${topR}px ${topR}px ${botR}px ${botR}px`,
                  color: 'var(--text)', fontSize: 13, textAlign: 'left',
                  cursor: 'pointer',
                }}>
                <span style={{ display: 'inline-flex', width: 18, color: f.color || 'var(--text-faint)', flexShrink: 0 }}>
                  <Icon name={f.icon} size={16}/>
                </span>
                <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{f.name}</span>
                <span style={{ fontSize: 11, color: 'var(--text-faint)', fontVariantNumeric: 'tabular-nums' }}>{f.count}</span>
                <span className={`chk ${on ? 'on' : ''}`} style={{ width: 16, height: 16, borderRadius: 4 }}>
                  {on && <Icon name="check" size={11} stroke={2.5}/>}
                </span>
              </button>
            );
          })}
        </div>

        <div style={{ height: 1, background: 'var(--border)', margin: '4px 4px' }}/>

        {creating ? (
          <div style={{ padding: 6, display: 'flex', flexDirection: 'column', gap: 6 }}>
            {pickerOpen && (
              <div style={{
                padding: 8, borderRadius: 8,
                background: 'var(--bg-soft)',
                border: '1px solid var(--border-soft)',
                display: 'flex', flexDirection: 'column', gap: 8,
              }}>
                {/* Color row */}
                <div style={{ display: 'flex', gap: 6, justifyContent: 'space-between' }}>
                  {FOLDER_COLOR_OPTIONS.map((c) => {
                    const on = iconChoice.color === c;
                    return (
                      <button key={c}
                        onClick={() => setIconChoice(s => ({ ...s, color: c }))}
                        aria-label={`Color ${c}`}
                        style={{
                          width: 22, height: 22, borderRadius: 999,
                          border: on ? '2px solid var(--text)' : '1px solid var(--border)',
                          background: c,
                          padding: 0, cursor: 'pointer',
                          boxShadow: on ? '0 0 0 2px var(--bg-soft)' : 'none',
                          flexShrink: 0,
                        }}/>
                    );
                  })}
                </div>
                {/* Icon grid */}
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 4 }}>
                  {FOLDER_ICON_OPTIONS.map((ic) => {
                    const on = iconChoice.icon === ic;
                    return (
                      <button key={ic}
                        onClick={() => setIconChoice(s => ({ ...s, icon: ic }))}
                        aria-label={`Icon ${ic}`}
                        style={{
                          height: 30, borderRadius: 6,
                          border: on ? '1px solid var(--text)' : '1px solid var(--border-soft)',
                          background: on ? 'var(--bg-surface)' : 'transparent',
                          color: on ? iconChoice.color : 'var(--text-muted)',
                          cursor: 'pointer',
                          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                          transition: 'background .12s, border-color .12s, color .12s',
                        }}
                        onMouseEnter={(e) => { if (!on) { e.currentTarget.style.background = 'var(--bg-surface)'; e.currentTarget.style.color = 'var(--text)'; } }}
                        onMouseLeave={(e) => { if (!on) { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = 'var(--text-muted)'; } }}>
                        <Icon name={ic} size={14}/>
                      </button>
                    );
                  })}
                </div>
              </div>
            )}
            <div style={{ display: 'flex', gap: 6 }}>
              <div className="fld" style={{ flex: 1, minWidth: 0, height: 32, borderRadius: 8, padding: '0 6px 0 4px' }}>
                <button onClick={() => setPickerOpen(v => !v)}
                        aria-label="Choose icon and color"
                        style={{
                          width: 26, height: 26, padding: 0, borderRadius: 6,
                          border: 0, background: pickerOpen ? 'var(--bg-soft)' : 'transparent',
                          color: iconChoice.color,
                          cursor: 'pointer',
                          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                          flexShrink: 0,
                          transition: 'background .12s',
                        }}
                        onMouseEnter={(e) => { if (!pickerOpen) e.currentTarget.style.background = 'var(--bg-soft)'; }}
                        onMouseLeave={(e) => { if (!pickerOpen) e.currentTarget.style.background = 'transparent'; }}>
                  <Icon name={iconChoice.icon} size={14}/>
                </button>
                <input autoFocus value={newName} onChange={(e) => setNewName(e.target.value)}
                       placeholder="Folder name" style={{ fontSize: 13, marginLeft: 4 }}
                       onKeyDown={(e) => {
                         if (e.key === 'Enter') commitNew();
                         else if (e.key === 'Escape') cancelNew();
                       }}/>
              </div>
              <button onClick={commitNew}
                      disabled={!newName.trim()}
                      className="btn btn-primary btn-sm"
                      style={{ height: 32, flexShrink: 0 }}>
                Create
              </button>
            </div>
          </div>
        ) : (
          <button onClick={(e) => { e.stopPropagation(); setCreating(true); }} style={{
            width: '100%', display: 'flex', alignItems: 'center', gap: 10,
            padding: '8px 10px', background: 'transparent', border: 0, borderRadius: 8,
            color: 'var(--accent)', fontSize: 13, fontWeight: 500, cursor: 'pointer',
          }}
          onMouseEnter={(e) => e.currentTarget.style.background = 'var(--bg-soft)'}
          onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
            <Icon name="plus" size={14}/>
            New folder
          </button>
        )}

        {/* Footer — confirm action */}
        <div style={{ height: 1, background: 'var(--border)', margin: '4px 4px' }}/>
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '6px 6px 4px',
        }}>
          <span style={{ fontSize: 12, color: 'var(--text-faint)', paddingLeft: 4 }}>
            {selected.size === 0
              ? 'No folder selected'
              : `${selected.size} folder${selected.size > 1 ? 's' : ''} selected`}
          </span>
          <button onClick={confirm} className="btn btn-primary btn-sm" style={{ height: 30 }}
                  disabled={selected.size === 0}>
            <Icon name="check" size={13} stroke={2.5}/> Done
          </button>
        </div>
      </div>
    </>
  );
};

// Customize-card dropdown — toggle which fields show on each card.
// `fields` is an object of booleans keyed by option id; `options` is
// [{ id, label, icon? }]. `onChange` receives the next fields object.
const CardCustomizeMenu = ({ fields, options, onChange, onClose, anchor = 'right', title = 'Show on cards' }) => (
  <>
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 60 }}/>
    <div role="menu" style={{
      position: 'absolute', top: 'calc(100% + 6px)', [anchor]: 0,
      zIndex: 61, width: 248,
      background: 'var(--bg-surface)',
      border: '1px solid var(--border)',
      borderRadius: 12,
      boxShadow: '0 12px 32px rgba(14,18,27,0.12)',
      padding: 6,
    }}>
      <div style={{
        fontSize: 11, fontWeight: 600, color: 'var(--text-faint)',
        letterSpacing: 0.06, textTransform: 'uppercase',
        padding: '6px 10px 4px',
      }}>{title}</div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 1, maxHeight: 320, overflow: 'auto' }} className="scroll">
        {options.map((o) => {
          const on = !!fields[o.id];
          return (
            <button key={o.id}
              onClick={() => onChange({ ...fields, [o.id]: !on })}
              style={{
                display: 'flex', alignItems: 'center', gap: 10,
                width: '100%', padding: '7px 10px',
                background: 'transparent', border: 0, borderRadius: 8,
                color: 'var(--text)', fontSize: 13, textAlign: 'left',
                cursor: 'pointer',
              }}
              onMouseEnter={(e) => e.currentTarget.style.background = 'var(--bg-muted)'}
              onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
              {o.icon && <Icon name={o.icon} size={14} style={{ color: 'var(--text-muted)' }}/>}
              <span style={{ flex: 1 }}>{o.label}</span>
              <span className={`chk ${on ? 'on' : ''}`} style={{ width: 16, height: 16, borderRadius: 4 }}>
                {on && <Icon name="check" size={11} stroke={2.5}/>}
              </span>
            </button>
          );
        })}
      </div>

      <div style={{ height: 1, background: 'var(--border)', margin: '6px 4px' }}/>

      <div style={{ display: 'flex', gap: 4, padding: 4 }}>
        <button onClick={() => onChange(Object.fromEntries(options.map(o => [o.id, true])))}
          style={{
            flex: 1, height: 28, fontSize: 12, color: 'var(--text-muted)',
            background: 'transparent', border: 0, borderRadius: 6,
            cursor: 'pointer', fontWeight: 500,
          }}>
          Show all
        </button>
        <button onClick={() => onChange(Object.fromEntries(options.map(o => [o.id, false])))}
          style={{
            flex: 1, height: 28, fontSize: 12, color: 'var(--text-muted)',
            background: 'transparent', border: 0, borderRadius: 6,
            cursor: 'pointer', fontWeight: 500,
          }}>
          Hide all
        </button>
      </div>
    </div>
  </>
);

// Reusable sort dropdown — opened from a chip trigger.
// `options` is an array of { id, label, icon? } and `value` is the active id.
const SortMenuV3 = ({ options, value, direction = 'desc', onChange, onDirectionChange, onClose, anchor = 'right' }) => {
  const active = options.find(o => o.id === value) || options[0];
  return (
    <>
      <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 60 }}/>
      <div role="menu" style={{
        position: 'absolute', top: 'calc(100% + 6px)', [anchor]: 0,
        zIndex: 61, width: 240,
        background: 'var(--bg-surface)',
        border: '1px solid var(--border)',
        borderRadius: 12,
        boxShadow: '0 12px 32px rgba(14,18,27,0.12)',
        padding: 6,
      }}>
        <div style={{
          fontSize: 11, fontWeight: 600, color: 'var(--text-faint)',
          letterSpacing: 0.06, textTransform: 'uppercase',
          padding: '6px 10px 4px',
        }}>Sort by</div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
          {options.map((o) => {
            const isActive = o.id === active.id;
            return (
              <button key={o.id}
                onClick={() => { onChange(o.id); onClose && onClose(); }}
                style={{
                  display: 'flex', alignItems: 'center', gap: 10,
                  width: '100%', padding: '8px 10px',
                  background: isActive ? 'var(--bg-soft)' : 'transparent',
                  border: 0, borderRadius: 8,
                  color: 'var(--text)', fontSize: 13, fontWeight: isActive ? 500 : 400,
                  textAlign: 'left', cursor: 'pointer',
                }}
                onMouseEnter={(e) => { if (!isActive) e.currentTarget.style.background = 'var(--bg-muted)'; }}
                onMouseLeave={(e) => { if (!isActive) e.currentTarget.style.background = 'transparent'; }}>
                {o.icon && <Icon name={o.icon} size={14} style={{ color: 'var(--text-muted)' }}/>}
                <span style={{ flex: 1 }}>{o.label}</span>
                {isActive && <Icon name="check" size={14} style={{ color: 'var(--accent)' }}/>}
              </button>
            );
          })}
        </div>

        <div style={{ height: 1, background: 'var(--border)', margin: '6px 4px' }}/>

        <div style={{ display: 'flex', gap: 4, padding: 4 }}>
          {[
            { id: 'desc', label: 'Descending', icon: 'arrow-down' },
            { id: 'asc',  label: 'Ascending',  icon: 'arrow-up' },
          ].map((d) => {
            const on = direction === d.id;
            return (
              <button key={d.id}
                onClick={() => { onDirectionChange && onDirectionChange(d.id); }}
                style={{
                  flex: 1,
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
                  height: 30, padding: '0 8px',
                  background: on ? 'var(--accent-soft)' : 'transparent',
                  color: on ? 'var(--accent)' : 'var(--text-muted)',
                  border: 0, borderRadius: 7,
                  fontSize: 12, fontWeight: 500, cursor: 'pointer',
                }}>
                <Icon name={d.icon} size={12}/> {d.label}
              </button>
            );
          })}
        </div>
      </div>
    </>
  );
};

const SortRowV3 = ({
  count,
  countLabel = 'ads found',
  sort,
  sortOptions,
  direction = 'desc',
  onSort,
  onDirection,
  leftExtra,
  cardFields,
  cardFieldOptions,
  onCardFieldsChange,
  cardFieldsTitle,
}) => {
  const [open, setOpen] = React.useState(false);
  const [custOpen, setCustOpen] = React.useState(false);
  const opts = sortOptions || [{ id: sort || 'budget', label: sort || 'Budget Spent' }];
  const active = opts.find(o => o.id === sort) || opts[0];
  return (
    <div className="sort-row">
      <div style={{ display: 'flex', alignItems: 'center', gap: 14, color: 'var(--text-muted)', fontSize: 13 }}>
        <span><b style={{ color: 'var(--text)' }}>{count.toLocaleString('en-US')}</b> {countLabel}</span>
        {leftExtra}
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <div style={{ position: 'relative' }}>
          <button className="chip" style={{ height: 28, fontSize: 12, color: open ? 'var(--accent)' : 'var(--text)', borderColor: open ? 'var(--accent-soft)' : undefined, background: open ? 'var(--accent-soft)' : undefined }}
                  onClick={() => setOpen(v => !v)}>
            <Icon name={direction === 'asc' ? 'arrow-up' : 'sort-desc'} size={14}/> {active.label}
            <Icon name="arrow-down-s" size={14}/>
          </button>
          {open && (
            <SortMenuV3
              options={opts}
              value={active.id}
              direction={direction}
              onChange={(id) => onSort && onSort(id)}
              onDirectionChange={(d) => onDirection && onDirection(d)}
              onClose={() => setOpen(false)}
            />
          )}
        </div>
        {cardFields && cardFieldOptions && (
          <div style={{ position: 'relative' }}>
            <button className="chip" style={{
              height: 28, fontSize: 12,
              color: custOpen ? 'var(--accent)' : 'var(--text)',
              borderColor: custOpen ? 'var(--accent-soft)' : undefined,
              background: custOpen ? 'var(--accent-soft)' : undefined,
            }}
            onClick={() => setCustOpen(v => !v)}>
              <Icon name="eye" size={14}/> Customize
              <Icon name="arrow-down-s" size={14}/>
            </button>
            {custOpen && (
              <CardCustomizeMenu
                fields={cardFields}
                options={cardFieldOptions}
                onChange={(next) => onCardFieldsChange && onCardFieldsChange(next)}
                onClose={() => setCustOpen(false)}
                title={cardFieldsTitle}
              />
            )}
          </div>
        )}
      </div>
    </div>
  );
};

Object.assign(window, { SidebarV3, PageHeader, SegToggle, FilterStripV3, SortRowV3, SortMenuV3, CardCustomizeMenu, SaveToFolderPopup, FolderTreeItem, flattenFolderTree });
