// ─── Settings Module ─────────────────────────────────────
function SettingsModule(props) {
  var user = props.user, userRecord = props.userRecord, role = props.role, meta = props.meta, cards = props.cards, MEDIA_TYPES = props.MEDIA_TYPES, db = props.db, showToast = props.showToast;
  var tasteProfile = props.tasteProfile;
  var brandSettings = props.brandSettings;

  // Team roster state
  var [teamUsers, setTeamUsers] = useState({});
  var [pendingUsers, setPendingUsers] = useState({});
  var [inviteEmail, setInviteEmail] = useState('');
  var [inviteRole, setInviteRole] = useState('captain');
  var [inviteDisplayName, setInviteDisplayName] = useState('');
  var [inviting, setInviting] = useState(false);

  useEffect(function() {
    var usersRef = db.ref('users');
    var pendingRef = db.ref('pending_users');
    usersRef.on('value', function(snap) { setTeamUsers(snap.val() || {}); });
    pendingRef.on('value', function(snap) { setPendingUsers(snap.val() || {}); });
    return function() { usersRef.off(); pendingRef.off(); };
  }, []);

  function handleInvite(e) {
    e.preventDefault();
    if (!inviteEmail || !inviteRole) return;
    setInviting(true);
    var emailKey = inviteEmail.trim().toLowerCase().replace(/\./g, ',');
    db.ref('pending_users/' + emailKey).set({
      email: inviteEmail.trim().toLowerCase(),
      role: inviteRole,
      display_name: inviteDisplayName.trim() || inviteEmail.split('@')[0],
      invited_by: user.uid,
      invited_at: new Date().toISOString()
    }).then(function() {
      setInviting(false);
      setInviteEmail('');
      setInviteDisplayName('');
      showToast('INVITE SENT');
    }).catch(function(err) {
      setInviting(false);
      showToast('INVITE FAILED: ' + err.message);
    });
  }

  function deletePendingInvite(emailKey) {
    db.ref('pending_users/' + emailKey).remove().then(function() {
      showToast('INVITE REMOVED');
    }).catch(function(err) {
      showToast('REMOVE FAILED: ' + err.message);
    });
  }

  // Default taste profile assembled from brand data (canon source of truth).
  // Falls back to a hardcoded default if BrandData hasn't loaded.
  var DEFAULT_TASTE_PROFILE = (function() {
    var bd = window.BrandData;
    if (bd && bd.voice && bd.content) {
      var v = bd.voice;
      var c = bd.content;
      return "## Brand Voice Profile\n\n### Identity\n- Brand: Lineconic\n- Voice: Chloe\n- Tone: Detached, observational, dissociative glamour\n\n### Setup Rules\n- Format: Second person, present tense, lowercase. Always.\n- Three tests: specific enough to screenshot, personal enough to feel like an attack, NOT generic enough to apply to everyone\n- Dead categories: " + c.setup_rules.dead_categories.map(function(d) { return '"' + d.split(' (')[0].replace(/^"|"$/g, '') + '"'; }).join(', ') + "\n- Working categories: \"finding out your...\", \"telling yourself...\", \"watching your best friend...\", scenario paint\n\n### Voice Rules\n- Lowercase always. No capitals except proper nouns.\n- Detached, observational. Never enthusiastic. Never exclamation marks.\n- Dissociative glamour. She doesn't try — she just is.\n- Never use: \"community\", \"content\", \"We're so excited to announce\", \"Partnering with\"\n\n### Sign-off Rules\n- One-line commentary. Lowercase. A verdict, not a description.\n- 1 sentence max. Often a fragment. Period at the end.\n- Examples: " + v.signoff_pool.map(function(s) { return '"' + s + '"'; }).join(', ') + "\n\n### Reference Preferences\n- Prefer lines of 6 words or fewer (acronym puzzle constraint)\n- Mix mediums: " + c.media_types.slips.join(', ') + "\n- Iconic > obscure, but fresh > overused";
    }
    return "## Brand Voice Profile\n\n### Identity\n- Brand: Lineconic\n- Voice: Chloe\n- Tone: Detached, observational, dissociative glamour\n\n### Setup Rules\n- Format: Second person, present tense, lowercase. Always.\n- Three tests: specific enough to screenshot, personal enough to feel like an attack, NOT generic enough to apply to everyone\n- Dead categories: \"That feeling when...\", \"Me when...\", \"When you...\", \"Nobody: / Me:\", \"POV:\"\n- Working categories: \"finding out your...\", \"telling yourself...\", \"watching your best friend...\", scenario paint\n\n### Voice Rules\n- Lowercase always. No capitals except proper nouns.\n- Detached, observational. Never enthusiastic. Never exclamation marks.\n- Dissociative glamour. She doesn't try — she just is.\n- Never use: \"community\", \"content\", \"We're so excited to announce\", \"Partnering with\"\n\n### Sign-off Rules\n- One-line commentary. Lowercase. A verdict, not a description.\n- 1 sentence max. Often a fragment. Period at the end.\n- Examples: \"you knew.\", \"if you know, you know.\", \"culturally sound.\", \"receipts don't lie.\", \"the group chat needs therapy.\"\n\n### Reference Preferences\n- Prefer lines of 6 words or fewer (acronym puzzle constraint)\n- Mix mediums: film, tv, music, internet\n- Iconic > obscure, but fresh > overused";
  })();

  var [tpContent, setTpContent] = useState(tasteProfile ? tasteProfile.content || '' : '');
  var [tpSaving, setTpSaving] = useState(false);

  useEffect(function() {
    if (tasteProfile && tasteProfile.content !== undefined) {
      setTpContent(tasteProfile.content);
    }
  }, [tasteProfile]);

  function saveTasteProfile() {
    setTpSaving(true);
    db.ref('taste_profile').set({ content: tpContent, updated_at: new Date().toISOString() }).then(function() {
      setTpSaving(false);
      showToast('TASTE PROFILE SAVED');
    }).catch(function(e) { setTpSaving(false); showToast('SAVE FAILED: ' + e.message); });
  }

  function resetTasteProfile() {
    setTpContent(DEFAULT_TASTE_PROFILE);
  }

  // Brand settings state
  var [brandName, setBrandName] = useState(brandSettings && brandSettings.display_name || 'lineconic');
  var [brandHandle, setBrandHandle] = useState(brandSettings && brandSettings.handle || '@lineconic');
  var [brandPicUrl, setBrandPicUrl] = useState(brandSettings && brandSettings.profile_pic_url || '');
  var [brandLineColor, setBrandLineColor] = useState(brandSettings && brandSettings.line_color || '#00FFFF');
  var [brandLineWeight, setBrandLineWeight] = useState(brandSettings && brandSettings.line_weight || 4);
  var [brandCardBg, setBrandCardBg] = useState(brandSettings && brandSettings.card_bg || '');
  var [brandSaving, setBrandSaving] = useState(false);

  useEffect(function() {
    if (brandSettings) {
      if (brandSettings.display_name !== undefined) setBrandName(brandSettings.display_name);
      if (brandSettings.handle !== undefined) setBrandHandle(brandSettings.handle);
      if (brandSettings.profile_pic_url !== undefined) setBrandPicUrl(brandSettings.profile_pic_url);
      if (brandSettings.line_color !== undefined) setBrandLineColor(brandSettings.line_color);
      if (brandSettings.line_weight !== undefined) setBrandLineWeight(brandSettings.line_weight);
      if (brandSettings.card_bg !== undefined) setBrandCardBg(brandSettings.card_bg);
    }
  }, [brandSettings]);

  function saveBrandSettings() {
    setBrandSaving(true);
    db.ref('brand_settings').set({
      display_name: brandName,
      handle: brandHandle,
      profile_pic_url: brandPicUrl,
      line_color: brandLineColor,
      line_weight: Number(brandLineWeight) || 4,
      card_bg: brandCardBg,
      updated_at: new Date().toISOString()
    }).then(function() {
      setBrandSaving(false);
      showToast('BRAND SETTINGS SAVED');
    }).catch(function(e) { setBrandSaving(false); showToast('SAVE FAILED: ' + e.message); });
  }

  var cardArray = useMemo(function() {
    if (!cards) return [];
    return Object.values(cards);
  }, [cards]);

  var tokenPreview = [
    {name:'--void',val:'#000000'},{name:'--signal',val:'#FF007F'},{name:'--cyan',val:'#00FFFF'},
    {name:'--gold',val:'#FFD700'},{name:'--surface',val:'#0A0A0A'},{name:'--surface-2',val:'#111111'},
    {name:'--surface-3',val:'#1A1A1A'},{name:'--border',val:'#2A2A2A'},{name:'--text',val:'#E0E0E0'},
    {name:'--text-sec',val:'#888888'},{name:'--text-dim',val:'#555555'}
  ];

  var [isMobile, setIsMobile] = useState(window.innerWidth < 768);
  useEffect(function(){
    function onResize(){setIsMobile(window.innerWidth < 768)}
    window.addEventListener('resize', onResize);
    return function(){window.removeEventListener('resize', onResize)};
  },[]);

  return (
    <div style={{padding:isMobile?12:24,overflow:'auto',height:'100%',maxWidth:800}}>
      {/* Team */}
      <div className="A-section">
        <div className="A-section-head">TEAM</div>
        <div style={{fontSize:12,marginBottom:8}}>
          <span style={{color:'var(--text-sec)'}}>You: </span>
          <span style={{color:'#fff'}}>{user.email}</span>
          <span style={{fontSize:9,padding:'2px 8px',border:'1px solid var(--signal)',color:'var(--signal)',letterSpacing:'.08em',textTransform:'uppercase',marginLeft:8}}>{role}</span>
        </div>
        <div style={{fontSize:12,marginBottom:16}}>
          <span style={{color:'var(--text-sec)'}}>UID: </span>
          <span style={{color:'var(--text-dim)',fontSize:10}}>{user.uid}</span>
        </div>

        {/* Team Members */}
        <div style={{marginBottom:16,overflowX:isMobile?'auto':'visible'}}>
          <div style={{fontSize:10,color:'var(--text-sec)',marginBottom:8,letterSpacing:'.06em',textTransform:'uppercase'}}>Members</div>
          {Object.keys(teamUsers).map(function(uid) {
            var u = teamUsers[uid];
            return <div key={uid} style={{display:'flex',justifyContent:'space-between',alignItems:'center',padding:'6px 0',borderBottom:'1px solid rgba(42,42,42,.3)',fontSize:11}}>
              <div>
                <span style={{color:'#fff'}}>{u.display_name || u.email}</span>
                <span style={{color:'var(--text-dim)',marginLeft:8,fontSize:10}}>{u.email}</span>
              </div>
              <span style={{fontSize:9,padding:'2px 6px',border:'1px solid var(--border)',color:'var(--text-sec)',letterSpacing:'.06em',textTransform:'uppercase'}}>{u.role}</span>
            </div>;
          })}
        </div>

        {/* Pending Invites */}
        {Object.keys(pendingUsers).length > 0 && (
          <div style={{marginBottom:16}}>
            <div style={{fontSize:10,color:'var(--text-sec)',marginBottom:8,letterSpacing:'.06em',textTransform:'uppercase'}}>Pending Invites</div>
            {Object.keys(pendingUsers).map(function(emailKey) {
              var p = pendingUsers[emailKey];
              return <div key={emailKey} style={{display:'flex',justifyContent:'space-between',alignItems:'center',padding:'6px 0',borderBottom:'1px solid rgba(42,42,42,.3)',fontSize:11}}>
                <div>
                  <span style={{color:'var(--text-sec)'}}>{p.email}</span>
                  <span style={{color:'var(--text-dim)',marginLeft:8,fontSize:10}}>{p.role}</span>
                </div>
                {role === 'founder' && <button className="A-btn danger" style={{fontSize:9,padding:'2px 8px'}} onClick={function(){deletePendingInvite(emailKey)}}>REMOVE</button>}
              </div>;
            })}
          </div>
        )}

        {/* Invite Form (founder only) */}
        {role === 'founder' && (
          <div style={{borderTop:'1px solid var(--border)',paddingTop:12}}>
            <div style={{fontSize:10,color:'var(--text-sec)',marginBottom:8,letterSpacing:'.06em',textTransform:'uppercase'}}>Add User</div>
            <form onSubmit={handleInvite} style={{display:'flex',flexDirection:'column',gap:8}}>
              <input className="A-input" type="email" placeholder="EMAIL" value={inviteEmail} onChange={function(e){setInviteEmail(e.target.value)}} required />
              <input className="A-input" placeholder="DISPLAY NAME" value={inviteDisplayName} onChange={function(e){setInviteDisplayName(e.target.value)}} />
              <select className="A-input" value={inviteRole} onChange={function(e){setInviteRole(e.target.value)}}>
                <option value="captain">CAPTAIN</option>
                <option value="admin">ADMIN</option>
                <option value="viewer">VIEWER</option>
              </select>
              <button type="submit" className="A-btn signal" style={{padding:'8px 14px'}} disabled={inviting}>{inviting ? 'INVITING...' : 'INVITE'}</button>
            </form>
          </div>
        )}

        <div style={{marginTop:16}}>
          <button className="A-btn" onClick={function(){firebase.auth().signOut()}}>SIGN OUT</button>
        </div>
      </div>

      {/* Restore from GitHub (founder only) */}
      {role === 'founder' && (
        <div className="A-section">
          <div className="A-section-head">DATA BACKUP & RESTORE</div>
          <div style={{fontSize:10,color:'var(--text-sec)',marginBottom:12}}>Restore Firebase data from the GitHub backup in lineconic-design/core/data/. This overwrites the current Firebase data with the last published version.</div>
          <RestorePanel user={user} showToast={showToast} />
        </div>
      )}

      {/* Brand Identity & Drop Settings */}
      <div className="A-section">
        <div className="A-section-head">BRAND IDENTITY</div>
        <div style={{fontSize:10,color:'var(--text-sec)',marginBottom:12}}>Display name, handle, and profile pic used in Studio live preview and renders.</div>
        <div style={{display:'flex',gap:12,marginBottom:12}}>
          <div style={{flex:1}}>
            <label className="A-label">Display Name</label>
            <input className="A-input" value={brandName} onChange={function(e){setBrandName(e.target.value)}} placeholder="lineconic" />
          </div>
          <div style={{flex:1}}>
            <label className="A-label">Handle</label>
            <input className="A-input" value={brandHandle} onChange={function(e){setBrandHandle(e.target.value)}} placeholder="@lineconic" />
          </div>
        </div>
        <div style={{marginBottom:12}}>
          <label className="A-label">Profile Pic</label>
          <div style={{display:'flex',gap:12,alignItems:'center'}}>
            {brandPicUrl
              ? <img src={brandPicUrl} style={{width:48,height:48,borderRadius:'50%',objectFit:'cover',border:'1px solid var(--border)',flexShrink:0}} />
              : <div style={{width:48,height:48,borderRadius:'50%',background:'#333',border:'1px solid var(--border)',flexShrink:0}}></div>
            }
            <div style={{flex:1}}>
              <input type="file" accept="image/*" style={{display:'none'}} id="brand-pic-upload" onChange={function(e) {
                var file = e.target.files && e.target.files[0];
                if (!file) return;
                if (file.size > 200000) { showToast('IMAGE TOO LARGE (200KB MAX)'); return; }
                var reader = new FileReader();
                reader.onload = function(ev) { setBrandPicUrl(ev.target.result); };
                reader.readAsDataURL(file);
              }} />
              <div style={{display:'flex',gap:6}}>
                <button className="A-btn cyan" style={{fontSize:9,padding:'4px 10px'}} onClick={function(){document.getElementById('brand-pic-upload').click()}}>UPLOAD</button>
                {brandPicUrl && <button className="A-btn danger" style={{fontSize:9,padding:'4px 10px'}} onClick={function(){setBrandPicUrl('')}}>REMOVE</button>}
              </div>
              <div style={{fontSize:9,color:'var(--text-dim)',marginTop:4}}>Max 200KB. Stored as base64.</div>
            </div>
          </div>
        </div>

        <div className="A-section-head" style={{marginTop:16}}>DROP RENDER SETTINGS</div>
        <div style={{fontSize:10,color:'var(--text-sec)',marginBottom:12}}>Accent line colour, weight, and card background for rendered drops.</div>
        <div style={{display:'flex',gap:12,marginBottom:12,alignItems:'end'}}>
          <div>
            <label className="A-label">Line Colour</label>
            <div style={{display:'flex',gap:8,alignItems:'center'}}>
              <input type="color" value={brandLineColor} onChange={function(e){setBrandLineColor(e.target.value)}} style={{width:32,height:32,border:'1px solid var(--border)',background:'transparent',cursor:'pointer',padding:0}} />
              <input className="A-input" value={brandLineColor} onChange={function(e){setBrandLineColor(e.target.value)}} style={{width:90,fontSize:10}} />
            </div>
          </div>
          <div>
            <label className="A-label">Line Weight (px)</label>
            <input className="A-input" type="number" min="1" max="20" value={brandLineWeight} onChange={function(e){setBrandLineWeight(e.target.value)}} style={{width:60}} />
          </div>
        </div>
        <div style={{marginBottom:12}}>
          <label className="A-label">Card Background (optional override)</label>
          <input className="A-input" value={brandCardBg} onChange={function(e){setBrandCardBg(e.target.value)}} placeholder="e.g., #15202b or leave empty for theme default" />
        </div>
        {/* Preview swatch */}
        <div style={{display:'flex',alignItems:'center',gap:12,marginBottom:12}}>
          <div style={{width:120,height:24,background:brandCardBg || '#15202b',border:'1px solid var(--border)',position:'relative',overflow:'hidden'}}>
            <div style={{position:'absolute',bottom:0,left:0,right:0,height:Number(brandLineWeight)||4,background:brandLineColor}}></div>
          </div>
          <span style={{fontSize:9,color:'var(--text-dim)',letterSpacing:1}}>PREVIEW</span>
        </div>
        <button className="A-btn signal" onClick={saveBrandSettings} disabled={brandSaving}>{brandSaving ? 'SAVING...' : 'SAVE BRAND SETTINGS'}</button>
        {brandSettings && brandSettings.updated_at && (
          <span style={{fontSize:9,color:'var(--text-dim)',letterSpacing:1,marginLeft:12}}>UPDATED: {new Date(brandSettings.updated_at).toLocaleString()}</span>
        )}
      </div>

      {/* Taste Profile */}
      <div className="A-section">
        <div className="A-section-head">TASTE PROFILE</div>
        <div style={{fontSize:10,color:'var(--text-sec)',marginBottom:8}}>Voice profile injected into AI generation prompts. Markdown format.</div>
        <textarea className="A-textarea" rows="20" value={tpContent} onChange={function(e){setTpContent(e.target.value)}} style={{fontFamily:'monospace',fontSize:11,lineHeight:1.5}} />
        <div style={{display:'flex',gap:8,marginTop:8,alignItems:'center'}}>
          <button className="A-btn signal" onClick={saveTasteProfile} disabled={tpSaving}>{tpSaving ? 'SAVING...' : 'SAVE'}</button>
          <button className="A-btn" onClick={resetTasteProfile}>RESET TO DEFAULT</button>
          {tasteProfile && tasteProfile.updated_at && (
            <span style={{fontSize:9,color:'var(--text-dim)',letterSpacing:1,marginLeft:'auto'}}>UPDATED: {new Date(tasteProfile.updated_at).toLocaleString()}</span>
          )}
        </div>
      </div>

      {/* Card Library Meta */}
      <div className="A-section">
        <div className="A-section-head">CARD LIBRARY META</div>
        {meta && (
          <div style={{fontSize:11}}>
            <div style={{marginBottom:4}}><span style={{color:'var(--text-sec)'}}>Version: </span><span style={{color:'#fff'}}>{meta.version||'—'}</span></div>
            <div style={{marginBottom:4}}><span style={{color:'var(--text-sec)'}}>Total Cards: </span><span style={{color:'#fff'}}>{meta.total_cards||cardArray.length}</span></div>
            <div style={{marginBottom:4}}><span style={{color:'var(--text-sec)'}}>Last Published: </span><span style={{color:'#fff'}}>{meta.last_published ? new Date(meta.last_published).toLocaleString() : '—'}</span></div>
          </div>
        )}
      </div>

      {/* DOA Topic Pool */}
      <div className="A-section">
        <div className="A-section-head">DOA TOPIC POOL</div>
        <div style={{fontSize:10,color:'var(--text-sec)',marginBottom:8}}>40 topics available for Dead or Alive rounds. Edit in builder.jsx DOA_POOL constant.</div>
        <div style={{display:'flex',flexWrap:'wrap',gap:4}}>
          {['SKINNY JEANS','ROM COMS','LAUGH TRACKS','NEPO BABIES','MARVEL PHASE 5','REALITY TV','A24','MOVIE THEATRES','CRYPTO','VINYL RECORDS','FAST FASHION','PODCASTS','NFTs','K-POP','CABLE TV','THRIFT SHOPPING','TRUE CRIME DOCS','BRUNCH CULTURE','SITUATIONSHIPS','CROCS'].map(function(t) {
            return <span key={t} style={{padding:'3px 8px',border:'1px solid var(--border)',fontSize:9,color:'var(--text-sec)',textTransform:'uppercase',letterSpacing:'.04em'}}>{t}</span>;
          })}
          <span style={{padding:'3px 8px',fontSize:9,color:'var(--text-dim)'}}>+20 more</span>
        </div>
      </div>

      {/* Design Token Preview */}
      <div className="A-section">
        <div className="A-section-head">DESIGN TOKENS</div>
        <div style={{display:'grid',gridTemplateColumns:'repeat(auto-fill,minmax(140px,1fr))',gap:8}}>
          {tokenPreview.map(function(t) {
            return <div key={t.name} style={{display:'flex',alignItems:'center',gap:8,padding:8,border:'1px solid var(--border)'}}>
              <div style={{width:24,height:24,background:t.val,border:'1px solid rgba(255,255,255,.1)',flexShrink:0}}></div>
              <div><div style={{fontSize:9,color:'var(--text-sec)'}}>{t.name}</div><div style={{fontSize:10,color:'#fff'}}>{t.val}</div></div>
            </div>;
          })}
        </div>
      </div>

      {/* Font Preview */}
      <div className="A-section">
        <div className="A-section-head">FONTS</div>
        <div style={{marginBottom:12}}>
          <div style={{fontFamily:'var(--display)',fontSize:24,color:'var(--signal)',textTransform:'uppercase',letterSpacing:'.04em'}}>LINECONIC DISPLAY</div>
          <div style={{fontSize:9,color:'var(--text-dim)',marginTop:4}}>Neue Haas Grotesk Display Pro Black</div>
        </div>
        <div>
          <div style={{fontFamily:'var(--mono)',fontSize:14,color:'#fff'}}>LINECONIC MONO 0123456789</div>
          <div style={{fontSize:9,color:'var(--text-dim)',marginTop:4}}>Space Mono 400/700</div>
        </div>
      </div>

      {/* Quick Stats */}
      <div className="A-section">
        <div className="A-section-head">MEDIA TYPE BREAKDOWN</div>
        <div style={{fontSize:11}}>
          {MEDIA_TYPES.map(function(mt) {
            var count = cardArray.filter(function(c){return c.media_type===mt}).length;
            return <div key={mt} style={{display:'flex',justifyContent:'space-between',padding:'4px 0',borderBottom:'1px solid rgba(42,42,42,.3)'}}>
              <span style={{textTransform:'uppercase'}}>{mt}</span>
              <span style={{color:'#fff'}}>{count}</span>
            </div>;
          })}
        </div>
      </div>
    </div>
  );
}

// ─── Restore Panel ──────────────────────────────────────
var RESTORE_COLLECTIONS = [
  { id: 'shows', label: 'Shows' },
  { id: 'templates', label: 'Templates' },
  { id: 'drops', label: 'Drops' },
  { id: 'slips', label: 'Slips' },
  { id: 'hotseat-cards', label: 'Hot Seat Cards' },
  { id: 'creators', label: 'Creators' },
  { id: 'card-stats', label: 'Card Stats' },
  { id: 'show-index', label: 'Show Index' }
];

function RestorePanel(props) {
  var user = props.user, showToast = props.showToast;
  var [restoring, setRestoring] = useState(null);
  var [confirm, setConfirm] = useState(null);

  function handleRestore(collectionId) {
    if (restoring) return;
    if (confirm !== collectionId) {
      setConfirm(collectionId);
      return;
    }
    setConfirm(null);
    setRestoring(collectionId);

    user.getIdToken().then(function(token) {
      return fetch('/api/restore-data', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
        body: JSON.stringify({ collection: collectionId })
      });
    }).then(function(res) { return res.json(); }).then(function(data) {
      setRestoring(null);
      if (data.ok) {
        showToast('RESTORED ' + collectionId.toUpperCase() + ' — ' + data.records + ' RECORDS');
      } else {
        showToast('RESTORE FAILED: ' + (data.error || 'unknown'));
      }
    }).catch(function(err) {
      setRestoring(null);
      showToast('RESTORE FAILED: ' + err.message);
    });
  }

  return React.createElement('div', { style: { display: 'flex', flexWrap: 'wrap', gap: 6 } },
    RESTORE_COLLECTIONS.map(function(col) {
      var isRestoring = restoring === col.id;
      var isConfirming = confirm === col.id;
      return React.createElement('button', {
        key: col.id,
        className: 'A-btn' + (isConfirming ? ' danger' : ''),
        style: { fontSize: 9, padding: '4px 10px', opacity: (restoring && !isRestoring) ? 0.4 : 1 },
        onClick: function() { handleRestore(col.id); },
        disabled: restoring && !isRestoring
      }, isRestoring ? 'RESTORING...' : (isConfirming ? 'CONFIRM ' + col.label.toUpperCase() + '?' : 'RESTORE ' + col.label.toUpperCase()));
    })
  );
}
