// overlays.jsx — Calculator + Settings overlays
// Exports: window.Calculator, window.Settings
const { useState: obUseS, useEffect: obUseE, useRef: obUseR } = React;
const obSeed = window.SisyphusSeed;
const ObIcon = window.Icon;

// ── shared overlay backdrop ──────────────────────────────────────────────────
function Backdrop({ onClose, children, width = 480 }) {
  return (
    <div onClick={onClose} style={{
      position:'fixed', inset:0, zIndex:800,
      background:'rgba(5,3,13,0.75)', backdropFilter:'blur(12px)',
      display:'flex', alignItems:'center', justifyContent:'center',
      padding:'calc(env(safe-area-inset-top, 20px) + 12px) 16px calc(env(safe-area-inset-bottom, 20px) + 12px)',
      animation:'fadeIn 0.15s ease',
    }}>
      <div onClick={e => e.stopPropagation()} style={{
        width:'100%', maxWidth:width,
        maxHeight:'100%', overflowY:'auto', WebkitOverflowScrolling:'touch',
        background:'rgba(14,9,28,0.98)', backdropFilter:'blur(40px)',
        border:'1px solid var(--border-strong)', borderRadius:20,
        padding:'24px', boxShadow:'0 40px 80px rgba(0,0,0,0.6)',
        animation:'popIn 0.2s cubic-bezier(0.2,0.8,0.2,1)',
      }}>
        {children}
      </div>
    </div>
  );
}

function OverlayHeader({ title, onClose }) {
  return (
    <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:20 }}>
      <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:18, fontWeight:600, letterSpacing:'-0.01em' }}>{title}</div>
      <button onClick={onClose} style={{ width:28, height:28, borderRadius:8, background:'rgba(255,255,255,0.06)', border:'none', color:'var(--text-3)', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center' }}>
        <ObIcon name="x" size={13} />
      </button>
    </div>
  );
}

// ── Calculator ───────────────────────────────────────────────────────────────
const CALC_NS = 'sisyphus.v1.calc_';
function calcLoad(key, def) {
  try { const v = localStorage.getItem(CALC_NS + key); return v !== null ? JSON.parse(v) : def; } catch { return def; }
}
function calcSave(key, val) {
  try { localStorage.setItem(CALC_NS + key, JSON.stringify(val)); } catch {}
}

function Calculator({ onClose }) {
  const [tab, setTab]   = obUseS(() => calcLoad('tab', 'fx'));
  // FX state
  const [from, setFrom] = obUseS(() => calcLoad('from', 'ARS'));
  const [amount, setAmount] = obUseS(() => calcLoad('fxAmount', ''));
  const fxBlue = obSeed?.fxBlue || 1480;
  const parsed    = parseFloat(amount.replace(/\./g,'').replace(/,/g,'.')) || 0;
  const converted = from === 'ARS' ? parsed / fxBlue : parsed * fxBlue;
  const fmtARS = n => '$ ' + new Intl.NumberFormat('es-AR').format(Math.round(n));
  const fmtUSD = n => 'US$ ' + new Intl.NumberFormat('en-US', { minimumFractionDigits:2, maximumFractionDigits:2 }).format(n);

  // Basic calc state — persisted in localStorage
  const [display,   setDisplay]   = obUseS(() => calcLoad('display', '0'));
  const [prevVal,   setPrevVal]   = obUseS(() => calcLoad('prevVal', null));
  const [operator,  setOperator]  = obUseS(() => calcLoad('operator', null));
  const [waiting,   setWaiting]   = obUseS(() => calcLoad('waiting', false));

  // Persist on every change
  obUseE(() => { calcSave('tab', tab); }, [tab]);
  obUseE(() => { calcSave('from', from); }, [from]);
  obUseE(() => { calcSave('fxAmount', amount); }, [amount]);
  obUseE(() => { calcSave('display', display); }, [display]);
  obUseE(() => { calcSave('prevVal', prevVal); }, [prevVal]);
  obUseE(() => { calcSave('operator', operator); }, [operator]);
  obUseE(() => { calcSave('waiting', waiting); }, [waiting]);

  // Keyboard support (desktop) — ref keeps calcPress always fresh without extra deps
  const calcPressRef = obUseR(null);
  obUseE(() => { calcPressRef.current = calcPress; });

  obUseE(() => {
    if (tab !== 'basic') return;
    function onKey(e) {
      if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
      const map = {
        '0':'0','1':'1','2':'2','3':'3','4':'4','5':'5','6':'6','7':'7','8':'8','9':'9',
        '.':'.', ',':'.',
        '+':'+', '-':'-', '*':'×', 'x':'×', 'X':'×', '/':'÷',
        'Enter':'=', '=':'=',
        'Backspace':'⌫', 'Delete':'⌫',
        'Escape':'AC', 'c':'AC', 'C':'AC',
        '%':'%',
      };
      const key = map[e.key];
      if (key) { e.preventDefault(); calcPressRef.current?.(key); }
    }
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [tab]);

  function calcPress(key) {
    if (key >= '0' && key <= '9' || key === '.') {
      if (waiting) {
        setDisplay(key === '.' ? '0.' : key);
        setWaiting(false);
      } else {
        if (key === '.' && display.includes('.')) return;
        setDisplay(display === '0' && key !== '.' ? key : display + key);
      }
      return;
    }
    const cur = parseFloat(display);
    if (key === 'AC') { setDisplay('0'); setPrevVal(null); setOperator(null); setWaiting(false); return; }
    if (key === '⌫')  { setDisplay(display.length > 1 ? display.slice(0,-1) : '0'); return; }
    if (key === '+/-') { setDisplay(String(-cur)); return; }
    if (key === '%')   { setDisplay(String(cur / 100)); return; }
    if (['+','-','×','÷'].includes(key)) {
      if (operator && !waiting) {
        const res = applyOp(prevVal, cur, operator);
        setDisplay(fmt(res)); setPrevVal(res);
      } else {
        setPrevVal(cur);
      }
      setOperator(key); setWaiting(true); return;
    }
    if (key === '=') {
      if (!operator) return;
      const res = applyOp(prevVal, cur, operator);
      setDisplay(fmt(res)); setPrevVal(null); setOperator(null); setWaiting(true); return;
    }
  }

  function applyOp(a, b, op) {
    if (op === '+') return a + b;
    if (op === '-') return a - b;
    if (op === '×') return a * b;
    if (op === '÷') return b !== 0 ? a / b : 0;
    return b;
  }
  function fmt(n) {
    if (!isFinite(n)) return 'Error';
    const s = String(Math.round(n * 1e9) / 1e9);
    return s;
  }

  const displayFormatted = (() => {
    if (display === 'Error') return 'Error';
    const n = parseFloat(display);
    if (isNaN(n)) return display;
    const hasDot = display.includes('.');
    const decimals = hasDot ? display.split('.')[1] : '';
    const intPart = new Intl.NumberFormat('es-AR').format(Math.floor(Math.abs(n)));
    const sign = n < 0 ? '-' : '';
    return sign + intPart + (hasDot ? '.' + decimals : '');
  })();

  const ROWS = [
    ['AC', '⌫', '%', '÷'],
    ['7',  '8',  '9', '×'],
    ['4',  '5',  '6', '-'],
    ['1',  '2',  '3', '+'],
    ['+/-','0',  '.', '='],
  ];

  function btnStyle(k) {
    const isOp  = ['÷','×','-','+','='].includes(k);
    const isMod = ['AC','⌫','%','+/-'].includes(k);
    const isActive = operator === k;
    return {
      width:'100%', aspectRatio:'1/1', borderRadius:'50%',
      fontFamily:'Space Grotesk, sans-serif', fontSize: k === 'AC' || k === '⌫' ? 13 : 20,
      fontWeight:600, cursor:'pointer', border:'none',
      background: isActive ? 'var(--on-accent)' :
                  isOp     ? 'var(--accent)' :
                  isMod    ? 'rgba(255,255,255,0.14)' :
                             'rgba(255,255,255,0.07)',
      color: isActive ? 'var(--accent)' :
             isOp     ? 'var(--on-accent)' :
             isMod    ? 'var(--text)' :
                        'var(--text)',
      display:'flex', alignItems:'center', justifyContent:'center',
      transition:'transform 0.08s, background 0.1s',
      WebkitTapHighlightColor:'transparent',
    };
  }

  return (
    <Backdrop onClose={onClose} width={380}>
      <OverlayHeader title="Calculadora" onClose={onClose} />
      {/* Tabs */}
      <div style={{ display:'flex', padding:3, background:'var(--card)', border:'1px solid var(--border)', borderRadius:10, gap:2, marginBottom:20 }}>
        {[{ id:'fx', label:'Cambio' }, { id:'basic', label:'Básica' }].map(t => (
          <button key={t.id} onClick={() => setTab(t.id)} style={{
            flex:1, padding:'9px 0', borderRadius:8,
            background: tab===t.id ? 'var(--accent)' : 'transparent',
            color: tab===t.id ? 'var(--on-accent)' : 'var(--text-2)',
            border:'none', cursor:'pointer', fontFamily:'inherit', fontSize:13.5, fontWeight:600,
            transition:'all 0.14s',
          }}>{t.label}</button>
        ))}
      </div>

      {tab === 'fx' && (
        <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
          <div style={{ fontSize:10, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.12em', fontWeight:700 }}>Convertir desde</div>
          <div style={{ display:'flex', gap:8 }}>
            {['ARS','USD'].map(c => (
              <button key={c} onClick={() => setFrom(c)} style={{
                flex:1, padding:'11px 0', borderRadius:10, fontFamily:'Space Grotesk, sans-serif', fontSize:14, fontWeight:700,
                background: from===c ? 'var(--accent)' : 'rgba(255,255,255,0.04)',
                color: from===c ? 'var(--on-accent)' : 'var(--text-2)',
                border:`1px solid ${from===c ? 'var(--accent)' : 'var(--border)'}`,
                cursor:'pointer', transition:'all 0.14s',
              }}>{c}</button>
            ))}
          </div>
          <div style={{ position:'relative' }}>
            <span style={{ position:'absolute', left:16, top:'50%', transform:'translateY(-50%)', fontSize:18, fontWeight:600, color:'var(--text-3)', fontFamily:'Space Grotesk, sans-serif' }}>{from === 'ARS' ? '$' : 'US$'}</span>
            <input
              type="text" inputMode="numeric"
              value={amount}
              onChange={e => setAmount(e.target.value)}
              placeholder={from === 'ARS' ? '500.000' : '1.000'}
              style={{ width:'100%', padding:'14px 16px 14px 52px', borderRadius:12, background:'rgba(255,255,255,0.05)', border:'1px solid var(--border-strong)', color:'var(--text)', fontFamily:'Space Grotesk, sans-serif', fontSize:22, fontWeight:600, outline:'none', boxSizing:'border-box', transition:'border-color 0.14s' }}
              onFocus={e => e.target.style.borderColor='var(--accent)'}
              onBlur={e => e.target.style.borderColor='var(--border-strong)'}
            />
          </div>
          {parsed > 0 && (
            <div style={{ padding:'18px 20px', borderRadius:14, background:'linear-gradient(135deg, rgba(139,92,246,0.15), rgba(99,102,241,0.1))', border:'1px solid var(--border-strong)', textAlign:'center' }}>
              <div style={{ fontSize:10.5, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.12em', fontWeight:700, marginBottom:8 }}>
                En {from === 'ARS' ? 'dólares' : 'pesos'}
              </div>
              <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:32, fontWeight:700, letterSpacing:'-0.03em', color:'var(--accent-bright)' }}>
                {from === 'ARS' ? fmtUSD(converted) : fmtARS(converted)}
              </div>
              <div style={{ fontSize:11.5, color:'var(--text-3)', marginTop:8 }}>Dólar blue · {fmtARS(fxBlue)} por US$1</div>
            </div>
          )}
        </div>
      )}

      {tab === 'basic' && (
        <div style={{ display:'flex', flexDirection:'column', gap:0 }}>
          {/* Display */}
          <div style={{ padding:'12px 8px 18px', textAlign:'right', minHeight:80, display:'flex', flexDirection:'column', justifyContent:'flex-end', gap:4 }}>
            {operator && (
              <div style={{ fontSize:13, color:'var(--text-3)', fontFamily:'Space Grotesk, sans-serif' }}>
                {new Intl.NumberFormat('es-AR').format(parseFloat(String(prevVal)))} {operator}
              </div>
            )}
            <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize: displayFormatted.length > 9 ? 28 : 40, fontWeight:300, letterSpacing:'-0.02em', color:'var(--text)', lineHeight:1, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
              {displayFormatted}
            </div>
          </div>
          {/* Button grid */}
          <div style={{ display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:10 }}>
            {ROWS.flat().map(k => (
              <button
                key={k}
                onClick={() => calcPress(k)}
                style={btnStyle(k)}
                onMouseDown={e => { e.currentTarget.style.transform='scale(0.93)'; }}
                onMouseUp={e => { e.currentTarget.style.transform='scale(1)'; }}
                onTouchStart={e => { e.currentTarget.style.transform='scale(0.93)'; }}
                onTouchEnd={e => { e.currentTarget.style.transform='scale(1)'; }}
              >
                {k}
              </button>
            ))}
          </div>
        </div>
      )}
    </Backdrop>
  );
}

// ── Settings ─────────────────────────────────────────────────────────────────
function Settings({ onClose, onEdit, userName, onUserNameChange, ccy, onCcy, profilePhoto, onProfileChange, spentState, budgets, onBudgetsChange }) {
  const NS = 'sisyphus.v1.';
  const [settTab, setSettTab] = obUseS('general');
  const [accent, setAccent] = obUseS(() => document.documentElement.getAttribute('data-accent') || 'violet');
  const [notifPayments, setNotifPayments] = obUseS(() => {
    try { return JSON.parse(localStorage.getItem(NS + 'notif_payments') ?? 'true'); } catch { return true; }
  });
  const [notifBudget, setNotifBudget] = obUseS(() => {
    try { return JSON.parse(localStorage.getItem(NS + 'notif_budget') ?? 'true'); } catch { return true; }
  });
  const [notifBank, setNotifBank] = obUseS(() => {
    try { return JSON.parse(localStorage.getItem(NS + 'notif_bank') ?? 'false'); } catch { return false; }
  });
  const [editingName, setEditingName] = obUseS(false);
  const [nameInput, setNameInput] = obUseS(userName || '');

  const accents = [
    { id:'violet', label:'Violeta', color:'#a78bfa' },
    { id:'indigo', label:'Índigo',  color:'#818cf8' },
    { id:'rose',   label:'Rosa',    color:'#f472b6' },
  ];

  function applyAccent(id) {
    setAccent(id);
    if (id === 'violet') { document.documentElement.removeAttribute('data-accent'); }
    else { document.documentElement.setAttribute('data-accent', id); }
    localStorage.setItem(NS + 'accent', id);
  }

  function saveName() {
    const n = nameInput.trim();
    if (n && onUserNameChange) onUserNameChange(n);
    setEditingName(false);
  }

  const sectionLabel = (txt) => (
    <div style={{ fontSize:10, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.12em', fontWeight:700, marginBottom:10, marginTop:4 }}>{txt}</div>
  );

  const toggle = (val, set, storageKey) => (
    <button onClick={() => { const n = !val; set(n); localStorage.setItem(NS + storageKey, JSON.stringify(n)); }} style={{
      width:44, height:24, borderRadius:999, padding:'2px 3px',
      background: val ? 'var(--accent)' : 'rgba(255,255,255,0.12)',
      border:'none', cursor:'pointer', transition:'background 0.2s',
      display:'flex', alignItems:'center', justifyContent: val ? 'flex-end' : 'flex-start',
    }}>
      <div style={{ width:18, height:18, borderRadius:'50%', background:'white', boxShadow:'0 1px 4px rgba(0,0,0,0.3)', transition:'all 0.2s' }} />
    </button>
  );

  // ── Gmail tab state ──────────────────────────────────────────────────────────
  const [gmailConnected, setGmailConnected] = obUseS(() => window.GmailAPI?.isConnected?.() || false);
  const [syncToken, setSyncToken] = obUseS(() => localStorage.getItem('sisyphus.v1.auth_token') || '');
  const [syncSaved, setSyncSaved] = obUseS(false);
  function saveSyncToken() {
    const t = syncToken.trim();
    if (!t) return;
    localStorage.setItem('sisyphus.v1.auth_token', t);
    setSyncSaved(true);
    window.SisyStorage?.schedulePush?.();
    setTimeout(() => setSyncSaved(false), 2000);
  }
  const [gmailClientId, setGmailClientId]   = obUseS(() => window.GmailAPI?.getClientId?.() || '');
  const [gmailSyncing,  setGmailSyncing]    = obUseS(false);
  const [gmailStatus,   setGmailStatus]     = obUseS('');
  const [gmailLastSync, setGmailLastSync]   = obUseS(() => {
    try { return JSON.parse(localStorage.getItem('sis_gmail_last_sync') || 'null'); } catch { return null; }
  });

  function gmailConnect() {
    if (!window.GmailAPI) { setGmailStatus('GmailAPI no disponible'); return; }
    window.GmailAPI.saveClientId(gmailClientId);
    window.GmailAPI.connect(err => {
      if (err) { setGmailStatus('Error: ' + err.message); return; }
      setGmailConnected(true);
      setGmailStatus('Conectado ✓');
    });
  }
  function gmailSync() {
    if (!window.GmailAPI?.isConnected?.()) return;
    setGmailSyncing(true); setGmailStatus('Sincronizando...');
    window.GmailAPI.sync((i, total) => setGmailStatus(`Procesando ${i+1}/${total}...`))
      .then(txns => {
        const now = new Date().toISOString();
        setGmailLastSync(now); setGmailSyncing(false);
        setGmailStatus(`✓ ${txns.length} movimiento${txns.length!==1?'s':''} importado${txns.length!==1?'s':''}`);
        if (txns.length > 0 && window._onGmailTxns) window._onGmailTxns(txns);
      })
      .catch(e => { setGmailSyncing(false); setGmailStatus('Error: ' + e.message); });
  }
  function gmailDisconnect() {
    window.GmailAPI?.disconnect?.();
    setGmailConnected(false); setGmailStatus('Desconectado');
  }

  const tabStyle = (id) => ({
    flex:1, padding:'8px 0', borderRadius:8,
    background: settTab===id ? 'var(--accent)' : 'transparent',
    color: settTab===id ? 'var(--on-accent)' : 'var(--text-2)',
    border:'none', cursor:'pointer', fontFamily:'inherit', fontSize:13, fontWeight:600,
    transition:'all 0.14s',
  });

  return (
    <Backdrop onClose={onClose} width={460}>
      <OverlayHeader title="Configuración" onClose={onClose} />

      {/* Tab bar */}
      <div style={{ display:'flex', padding:3, background:'var(--card)', border:'1px solid var(--border)', borderRadius:11, gap:2, marginBottom:20 }}>
        {[['general','General'],['presupuestos','Presupuestos'],['gmail','Gmail']].map(([id, label]) => (
          <button key={id} onClick={() => setSettTab(id)} style={tabStyle(id)}>{label}</button>
        ))}
      </div>

      {/* ── TAB: GENERAL ─────────────────────────────────────────────── */}
      {settTab === 'general' && (<>
        {/* Profile */}
        <div style={{ display:'flex', alignItems:'center', gap:14, padding:'14px 16px', borderRadius:12, background:'rgba(255,255,255,0.03)', border:'1px solid var(--border)', marginBottom:20 }}>
          <div style={{ width:48, height:48, borderRadius:'50%', background: profilePhoto ? 'transparent' : 'linear-gradient(145deg, var(--accent-bright), var(--accent-deep))', overflow:'hidden', display:'flex', alignItems:'center', justifyContent:'center', color:'var(--on-accent)', fontWeight:700, fontSize:18, flexShrink:0 }}>
            {profilePhoto ? <img src={profilePhoto} style={{ width:'100%', height:'100%', objectFit:'cover' }} alt="perfil" /> : (userName||'A').charAt(0).toUpperCase()}
          </div>
          <div style={{ flex:1 }}>
            {editingName ? (
              <div style={{ display:'flex', gap:7 }}>
                <input autoFocus value={nameInput} onChange={e => setNameInput(e.target.value)} onKeyDown={e => { if(e.key==='Enter') saveName(); if(e.key==='Escape') setEditingName(false); }} style={{ flex:1, padding:'7px 10px', borderRadius:8, background:'rgba(255,255,255,0.07)', border:'1px solid var(--accent)', color:'var(--text)', fontFamily:'inherit', fontSize:14, outline:'none' }} />
                <button onClick={saveName} style={{ padding:'7px 12px', borderRadius:8, background:'var(--accent)', color:'var(--on-accent)', border:'none', cursor:'pointer', fontFamily:'inherit', fontSize:12, fontWeight:600 }}>OK</button>
              </div>
            ) : (
              <>
                <div style={{ fontSize:14, fontWeight:600 }}>{userName || 'Usuario'}</div>
                <div style={{ fontSize:12, color:'var(--text-3)' }}>adolfo@sisyphus.app</div>
              </>
            )}
          </div>
          <button onClick={() => onEdit ? onEdit() : null} style={{ padding:'6px 14px', borderRadius:8, background:'var(--accent-dim)', border:'1px solid var(--border-strong)', color:'var(--accent-bright)', cursor:'pointer', fontFamily:'inherit', fontSize:12, fontWeight:600 }}>
            Editar
          </button>
        </div>

        {sectionLabel('Apariencia')}
        <div style={{ marginBottom:16 }}>
          <div style={{ fontSize:12.5, color:'var(--text-3)', marginBottom:10 }}>Color de acento</div>
          <div style={{ display:'flex', gap:10 }}>
            {accents.map(a => (
              <button key={a.id} onClick={() => applyAccent(a.id)} style={{
                flex:1, padding:'12px 8px', borderRadius:11, cursor:'pointer', fontFamily:'inherit',
                background: accent===a.id ? 'rgba(255,255,255,0.07)' : 'rgba(255,255,255,0.025)',
                border:`2px solid ${accent===a.id ? a.color : 'var(--border)'}`,
                display:'flex', flexDirection:'column', alignItems:'center', gap:8, transition:'all 0.14s',
              }}>
                <div style={{ width:28, height:28, borderRadius:'50%', background:a.color, boxShadow: accent===a.id ? `0 0 16px ${a.color}66` : 'none', transition:'box-shadow 0.2s' }} />
                <span style={{ fontSize:11.5, fontWeight:600, color: accent===a.id ? 'var(--text)' : 'var(--text-3)' }}>{a.label}</span>
              </button>
            ))}
          </div>
        </div>

        {sectionLabel('Moneda principal')}
        <div style={{ display:'flex', gap:8, marginBottom:20 }}>
          {['ARS','USD'].map(c => (
            <button key={c} onClick={() => onCcy && onCcy(c)} style={{
              flex:1, padding:'11px 0', borderRadius:10, fontFamily:'inherit', fontSize:14, fontWeight:600,
              background: ccy===c ? 'var(--accent)' : 'rgba(255,255,255,0.04)',
              color: ccy===c ? 'var(--on-accent)' : 'var(--text-2)',
              border:`1px solid ${ccy===c ? 'var(--accent)' : 'var(--border)'}`,
              cursor:'pointer', transition:'all 0.14s',
            }}>{c === 'ARS' ? 'Pesos (ARS)' : 'Dólares (USD)'}</button>
          ))}
        </div>

        {sectionLabel('Notificaciones')}
        <div style={{ display:'flex', flexDirection:'column', gap:8, marginBottom:20 }}>
          {[
            { key:'notif_payments', label:'Vencimientos de pagos',  sub:'Alertas de pagos próximos',       val:notifPayments,  set:setNotifPayments },
            { key:'notif_budget',   label:'Alertas de presupuesto', sub:'Cuando superás el límite de una categoría', val:notifBudget, set:setNotifBudget },
            { key:'notif_bank',     label:'Movimientos del banco',  sub:'Confirmación de movimientos bancarios', val:notifBank, set:setNotifBank },
          ].map(n => (
            <div key={n.key} style={{ display:'flex', alignItems:'center', justifyContent:'space-between', padding:'12px 14px', borderRadius:11, background:'rgba(255,255,255,0.025)', border:'1px solid var(--border)' }}>
              <div>
                <div style={{ fontSize:13.5, fontWeight:500 }}>{n.label}</div>
                <div style={{ fontSize:11.5, color:'var(--text-3)', marginTop:2 }}>{n.sub}</div>
              </div>
              {toggle(n.val, n.set, n.key)}
            </div>
          ))}
        </div>

        {sectionLabel('Sincronización entre dispositivos')}
        <div style={{ display:'flex', gap:8, marginBottom:20 }}>
          <input
            value={syncToken}
            onChange={e => setSyncToken(e.target.value)}
            type="password"
            placeholder="tu-token-de-sync"
            style={{ flex:1, padding:'9px 12px', borderRadius:9, background:'rgba(255,255,255,0.04)', border:'1px solid var(--border-strong)', color:'var(--text)', fontFamily:'inherit', fontSize:13, outline:'none' }}
          />
          <button onClick={saveSyncToken} style={{ padding:'9px 16px', borderRadius:9, background: syncSaved ? 'rgba(74,222,128,0.2)' : 'var(--accent-dim)', border:'1px solid var(--border-strong)', color: syncSaved ? '#4ade80' : 'var(--accent-bright)', cursor:'pointer', fontFamily:'inherit', fontSize:13, fontWeight:700 }}>
            {syncSaved ? '✓' : 'Guardar'}
          </button>
        </div>

        <div style={{ textAlign:'center', fontSize:11, color:'var(--text-3)', paddingTop:4 }}>Sisyphus · v2.0 · hecho con cariño</div>
      </>)}

      {/* ── TAB: PRESUPUESTOS ────────────────────────────────────────── */}
      {settTab === 'presupuestos' && (
        <div style={{ maxHeight:'60vh', overflowY:'auto', paddingRight:4 }}>
          {window.SlidersPane
            ? React.createElement(window.SlidersPane, {
                ccy:'ARS', spentState, budgets, onBudgetsChange: onBudgetsChange || (() => {}),
                // Read sueldo/extra directly from storage since Settings doesn't receive them as props
                sueldo:          window.SisyStorage?.load('sueldo', 0) || 0,
                onSueldoChange:  v => window.SisyStorage?.save('sueldo', v),
                sueldoDia:       window.SisyStorage?.load('sueldo_dia', 25) || 25,
                onSueldoDiaChange: v => window.SisyStorage?.save('sueldo_dia', v),
                extraIngresos:   window.SisyStorage?.load('extra_ing', 0) || 0,
                onExtraIngresosChange: v => window.SisyStorage?.save('extra_ing', v),
              })
            : <div style={{ textAlign:'center', padding:'40px 0', color:'var(--text-3)', fontSize:13 }}>Cargando presupuestos...</div>
          }
        </div>
      )}

      {/* ── TAB: GMAIL ──────────────────────────────────────────────── */}
      {settTab === 'gmail' && (
        <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
          {/* Status pill */}
          <div style={{ display:'flex', alignItems:'center', gap:10, padding:'12px 16px', borderRadius:12, background: gmailConnected ? 'rgba(74,222,128,0.08)' : 'rgba(255,255,255,0.03)', border:`1px solid ${gmailConnected ? 'rgba(74,222,128,0.25)' : 'var(--border)'}` }}>
            <div style={{ width:8, height:8, borderRadius:'50%', background: gmailConnected ? '#4ade80' : 'rgba(255,255,255,0.25)', flexShrink:0 }} />
            <div style={{ flex:1 }}>
              <div style={{ fontSize:13.5, fontWeight:600, color: gmailConnected ? '#4ade80' : 'var(--text-2)' }}>{gmailConnected ? 'Gmail conectado' : 'Gmail desconectado'}</div>
              {gmailLastSync && <div style={{ fontSize:11.5, color:'var(--text-3)', marginTop:2 }}>Última sync: {new Date(gmailLastSync).toLocaleString('es-AR', { day:'2-digit', month:'short', hour:'2-digit', minute:'2-digit' })}</div>}
            </div>
            {gmailConnected && (
              <button onClick={gmailDisconnect} style={{ padding:'5px 10px', borderRadius:7, background:'rgba(248,113,113,0.1)', border:'1px solid rgba(248,113,113,0.3)', color:'#f87171', cursor:'pointer', fontFamily:'inherit', fontSize:11.5, fontWeight:600 }}>Desconectar</button>
            )}
          </div>

          {!gmailConnected && (<>
            {sectionLabel('Google OAuth Client ID')}
            <input
              value={gmailClientId}
              onChange={e => setGmailClientId(e.target.value)}
              placeholder="xxxxxxxxxx.apps.googleusercontent.com"
              style={{ width:'100%', padding:'11px 14px', borderRadius:11, background:'rgba(255,255,255,0.05)', border:'1px solid var(--border-strong)', color:'var(--text)', fontFamily:'inherit', fontSize:13, outline:'none', boxSizing:'border-box', transition:'border-color 0.14s' }}
              onFocus={e=>e.target.style.borderColor='var(--accent)'}
              onBlur={e=>e.target.style.borderColor='var(--border-strong)'}
            />
            <button onClick={gmailConnect} style={{ width:'100%', padding:'12px 0', borderRadius:11, background:'var(--accent)', color:'var(--on-accent)', border:'none', cursor:'pointer', fontFamily:'inherit', fontSize:14, fontWeight:600, display:'flex', alignItems:'center', justifyContent:'center', gap:8 }}>
              <ObIcon name="mail" size={14} /> Conectar Gmail
            </button>
          </>)}

          {gmailConnected && (
            <button onClick={gmailSync} disabled={gmailSyncing} style={{ width:'100%', padding:'12px 0', borderRadius:11, background: gmailSyncing ? 'var(--accent-dim)' : 'var(--accent)', color: gmailSyncing ? 'var(--accent-bright)' : 'var(--on-accent)', border:'none', cursor: gmailSyncing ? 'default' : 'pointer', fontFamily:'inherit', fontSize:14, fontWeight:600, display:'flex', alignItems:'center', justifyContent:'center', gap:8, transition:'all 0.15s' }}>
              <ObIcon name="swap" size={14} /> {gmailSyncing ? 'Sincronizando...' : 'Sincronizar ahora'}
            </button>
          )}

          {gmailStatus && (
            <div style={{ padding:'10px 14px', borderRadius:10, background:'rgba(255,255,255,0.04)', border:'1px solid var(--border)', fontSize:12.5, color:'var(--text-2)' }}>{gmailStatus}</div>
          )}

          <div style={{ padding:'14px 16px', borderRadius:12, background:'rgba(255,255,255,0.025)', border:'1px solid var(--border)' }}>
            <div style={{ fontSize:12, fontWeight:600, color:'var(--text-2)', marginBottom:6 }}>¿Cómo funciona?</div>
            <div style={{ fontSize:11.5, color:'var(--text-3)', lineHeight:1.6 }}>
              Sisyphus lee tus mails de BBVA, Galicia, Santander, Mercado Pago, Wise y otros para detectar movimientos automáticamente. Solo lee — nunca escribe ni borra nada.
            </div>
          </div>
        </div>
      )}
    </Backdrop>
  );
}

window.Calculator = Calculator;
window.Settings   = Settings;
