// admin.jsx — Adminpanel för Sandareds Intresseförening

// ─── Auth ────────────────────────────────────────────────────────────────────
// Autentisering sker server-side mot /api/auth (JWT). Inga lösenord i klienten.

// ─── Hjälpfunktioner ──────────────────────────────────────────────────────────
const MO = ['jan','feb','mar','apr','maj','jun','jul','aug','sep','okt','nov','dec'];
function dateToFields(d) {
  const [,, day] = d.split('-'); const mo = parseInt(d.split('-')[1],10)-1;
  return { day, month: MO[mo] };
}

// Gruppera en lista (anmälningar/påminnelser) per eventId
function groupByEvent(list) {
  const out = {};
  (list || []).forEach(r => {
    const k = r.eventId || 'okänd';
    (out[k] = out[k] || []).push(r);
  });
  return out;
}

const ACCENT_PRESETS = [
  { label:'Grön',   hex:'#4A8B5C' }, { label:'Korall', hex:'#E8825A' },
  { label:'Blå',    hex:'#4A7BA8' }, { label:'Guld',   hex:'#E8B84A' },
  { label:'Lila',   hex:'#8B6BA8' }, { label:'Teal',   hex:'#5A9FA8' },
];
function emptyEvent() {
  const today = new Date().toISOString().slice(0,10);
  const { day, month } = dateToFields(today);
  return { date: today, day, month, title: '', time: '10:00', place: '', accent: '#4A8B5C' };
}

// ─── AdminLoginModal ──────────────────────────────────────────────────────────
function AdminLoginModal({ onLogin, onClose }) {
  const [email,    setEmail]    = React.useState('');
  const [password, setPassword] = React.useState('');
  const [error,    setError]    = React.useState('');
  const [loading,  setLoading]  = React.useState(false);
  const T = SITE_TOKENS;

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

  const submit = async () => {
    setError(''); setLoading(true);
    try {
      const u = email.trim().toLowerCase();
      const { token, role } = await API.post('auth', { email: u, password });
      API.setToken(token);
      API.setRole(role || 'admin');
      sessionStorage.setItem('sint_admin', u);
      onLogin(u, role || 'admin');
    } catch (err) {
      setError(err.status === 401
        ? 'Fel e-post eller lösenord. Försök igen.'
        : 'Något gick fel. Försök igen senare.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div onClick={onClose} style={{ position:'fixed', inset:0, background:'rgba(31,42,36,0.72)', backdropFilter:'blur(8px)', WebkitBackdropFilter:'blur(8px)', zIndex:3000, display:'flex', alignItems:'center', justifyContent:'center', padding:20 }}>
      <div onClick={e=>e.stopPropagation()} style={{ background:T.paper, borderRadius:24, padding:44, width:'100%', maxWidth:420, boxShadow:'0 32px 80px rgba(31,42,36,0.3)', position:'relative' }}>
        <button onClick={onClose} style={{ position:'absolute', top:18, right:18, width:34, height:34, borderRadius:'50%', background:T.cream2, border:0, cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center' }}>
          <svg width="11" height="11" viewBox="0 0 12 12" fill="none"><path d="M1 1L11 11M11 1L1 11" stroke={T.ink2} strokeWidth="2" strokeLinecap="round"/></svg>
        </button>
        <div style={{ width:52, height:52, borderRadius:16, background:T.forest+'20', display:'flex', alignItems:'center', justifyContent:'center', marginBottom:20 }}>
          <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke={T.forest} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
        </div>
        <div className="eyebrow" style={{ marginBottom:8 }}>Styrelsepanel</div>
        <h2 style={{ fontSize:26, marginBottom:6 }}>Logga in som admin</h2>
        <p style={{ fontSize:13, color:T.muted }}>Sandareds Intresseförening</p>

        <div style={{ display:'flex', flexDirection:'column', gap:12, marginTop:28 }}>
          {[['E-post','email','din@epost.se',email,setEmail],['Lösenord','password','Lösenord',password,setPassword]].map(([lbl,tp,ph,val,set])=>(
            <div key={lbl}>
              <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:6, textTransform:'uppercase', letterSpacing:'0.06em' }}>{lbl}</label>
              <input type={tp} value={val} onChange={e=>set(e.target.value)} onKeyDown={e=>e.key==='Enter'&&submit()} placeholder={ph}
                autoComplete={tp==='password'?'new-password':'off'} autoCorrect="off" autoCapitalize="off" spellCheck="false" name={tp==='password'?'sint-pw':'sint-user'}
                style={{ width:'100%', padding:'13px 16px', borderRadius:12, border:0, background:T.cream, color:T.ink, fontSize:14, fontFamily:'inherit', outline:'none', boxShadow:`inset 0 0 0 1.5px ${T.line}`, boxSizing:'border-box' }}/>
            </div>
          ))}
        </div>

        {error && <div style={{ marginTop:12, padding:'10px 14px', borderRadius:10, background:'#FDE8E8', color:'#CC3333', fontSize:13 }}>{error}</div>}

        <button onClick={submit} disabled={loading} className="btn btn-primary" style={{ width:'100%', justifyContent:'center', marginTop:20, padding:'16px 24px', fontSize:15, opacity:loading?0.7:1 }}>
          {loading ? 'Loggar in…' : 'Logga in →'}
        </button>
      </div>
    </div>
  );
}

// ─── Toggle-switch ────────────────────────────────────────────────────────────
function ToggleSwitch({ on, onChange, labelOn='Öppen', labelOff='Stängd', accentOn='#4A8B5C' }) {
  return (
    <button
      onClick={() => onChange(!on)}
      style={{ display:'flex', alignItems:'center', gap:10, padding:'9px 16px 9px 10px', borderRadius:999, background: on ? accentOn+'18' : '#F0F0EE', border: `1.5px solid ${on ? accentOn+'55' : '#D8D4C8'}`, cursor:'pointer', fontWeight:600, fontSize:13, color: on ? accentOn : '#888', transition:'all .18s', userSelect:'none' }}
    >
      {/* Pill */}
      <div style={{ width:38, height:22, borderRadius:999, background: on ? accentOn : '#C8C4BC', position:'relative', transition:'background .2s', flexShrink:0 }}>
        <div style={{ position:'absolute', top:3, left: on ? 19 : 3, width:16, height:16, borderRadius:'50%', background:'#fff', transition:'left .2s', boxShadow:'0 1px 4px rgba(0,0,0,0.22)' }}/>
      </div>
      {on ? labelOn : labelOff}
    </button>
  );
}

// ─── Anmälningar ──────────────────────────────────────────────────────────────
function AdminAnmalningar({ T, isMobile, isAdmin }) {
  const [tab,       setTab]       = React.useState(SIGNUP_EVENTS[0].id);
  const [settings,  setSettings]  = React.useState({});
  const [signups,   setSignups]   = React.useState({});
  const [reminders, setReminders] = React.useState({});
  const [loading,   setLoading]   = React.useState(true);
  const [saved,     setSaved]     = React.useState(false);
  const [editSignup, setEditSignup] = React.useState(null);

  React.useEffect(() => {
    (async () => {
      try {
        const [allSignups, allRem, allSet] = await Promise.all([
          API.get('signups'),
          API.get('reminders'),
          API.get('settings'),
        ]);
        setSignups(groupByEvent(allSignups));
        setReminders(groupByEvent(allRem));
        setSettings(allSet || {});
      } catch (e) { /* visa tomt */ }
      setLoading(false);
    })();
  }, []);

  // Hämta inställningar för ett event (fallback till datats ursprungsvärden)
  const getS = (id) => {
    const ev = SIGNUP_EVENTS.find(e => e.id === id);
    return {
      open: settings[id]?.open ?? ev?.signupOpen ?? true,
      max:  settings[id]?.max  ?? 0,
    };
  };

  const updateS = (id, patch) => {
    const next = { ...settings, [id]: { ...getS(id), ...patch } };
    setSettings(next);
    API.post('settings', { settings: next }).catch(() => {});
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  };

  const deleteSignup = (r) => {
    if (!confirm(`Ta bort anmälan från ${r.namn}?`)) return;
    setSignups(prev => ({ ...prev, [tab]: (prev[tab] || []).filter(x => x.id !== r.id) }));
    API.del('signups', { eventId: tab, id: r.id }).catch(() => {});
  };
  const clearAll = () => {
    if (!rows.length) return;
    if (!confirm(`Ta bort ALLA ${rows.length} anmälningar för detta event? Detta går inte att ångra.`)) return;
    setSignups(prev => ({ ...prev, [tab]: [] }));
    API.del('signups', { eventId: tab, all: 'true' }).catch(() => {});
  };

  const deleteReminder = (rem) => {
    if (!confirm(`Ta bort ${rem.email} från påminnelselistan?`)) return;
    setReminders(prev => ({ ...prev, [tab]: (prev[tab] || []).filter(x => x.email !== rem.email) }));
    API.del('reminders', { eventId: tab, email: rem.email }).catch(() => {});
  };
  const clearReminders = () => {
    const list = reminders[tab] || [];
    if (!list.length) return;
    if (!confirm(`Ta bort ALLA ${list.length} påminnelse-adresser för detta event?`)) return;
    setReminders(prev => ({ ...prev, [tab]: [] }));
    API.del('reminders', { eventId: tab, all: 'true' }).catch(() => {});
  };

  const ev     = SIGNUP_EVENTS.find(e => e.id === tab);
  const evS    = getS(tab);
  const isOpen = evS.open;
  const maxN   = evS.max || 0;
  const rows   = signups[tab] || [];
  const Illu   = window[ev.illu];
  const pct    = maxN > 0 ? Math.min(rows.length / maxN, 1) : null;
  const barCol = pct === null ? T.forest : pct >= 1 ? '#CC3333' : pct >= 0.8 ? T.coral : T.forest;
  const typCount = (t) => rows.filter(r => r.typ === t).length;
  const COLS = ['Typ','Namn','Kontaktperson','Mobil','E-post','Önskad plats','Övrigt','Inkommit'];

  return (
    <div>
      {editSignup && <SignupEditModal T={T} signup={editSignup} eventId={tab} onClose={() => setEditSignup(null)} onSaved={(upd) => { setSignups(prev => ({ ...prev, [tab]: (prev[tab] || []).map(x => x.id === upd.id ? upd : x) })); setEditSignup(null); }}/>}
      {/* ── Event-väljare ── */}
      <div style={{ display:'grid', gridTemplateColumns: isMobile ? '1fr' : `repeat(${SIGNUP_EVENTS.length},1fr)`, gap: isMobile?12:14, marginBottom: isMobile?20:28 }}>
        {SIGNUP_EVENTS.map(e => {
          const cnt    = (signups[e.id]||[]).length;
          const eS     = getS(e.id);
          const EIllu  = window[e.illu];
          const active = tab === e.id;
          const eMax   = eS.max || 0;
          return (
            <button key={e.id} onClick={()=>setTab(e.id)} style={{ background:active?T.paper:T.cream+'cc', borderRadius:20, overflow:'hidden', border:0, cursor:'pointer', textAlign:'left', boxShadow:active?`0 0 0 2.5px ${e.accent},0 8px 24px rgba(31,42,36,0.10)`:`inset 0 0 0 1.5px ${T.line}`, transition:'all .18s', padding:0 }}>
              <div style={{ display:'flex', alignItems:'stretch' }}>
                {!isMobile && (
                  <div style={{ width:110, background:e.tint, display:'flex', alignItems:'center', justifyContent:'center', padding:14, flexShrink:0 }}>
                    <EIllu size={82}/>
                  </div>
                )}
                <div style={{ padding:'16px 18px', flex:1 }}>
                  <div style={{ display:'flex', alignItems:'center', gap:7, marginBottom:8 }}>
                    <span style={{ width:7, height:7, borderRadius:'50%', background:eS.open?e.accent:T.muted, flexShrink:0 }}/>
                    <span style={{ fontSize:10, fontWeight:700, color:eS.open?e.accent:T.muted, textTransform:'uppercase', letterSpacing:'0.1em' }}>{eS.open?'Anmälan öppen':'Anmälan stängd'}</span>
                  </div>
                  <div style={{ fontFamily:'Bricolage Grotesque', fontSize:17, fontWeight:700, lineHeight:1.15, color:T.ink, marginBottom:6 }}>{e.title}</div>
                  <div style={{ fontSize:12, color:T.ink2, lineHeight:1.5 }}><strong>{e.date}</strong><br/>{e.time} · {e.place}</div>
                  <div style={{ marginTop:10, display:'flex', alignItems:'center', gap:6 }}>
                    <span style={{ fontFamily:'Bricolage Grotesque', fontSize:24, fontWeight:700, color:active?e.accent:T.muted, lineHeight:1 }}>{cnt}</span>
                    <span style={{ fontSize:12, color:T.muted }}>{eMax > 0 ? `/ ${eMax} platser` : 'anmälningar'}</span>
                  </div>
                </div>
              </div>
            </button>
          );
        })}
      </div>

      {/* ── Evenemangshuvud ── */}
      <div style={{ background:T.paper, borderRadius:20, overflow:'hidden', marginBottom:20, boxShadow:`inset 0 0 0 1px ${T.line}` }}>
        <div style={{ display:'grid', gridTemplateColumns: isMobile ? '1fr' : '200px 1fr', alignItems:'stretch' }}>
          {/* Illustration (dölj på mobil) */}
          {!isMobile && (
          <div style={{ background:ev.tint, display:'flex', alignItems:'center', justifyContent:'center', padding:24 }}>
            <Illu size={148}/>
          </div>
          )}
          {/* Info */}
          <div style={{ padding: isMobile ? '20px 18px' : '26px 32px', display:'flex', flexDirection:'column', gap:0 }}>
            <h2 style={{ fontSize: isMobile ? 23 : 30, marginBottom:10 }}>{ev.title}</h2>
            <div style={{ display:'flex', gap:22, fontSize:13, color:T.ink2, flexWrap:'wrap', marginBottom:12 }}>
              <span>📅 <strong style={{color:T.ink}}>{ev.date}</strong></span>
              <span>⏰ {ev.time}</span>
              <span>📍 {ev.place}</span>
              <span>👥 {ev.audience}</span>
            </div>
            <p style={{ fontSize:13, color:T.ink2, lineHeight:1.6, maxWidth:580, margin:0 }}>{ev.intro}</p>

            {/* ── Statistiksiffror ── */}
            <div style={{ display:'flex', gap:18, marginTop:18, paddingTop:18, borderTop:`1px solid ${T.line}` }}>
              {[['Totalt',rows.length,ev.accent],['Företag',typCount('Företag'),'#4A7BA8'],['Föreningar',typCount('Förening'),'#4A8B5C'],['Privat',typCount('Privat'),T.muted]].map(([lbl,num,col])=>(
                <div key={lbl} style={{ textAlign:'center', minWidth:58 }}>
                  <div style={{ fontFamily:'Bricolage Grotesque', fontSize:26, fontWeight:700, color:col, lineHeight:1 }}>{num}</div>
                  <div style={{ fontSize:11, color:T.muted, marginTop:3 }}>{lbl}</div>
                </div>
              ))}
            </div>
          </div>
        </div>

        {/* ── Inställningsrad ── */}
        <div style={{ padding: isMobile?'16px 18px':'18px 32px', borderTop:`1px solid ${T.line}`, background:T.cream+'66', display:'flex', flexDirection: isMobile?'column':'row', alignItems: isMobile?'stretch':'center', gap: isMobile?18:32, flexWrap:'wrap' }}>

          {/* Status-toggle */}
          <div>
            <div style={{ fontSize:11, fontWeight:600, color:T.muted, textTransform:'uppercase', letterSpacing:'0.06em', marginBottom:8 }}>Anmälningsstatus</div>
            <ToggleSwitch
              on={isOpen}
              onChange={val => updateS(tab, { open: val })}
              labelOn="Anmälan öppen"
              labelOff="Anmälan stängd"
              accentOn={ev.accent}
            />
          </div>

          {/* Separator */}
          {!isMobile && <div style={{ width:1, height:48, background:T.line }}/>}

          {/* Max antal */}
          <div>
            <div style={{ fontSize:11, fontWeight:600, color:T.muted, textTransform:'uppercase', letterSpacing:'0.06em', marginBottom:8 }}>
              Max antal platser
            </div>
            <div style={{ display:'flex', alignItems:'center', gap:0 }}>
              <button onClick={() => updateS(tab, { max: Math.max(0, maxN - 1) })} style={{ width:34, height:36, background:T.cream2, border:`1px solid ${T.line}`, borderRight:0, borderRadius:'8px 0 0 8px', cursor:'pointer', fontSize:17, color:T.ink, lineHeight:1 }}>−</button>
              <input
                type="number" min="0" value={maxN || ''}
                onChange={e => updateS(tab, { max: Math.max(0, parseInt(e.target.value)||0) })}
                placeholder="∞"
                style={{ width:68, height:36, textAlign:'center', border:`1px solid ${T.line}`, background:T.paper, color:T.ink, fontSize:15, fontFamily:'inherit', outline:'none' }}
              />
              <button onClick={() => updateS(tab, { max: maxN + 1 })} style={{ width:34, height:36, background:T.cream2, border:`1px solid ${T.line}`, borderLeft:0, borderRadius:'0 8px 8px 0', cursor:'pointer', fontSize:17, color:T.ink, lineHeight:1 }}>+</button>
            </div>
            <div style={{ fontSize:11, color:T.muted, marginTop:5 }}>{maxN === 0 ? 'Obegränsat antal platser' : `${maxN} platser totalt`}</div>
          </div>

          {/* Progressbar (bara om max är satt) */}
          {maxN > 0 && (
            <>
              {!isMobile && <div style={{ width:1, height:48, background:T.line }}/>}
              <div style={{ flex:1, minWidth:200, maxWidth:320 }}>
                <div style={{ display:'flex', justifyContent:'space-between', marginBottom:7, fontSize:13 }}>
                  <span style={{ color:T.muted, fontWeight:500 }}>Platsutnyttjande</span>
                  <span style={{ fontWeight:700, color:barCol }}>{rows.length} / {maxN} bokade</span>
                </div>
                <div style={{ height:10, borderRadius:999, background:T.line, overflow:'hidden' }}>
                  <div style={{ height:'100%', borderRadius:999, width:`${(pct||0)*100}%`, background:barCol, transition:'width .4s, background .3s' }}/>
                </div>
                <div style={{ marginTop:6, fontSize:11, fontWeight:600, color:barCol }}>
                  {pct >= 1 ? '⚠️ Fullt — stäng anmälan' : pct >= 0.8 ? `⚡ ${maxN - rows.length} platser kvar` : `${maxN - rows.length} platser lediga`}
                </div>
              </div>
            </>
          )}

          {/* Sparat-indikator */}
          {saved && (
            <div style={{ marginLeft:'auto', display:'flex', alignItems:'center', gap:7, padding:'7px 14px', borderRadius:999, background:'#E8F5EC', color:'#2D6B4E', fontSize:13, fontWeight:600 }}>
              <svg width="13" height="13" viewBox="0 0 24 24"><path d="M4 12L9 17L20 6" stroke="currentColor" strokeWidth="2.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
              Sparat
            </div>
          )}
        </div>
      </div>

      {/* ── Anmälningstabell ── */}
      <div style={{ background:T.paper, borderRadius:16, overflow:'hidden', boxShadow:`inset 0 0 0 1px ${T.line}` }}>
        <div style={{ padding:'16px 22px', borderBottom:`1px solid ${T.line}`, display:'flex', justifyContent:'space-between', alignItems:'center', gap:12, flexWrap:'wrap' }}>
          <span style={{ fontWeight:600, fontSize:15 }}>Anmälda deltagare</span>
          <div style={{ display:'flex', alignItems:'center', gap:14 }}>
            <span style={{ fontSize:13, color:T.muted }}>{rows.length} st{maxN>0?` av ${maxN}`:''}</span>
            {rows.length > 0 && (
              <button onClick={clearAll} style={{ padding:'7px 14px', borderRadius:8, background:'#FDE8E8', border:0, fontSize:12.5, fontWeight:600, color:'#CC3333', cursor:'pointer' }}>Rensa alla</button>
            )}
          </div>
        </div>
        {isMobile ? (
          rows.length === 0 ? (
            <div style={{ padding:'32px 16px', textAlign:'center', color:T.muted }}>Inga anmälningar ännu.</div>
          ) : (
            <div style={{ padding:14, display:'flex', flexDirection:'column', gap:12 }}>
              {rows.map(r => (
                <div key={r.id} style={{ border:`1px solid ${T.line}`, borderRadius:12, padding:'14px 16px', background:T.cream+'55' }}>
                  <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', gap:10, marginBottom:8 }}>
                    <span style={{ fontWeight:700, fontSize:15 }}>{r.namn}</span>
                    <span style={{ fontSize:11, fontWeight:600, padding:'3px 9px', borderRadius:999, flexShrink:0, background:r.typ==='Företag'?'#E8F1FF':r.typ==='Förening'?'#E8F5EC':'#FFF8E0', color:r.typ==='Företag'?'#4A7BA8':r.typ==='Förening'?'#4A8B5C':'#B8860B' }}>{r.typ}</span>
                  </div>
                  {[['Kontaktperson', r.kontakt],['Mobil', r.mobil],['E-post', r.email],['Önskad plats', r.plats],['Övrigt', r.ovrigt],['Inkommit', r.datum]].map(([label,val]) => (
                    <div key={label} style={{ display:'flex', justifyContent:'space-between', gap:12, padding:'6px 0', borderTop:`1px solid ${T.line}`, fontSize:13 }}>
                      <span style={{ color:T.muted, flexShrink:0 }}>{label}</span>
                      <span style={{ textAlign:'right', wordBreak:'break-word', minWidth:0 }}>
                        {label === 'E-post' && val ? <a href={`mailto:${val}`} style={{ color:'#4A7BA8' }}>{val}</a> : (val || '—')}
                      </span>
                    </div>
                  ))}
                  <div style={{ display:'flex', gap:8, marginTop:10 }}>
                    {isAdmin && <button onClick={() => setEditSignup(r)} style={{ flex:1, padding:'9px', borderRadius:8, background:T.cream2, border:0, fontSize:13, fontWeight:600, color:T.ink, cursor:'pointer' }}>Redigera</button>}
                    <button onClick={() => deleteSignup(r)} style={{ flex:1, padding:'9px', borderRadius:8, background:'#FDE8E8', border:0, fontSize:13, fontWeight:600, color:'#CC3333', cursor:'pointer' }}>Ta bort</button>
                  </div>
                </div>
              ))}
            </div>
          )
        ) : (
        <div style={{ overflowX:'auto' }}>
          <table style={{ width:'100%', borderCollapse:'collapse', fontSize:13 }}>
            <thead>
              <tr style={{ background:T.cream2 }}>
                {COLS.map(c => <th key={c} style={{ padding:'11px 16px', textAlign:'left', fontWeight:600, fontSize:11, letterSpacing:'0.06em', textTransform:'uppercase', color:T.muted, whiteSpace:'nowrap', borderBottom:`1px solid ${T.line}` }}>{c}</th>)}
                <th style={{ borderBottom:`1px solid ${T.line}` }}/>
              </tr>
            </thead>
            <tbody>
              {rows.length === 0 ? (
                <tr><td colSpan={9} style={{ padding:'40px 16px', textAlign:'center', color:T.muted }}>Inga anmälningar ännu.</td></tr>
              ) : rows.map((r, i) => (
                <tr key={r.id} style={{ background:i%2===0?T.paper:T.cream+'44', borderBottom:`1px solid ${T.line}` }}>
                  <td style={{ padding:'13px 16px' }}>
                    <span style={{ fontSize:11, fontWeight:600, padding:'3px 9px', borderRadius:999, background:r.typ==='Företag'?'#E8F1FF':r.typ==='Förening'?'#E8F5EC':'#FFF8E0', color:r.typ==='Företag'?'#4A7BA8':r.typ==='Förening'?'#4A8B5C':'#B8860B' }}>{r.typ}</span>
                  </td>
                  <td style={{ padding:'13px 16px', fontWeight:600 }}>{r.namn}</td>
                  <td style={{ padding:'13px 16px' }}>{r.kontakt}</td>
                  <td style={{ padding:'13px 16px', whiteSpace:'nowrap' }}>{r.mobil}</td>
                  <td style={{ padding:'13px 16px' }}><a href={`mailto:${r.email}`} style={{ color:'#4A7BA8', textDecoration:'underline' }}>{r.email}</a></td>
                  <td style={{ padding:'13px 16px' }}>{r.plats||'—'}</td>
                  <td style={{ padding:'13px 16px', color:T.muted, maxWidth:200 }}>{r.ovrigt||'—'}</td>
                  <td style={{ padding:'13px 16px', color:T.muted, whiteSpace:'nowrap', fontSize:12 }}>{r.datum}</td>
                  <td style={{ padding:'13px 10px', textAlign:'right', whiteSpace:'nowrap' }}>
                    {isAdmin && (
                      <button onClick={() => setEditSignup(r)} title="Redigera" style={{ padding:'6px 10px', borderRadius:8, background:T.cream2, border:0, color:T.ink, cursor:'pointer', marginRight:6 }}><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg></button>
                    )}
                    <button onClick={() => deleteSignup(r)} title="Ta bort anmälan" style={{ padding:'6px 10px', borderRadius:8, background:'#FDE8E8', border:0, fontSize:12, fontWeight:600, color:'#CC3333', cursor:'pointer' }}><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg></button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
        )}
      </div>

      {/* ── Påminnelselista ── */}
      {(() => {
        const rems = reminders[tab] || [];
        if (rems.length === 0) return null;
        const bcc = rems.map(r => r.email).join(',');
        const subject = encodeURIComponent(`Anmälan till ${ev.title} öppnar nu!`);
        const body = encodeURIComponent(
          `Hej!\n\nNi registrerade er för att få en påminnelse när anmälan till ${ev.title} öppnar.\n\n` +
          `Vi är glada att kunna meddela att anmälan nu är öppen!\n\n` +
          `📅 Datum: ${ev.date}\n` +
          `⏰ Tid: ${ev.time}\n` +
          `📍 Plats: ${ev.place}\n\n` +
          `Anmäl er på sandared.se\n\n` +
          `Hälsningar,\nSandareds Intresseförening`
        );
        const mailtoHref = `mailto:?bcc=${encodeURIComponent(bcc)}&subject=${subject}&body=${body}`;
        return (
          <div style={{ marginTop:20, background:T.paper, borderRadius:16, overflow:'hidden', boxShadow:`inset 0 0 0 1px ${T.line}` }}>
            <div style={{ padding:'16px 22px', borderBottom:`1px solid ${T.line}`, display:'flex', justifyContent:'space-between', alignItems:'center', gap:16 }}>
              <div>
                <span style={{ fontWeight:600, fontSize:15 }}>Påminnelselista</span>
                <span style={{ marginLeft:10, fontSize:12, color:T.muted }}>{rems.length} adress{rems.length !== 1 ? 'er' : ''} sparade</span>
              </div>
              <div style={{ display:'flex', gap:8, alignItems:'center', flexWrap:'wrap' }}>
                <a href={mailtoHref} className="btn btn-primary" style={{ padding:'9px 18px', fontSize:13, display:'inline-flex', alignItems:'center', gap:7, textDecoration:'none' }}>
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
                  Skicka påminnelse till alla →
                </a>
                <button onClick={clearReminders} style={{ padding:'9px 16px', borderRadius:999, background:'#FDE8E8', border:0, fontSize:13, fontWeight:600, color:'#CC3333', cursor:'pointer' }}>Rensa alla</button>
              </div>
            </div>
            <div style={{ overflowX:'auto' }}>
              <table style={{ width:'100%', borderCollapse:'collapse', fontSize:13 }}>
                <thead>
                  <tr style={{ background:T.cream2 }}>
                    {['E-post','Sparad'].map(c => <th key={c} style={{ padding:'10px 16px', textAlign:'left', fontWeight:600, fontSize:11, letterSpacing:'0.06em', textTransform:'uppercase', color:T.muted, borderBottom:`1px solid ${T.line}` }}>{c}</th>)}
                    <th style={{ padding:'10px 16px', borderBottom:`1px solid ${T.line}` }}/>
                  </tr>
                </thead>
                <tbody>
                  {rems.map((r, i) => (
                    <tr key={i} style={{ background:i%2===0?T.paper:T.cream+'44', borderBottom:`1px solid ${T.line}` }}>
                      <td style={{ padding:'12px 16px' }}><a href={`mailto:${r.email}`} style={{ color:'#4A7BA8', textDecoration:'underline' }}>{r.email}</a></td>
                      <td style={{ padding:'12px 16px', color:T.muted, whiteSpace:'nowrap', fontSize:12 }}>{r.savedAt}</td>
                      <td style={{ padding:'12px 16px', textAlign:'right', whiteSpace:'nowrap' }}>
                        <a href={`mailto:${r.email}?subject=${subject}&body=${body}`} style={{ fontSize:12, color:T.forest, fontWeight:600, textDecoration:'underline' }}>Skicka enskilt</a>
                        <button onClick={() => deleteReminder(r)} title="Ta bort" style={{ marginLeft:12, padding:'5px 9px', borderRadius:8, background:'#FDE8E8', border:0, fontSize:12, fontWeight:600, color:'#CC3333', cursor:'pointer' }}><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg></button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        );
      })()}
    </div>
  );
}

// ─── Kalender ─────────────────────────────────────────────────────────────────
function AdminKalender({ T }) {
  const [events,   setEvents]   = React.useState([]);
  const [editing,  setEditing]  = React.useState(null); // null | 'new' | index number
  const [saved,    setSaved]    = React.useState(false);
  const [formData, setFormData] = React.useState(emptyEvent());

  React.useEffect(() => {
    API.get('events')
      .then(evs => setEvents(evs && evs.length ? evs : [...EVENTS]))
      .catch(() => setEvents([...EVENTS]));
  }, []);

  const openEdit = (idx) => {
    setFormData({ ...events[idx] });
    setEditing(idx);
  };
  const openNew = () => {
    setFormData(emptyEvent());
    setEditing('new');
  };
  const cancelEdit = () => setEditing(null);

  const saveEdit = () => {
    const { day, month } = dateToFields(formData.date);
    const updated = { ...formData, day, month };
    let next;
    if (editing === 'new') {
      next = [...events, updated].sort((a,b) => a.date.localeCompare(b.date));
    } else {
      next = events.map((e,i) => i===editing ? updated : e);
    }
    setEvents(next);
    API.post('events', { items: next }).catch(() => {});
    setEditing(null);
    setSaved(true);
    setTimeout(() => setSaved(false), 2500);
  };

  const deleteEvent = (idx) => {
    if (!confirm('Ta bort detta event?')) return;
    const next = events.filter((_,i)=>i!==idx);
    setEvents(next);
    API.post('events', { items: next }).catch(() => {});
    setSaved(true);
    setTimeout(() => setSaved(false), 2500);
  };

  const setField = (key, val) => setFormData(prev => ({ ...prev, [key]: val }));

  return (
    <div>
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', marginBottom:28 }}>
        <div>
          <h2 style={{ fontSize:28 }}>Kalender</h2>
          <p style={{ fontSize:14, color:T.muted, marginTop:6 }}>Hantera commande event. Ändringar aktiveras vid sidinladdning.</p>
        </div>
        <div style={{ display:'flex', alignItems:'center', gap:12 }}>
          {saved && (
            <div style={{ display:'flex', alignItems:'center', gap:8, padding:'8px 16px', borderRadius:999, background:'#E8F5EC', color:'#2D6B4E', fontSize:13, fontWeight:600 }}>
              <svg width="14" height="14" viewBox="0 0 24 24"><path d="M4 12L9 17L20 6" stroke="currentColor" strokeWidth="2.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
              Sparad
            </div>
          )}
          <button onClick={openNew} className="btn btn-primary" style={{ padding:'11px 20px', fontSize:14 }}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"><path d="M12 5v14M5 12h14"/></svg>
            Nytt event
          </button>
        </div>
      </div>

      {/* Event-lista */}
      <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
        {events.map((ev, idx) => (
          <div key={idx}>
            {/* Event-rad */}
            {editing !== idx && (
              <div style={{ background:T.paper, borderRadius:16, padding:'18px 22px', boxShadow:`inset 0 0 0 1px ${T.line}`, display:'flex', alignItems:'center', gap:18 }}>
                <div style={{ width:52, height:52, borderRadius:14, background:ev.accent+'20', display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
                  <div style={{ fontFamily:'Bricolage Grotesque', fontSize:20, fontWeight:700, color:ev.accent, lineHeight:1 }}>{ev.day}</div>
                  <div style={{ fontSize:10, fontWeight:600, textTransform:'uppercase', color:ev.accent, letterSpacing:'0.08em' }}>{ev.month}</div>
                </div>
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontFamily:'Bricolage Grotesque', fontSize:17, fontWeight:600, lineHeight:1.2 }}>{ev.title}</div>
                  <div style={{ fontSize:13, color:T.muted, marginTop:3 }}>{ev.time} · {ev.place}</div>
                </div>
                <div style={{ display:'flex', gap:8, flexShrink:0 }}>
                  <button onClick={() => openEdit(idx)} title="Redigera" style={{ width:38, height:38, borderRadius:10, background:T.cream2, border:0, cursor:'pointer', color:T.ink, display:'flex', alignItems:'center', justifyContent:'center' }}>
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>
                  </button>
                  <button onClick={() => deleteEvent(idx)} title="Ta bort" style={{ width:38, height:38, borderRadius:10, background:'#FDE8E8', border:0, cursor:'pointer', color:'#CC3333', display:'flex', alignItems:'center', justifyContent:'center' }}>
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg>
                  </button>
                </div>
              </div>
            )}
            {/* Inline redigeringsformulär */}
            {editing === idx && <EventForm T={T} data={formData} setField={setField} onSave={saveEdit} onCancel={cancelEdit} isNew={false}/>}
          </div>
        ))}

        {/* Nytt event-formulär (i botten) */}
        {editing === 'new' && (
          <div>
            <div style={{ height:1, background:T.line, margin:'4px 0 16px' }}/>
            <div className="eyebrow" style={{ marginBottom:12, color:T.forest }}>Nytt event</div>
            <EventForm T={T} data={formData} setField={setField} onSave={saveEdit} onCancel={cancelEdit} isNew={true}/>
          </div>
        )}
      </div>

      {events.length === 0 && editing !== 'new' && (
        <div style={{ textAlign:'center', padding:'48px 0', color:T.muted }}>
          <p>Inga event ännu.</p>
          <button onClick={openNew} className="btn btn-secondary" style={{ marginTop:16 }}>Lägg till ett event</button>
        </div>
      )}
    </div>
  );
}

function EventForm({ T, data, setField, onSave, onCancel, isNew }) {
  return (
    <div style={{ background:T.cream, borderRadius:16, padding:'24px 26px', boxShadow:`inset 0 0 0 1.5px ${T.forest}` }}>
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:14, marginBottom:14 }}>
        {/* Titel */}
        <div style={{ gridColumn:'1 / -1' }}>
          <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:6, textTransform:'uppercase', letterSpacing:'0.06em' }}>Titel</label>
          <input value={data.title} onChange={e=>setField('title',e.target.value)} placeholder="Eventnamn"
            style={{ width:'100%', padding:'12px 14px', borderRadius:10, border:0, background:T.paper, color:T.ink, fontSize:14, fontFamily:'inherit', outline:'none', boxShadow:`inset 0 0 0 1.5px ${T.line}`, boxSizing:'border-box' }}/>
        </div>
        {/* Datum */}
        <div>
          <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:6, textTransform:'uppercase', letterSpacing:'0.06em' }}>Datum</label>
          <input type="date" value={data.date} onChange={e=>setField('date',e.target.value)}
            style={{ width:'100%', padding:'12px 14px', borderRadius:10, border:0, background:T.paper, color:T.ink, fontSize:14, fontFamily:'inherit', outline:'none', boxShadow:`inset 0 0 0 1.5px ${T.line}`, boxSizing:'border-box' }}/>
        </div>
        {/* Tid */}
        <div>
          <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:6, textTransform:'uppercase', letterSpacing:'0.06em' }}>Tid</label>
          <input type="time" value={data.time} onChange={e=>setField('time',e.target.value)}
            style={{ width:'100%', padding:'12px 14px', borderRadius:10, border:0, background:T.paper, color:T.ink, fontSize:14, fontFamily:'inherit', outline:'none', boxShadow:`inset 0 0 0 1.5px ${T.line}`, boxSizing:'border-box' }}/>
        </div>
        {/* Plats */}
        <div>
          <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:6, textTransform:'uppercase', letterSpacing:'0.06em' }}>Plats</label>
          <input value={data.place} onChange={e=>setField('place',e.target.value)} placeholder="T.ex. Magasinet"
            style={{ width:'100%', padding:'12px 14px', borderRadius:10, border:0, background:T.paper, color:T.ink, fontSize:14, fontFamily:'inherit', outline:'none', boxShadow:`inset 0 0 0 1.5px ${T.line}`, boxSizing:'border-box' }}/>
        </div>
      </div>
      {/* Accent-färg */}
      <div style={{ marginBottom:18 }}>
        <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:8, textTransform:'uppercase', letterSpacing:'0.06em' }}>Färg</label>
        <div style={{ display:'flex', gap:8 }}>
          {ACCENT_PRESETS.map(c => (
            <button key={c.hex} onClick={()=>setField('accent',c.hex)} title={c.label}
              style={{ width:32, height:32, borderRadius:'50%', background:c.hex, border: data.accent===c.hex ? `3px solid ${T.ink}` : '3px solid transparent', cursor:'pointer', transition:'all .15s' }}/>
          ))}
        </div>
      </div>
      {/* Knappar */}
      <div style={{ display:'flex', gap:10 }}>
        <button onClick={onSave} className="btn btn-primary" style={{ fontSize:14, padding:'11px 22px' }}>
          {isNew ? 'Skapa event' : 'Spara ändringar'}
        </button>
        <button onClick={onCancel} className="btn btn-secondary" style={{ fontSize:14, padding:'11px 20px' }}>Avbryt</button>
      </div>
    </div>
  );
}

// ─── Förslag ──────────────────────────────────────────────────────────────────
function AdminForslag({ T }) {
  const [rows, setRows] = React.useState([]);
  React.useEffect(() => {
    API.get('proposals').then(p => setRows(p || [])).catch(() => {});
  }, []);

  const toggleHandled = (r) => {
    const next = !r.handled;
    setRows(prev => prev.map(x => x.id === r.id ? { ...x, handled: next } : x));
    API.patch('proposals', { id: r.id, handled: next }).catch(() => {});
  };
  const remove = (r) => {
    if (!confirm('Ta bort förslaget permanent?')) return;
    setRows(prev => prev.filter(x => x.id !== r.id));
    API.del('proposals', { id: r.id }).catch(() => {});
  };

  return (
    <div>
      <div style={{ marginBottom:28 }}>
        <h2 style={{ fontSize:28 }}>Projektförslag</h2>
        <p style={{ fontSize:14, color:T.muted, marginTop:6 }}>Inkomna förslag från invånare via webbsidan.</p>
      </div>
      <div style={{ display:'flex', flexDirection:'column', gap:12 }}>
        {rows.map((r) => (
          <div key={r.id} style={{ background:T.paper, borderRadius:16, padding:'20px 24px', boxShadow:`inset 0 0 0 1px ${r.handled ? '#BFE3CC' : T.line}`, opacity: r.handled ? 0.65 : 1 }}>
            <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', gap:16, flexWrap:'wrap' }}>
              <div style={{ flex:1, minWidth:200 }}>
                <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:8 }}>
                  <div style={{ width:34, height:34, borderRadius:10, background:SITE_TOKENS.coral+'22', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={T.coral} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26Z"/></svg>
                  </div>
                  <div>
                    <div style={{ fontWeight:600, fontSize:15, display:'flex', alignItems:'center', gap:8, flexWrap:'wrap' }}>
                      {r.namn}
                      {r.handled && <span style={{ fontSize:10, fontWeight:700, color:'#2D6B4E', background:'#E8F5EC', padding:'2px 8px', borderRadius:999, letterSpacing:'0.04em' }}>HANTERAD</span>}
                    </div>
                    <div style={{ fontSize:12, color:T.muted }}>{r.adress}{r.telefon ? ' · ' + r.telefon : ''}</div>
                  </div>
                </div>
                <p style={{ fontSize:14, color:T.ink2, lineHeight:1.6, margin:0 }}>{r.forslag}</p>
              </div>
              <div style={{ flexShrink:0 }}>
                <div style={{ fontSize:11, color:T.muted, textAlign:'right' }}>{r.datum}</div>
                <div style={{ display:'flex', gap:8, marginTop:8 }}>
                  <button onClick={() => toggleHandled(r)} title={r.handled ? 'Markera som ohanterad' : 'Markera som hanterad'} style={{ width:38, height:38, borderRadius:10, background: r.handled ? T.cream2 : '#E8F5EC', border:0, color: r.handled ? T.ink2 : '#2D6B4E', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center' }}>
                    {r.handled
                      ? <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 7v6h6"/><path d="M3 13a9 9 0 1 0 3-7.7L3 8"/></svg>
                      : <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><path d="M4 12l5 5L20 6"/></svg>}
                  </button>
                  <button onClick={() => remove(r)} title="Ta bort" style={{ width:38, height:38, borderRadius:10, background:'#FDE8E8', border:0, color:'#CC3333', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center' }}>
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg>
                  </button>
                </div>
              </div>
            </div>
          </div>
        ))}
        {rows.length === 0 && <div style={{ textAlign:'center', padding:'48px 0', color:T.muted }}>Inga förslag inkomna ännu.</div>}
      </div>
    </div>
  );
}

// ─── Startsidans siffror (hero-statistik) ────────────────────────────────────
function HeroStatsEditor({ T }) {
  const [stats, setStats] = React.useState(null);
  const [saved, setSaved] = React.useState(false);
  React.useEffect(() => {
    // Företagspartners räknas automatiskt (betalda företag) — visas inte här.
    const clean = (arr) => arr.filter(x => !x.auto && !/företag/i.test(x.label || '')).map(x => ({ num: String(x.num), label: x.label }));
    const fallback = clean(STATS);
    API.get('stats')
      .then(s => { const c = clean(Array.isArray(s) ? s : []); setStats(c.length ? c : fallback); })
      .catch(() => setStats(fallback));
  }, []);
  if (!stats) return null;
  const update = (i, key, val) => setStats(prev => prev.map((s, idx) => idx === i ? { ...s, [key]: val } : s));
  const save = () => {
    API.post('stats', { stats })
      .then(() => { setSaved(true); setTimeout(() => setSaved(false), 2500); })
      .catch(() => alert('Kunde inte spara siffrorna. Försök igen.'));
  };
  return (
    <div style={{ background:T.paper, borderRadius:16, padding:'20px 24px', marginBottom:24, boxShadow:`inset 0 0 0 1px ${T.line}` }}>
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', gap:12, flexWrap:'wrap', marginBottom:14 }}>
        <div>
          <div style={{ fontWeight:600, fontSize:15 }}>Siffror på startsidan</div>
          <div style={{ fontSize:12.5, color:T.muted, marginTop:3 }}>Visas högst upp på sidan. Antal företagsmedlemmar räknas automatiskt (betalda företag) och visas inte här.</div>
        </div>
        <div style={{ display:'flex', alignItems:'center', gap:10 }}>
          {saved && <span style={{ fontSize:13, color:'#2D6B4E', fontWeight:600 }}>Sparat ✓</span>}
          <button onClick={save} className="btn btn-primary" style={{ padding:'9px 18px', fontSize:14 }}>Spara siffror</button>
        </div>
      </div>
      <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fit, minmax(150px, 1fr))', gap:12 }}>
        {stats.map((s, i) => (
          <div key={i} style={{ border:`1px solid ${T.line}`, borderRadius:12, padding:12 }}>
            <input value={s.num} onChange={e=>update(i,'num',e.target.value)} placeholder="539"
              style={{ width:'100%', padding:'8px 10px', borderRadius:8, border:0, boxShadow:`inset 0 0 0 1.5px ${T.line}`, fontSize:20, fontWeight:700, fontFamily:'Bricolage Grotesque, sans-serif', color:T.forest, outline:'none', boxSizing:'border-box' }}/>
            <input value={s.label} onChange={e=>update(i,'label',e.target.value)} placeholder="medlemmar 2026"
              style={{ width:'100%', padding:'7px 10px', marginTop:8, borderRadius:8, border:0, boxShadow:`inset 0 0 0 1.5px ${T.line}`, fontSize:13, color:T.ink2, outline:'none', boxSizing:'border-box' }}/>
          </div>
        ))}
      </div>
    </div>
  );
}

// ─── Medlemmar (privatpersoner + företag) ─────────────────────────────────────
function AdminMedlemmar({ T, isAdmin }) {
  const [filter, setFilter] = React.useState('all'); // all | person | company
  const [rows, setRows] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [editMember, setEditMember] = React.useState(null);

  const load = () => {
    setLoading(true);
    API.get('members').then(m => setRows(m || [])).catch(() => {}).finally(() => setLoading(false));
  };
  React.useEffect(load, []);

  const togglePaid = (m) => {
    const next = !m.paid;
    setRows(prev => prev.map(x => x.id === m.id ? { ...x, paid: next } : x));
    API.patch('members', { type: m.type, id: m.id, paid: next }).catch(() => {});
  };
  const remove = (m) => {
    if (!confirm(`Ta bort ${m.namn}?`)) return;
    setRows(prev => prev.filter(x => x.id !== m.id));
    API.del('members', { type: m.type, id: m.id }).catch(() => {});
  };

  const shown = rows.filter(m => filter === 'all' ? true : m.type === filter);
  const persons = rows.filter(m => m.type === 'person').length;
  const companies = rows.filter(m => m.type === 'company').length;
  const paidCount = shown.filter(m => m.paid).length;

  const TABS = [
    { id:'all', label:`Alla (${rows.length})` },
    { id:'person', label:`Privatpersoner (${persons})` },
    { id:'company', label:`Företag (${companies})` },
  ];

  return (
    <div>
      {editMember && <MemberEditModal T={T} member={editMember} onClose={() => setEditMember(null)} onSaved={(upd) => { setRows(prev => prev.map(x => x.id === upd.id ? upd : x)); setEditMember(null); }}/>}
      {isAdmin && <HeroStatsEditor T={T}/>}
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', flexWrap:'wrap', gap:12, marginBottom:20 }}>
        <div>
          <h2 style={{ fontSize:28 }}>Medlemmar</h2>
          <p style={{ fontSize:14, color:T.muted, marginTop:6 }}>Privatpersoner och företag. Tagga betald status{isAdmin ? ', redigera uppgifter och ta bort vid behov.' : '.'}</p>
        </div>
        <div style={{ fontSize:13, color:T.muted, textAlign:'right' }}>
          <div><strong style={{ color:T.ink }}>{paidCount}</strong> av {shown.length} betalda</div>
        </div>
      </div>

      <div style={{ display:'flex', gap:8, marginBottom:18, flexWrap:'wrap' }}>
        {TABS.map(t => {
          const active = filter === t.id;
          return (
            <button key={t.id} onClick={() => setFilter(t.id)} style={{ padding:'8px 16px', borderRadius:999, border:0, cursor:'pointer', fontSize:13, fontWeight:600, background: active ? T.forest : T.cream2, color: active ? T.cream : T.ink2 }}>{t.label}</button>
          );
        })}
      </div>

      {loading ? (
        <div style={{ textAlign:'center', padding:'48px 0', color:T.muted }}>Laddar…</div>
      ) : shown.length === 0 ? (
        <div style={{ textAlign:'center', padding:'48px 0', color:T.muted }}>Inga medlemmar i den här vyn ännu.</div>
      ) : (
        <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
          {shown.map(m => (
            <div key={m.id} style={{ background:T.paper, borderRadius:14, padding:'16px 20px', boxShadow:`inset 0 0 0 1px ${T.line}`, display:'flex', alignItems:'center', gap:16, flexWrap:'wrap' }}>
              <div style={{ flex:1, minWidth:200 }}>
                <div style={{ display:'flex', alignItems:'center', gap:8, flexWrap:'wrap' }}>
                  <span style={{ fontWeight:600, fontSize:15 }}>{m.namn}</span>
                  <span style={{ fontSize:10, fontWeight:700, padding:'2px 8px', borderRadius:999, background: m.type==='company' ? SITE_TOKENS.sun+'33' : SITE_TOKENS.sky+'33', color: T.ink2 }}>
                    {m.type==='company' ? 'FÖRETAG' : 'PRIVAT'}
                  </span>
                </div>
                <div style={{ fontSize:12, color:T.muted, marginTop:3 }}>
                  {[m.email, m.telefon, m.orgnr && ('Org.nr ' + m.orgnr), [m.adress, m.postnummer, m.ort].filter(Boolean).join(' ')].filter(Boolean).join(' · ')}
                </div>
              </div>
              <div style={{ display:'flex', alignItems:'center', gap:8 }}>
                <button onClick={() => togglePaid(m)} style={{ padding:'7px 14px', borderRadius:999, border:0, cursor:'pointer', fontSize:12, fontWeight:600, background: m.paid ? '#E8F5EC' : T.cream2, color: m.paid ? '#2D6B4E' : T.muted, display:'flex', alignItems:'center', gap:6 }}>
                  <span style={{ width:8, height:8, borderRadius:'50%', background: m.paid ? '#3FA66A' : T.line }}/>
                  {m.paid ? 'Betald' : 'Ej betald'}
                </button>
                {isAdmin && (
                  <button onClick={() => setEditMember(m)} title="Redigera" style={{ width:34, height:34, borderRadius:8, background:T.cream2, border:0, cursor:'pointer', color:T.ink, display:'flex', alignItems:'center', justifyContent:'center' }}>
                    <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>
                  </button>
                )}
                {isAdmin && (
                  <button onClick={() => remove(m)} title="Ta bort" style={{ width:34, height:34, borderRadius:8, background:'#FDE8E8', border:0, cursor:'pointer', color:'#CC3333', display:'flex', alignItems:'center', justifyContent:'center' }}><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg></button>
                )}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ─── Info-register (de som vill ha utskick) ───────────────────────────────────
function AdminInfo({ T }) {
  const [rows, setRows] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  React.useEffect(() => {
    API.get('subscribers').then(s => setRows(s || [])).catch(() => {}).finally(() => setLoading(false));
  }, []);

  const remove = (s) => {
    if (!confirm(`Ta bort ${s.email}?`)) return;
    setRows(prev => prev.filter(x => x.email !== s.email));
    API.del('subscribers', { email: s.email }).catch(() => {});
  };
  const mailAll = () => {
    const bcc = rows.map(r => r.email).join(',');
    window.location.href = `mailto:?bcc=${encodeURIComponent(bcc)}`;
  };

  return (
    <div>
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', flexWrap:'wrap', gap:12, marginBottom:20 }}>
        <div>
          <h2 style={{ fontSize:28 }}>Informationsregister</h2>
          <p style={{ fontSize:14, color:T.muted, marginTop:6 }}>Personer som vill ha utskick om event och nyheter ({rows.length} st).</p>
        </div>
        {rows.length > 0 && (
          <button onClick={mailAll} className="btn btn-primary" style={{ padding:'10px 18px', fontSize:14 }}>Maila alla →</button>
        )}
      </div>
      {loading ? (
        <div style={{ textAlign:'center', padding:'48px 0', color:T.muted }}>Laddar…</div>
      ) : rows.length === 0 ? (
        <div style={{ textAlign:'center', padding:'48px 0', color:T.muted }}>Ingen har anmält sig till informationsutskick ännu.</div>
      ) : (
        <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
          {rows.map(s => (
            <div key={s.email} style={{ background:T.paper, borderRadius:12, padding:'12px 18px', boxShadow:`inset 0 0 0 1px ${T.line}`, display:'flex', alignItems:'center', gap:12, flexWrap:'wrap' }}>
              <div style={{ flex:1, minWidth:160 }}>
                <div style={{ fontWeight:600, fontSize:14 }}>{s.email}</div>
                {s.namn && <div style={{ fontSize:12, color:T.muted }}>{s.namn}</div>}
              </div>
              <span style={{ fontSize:11, color:T.muted }}>{s.datum}</span>
              <button onClick={() => remove(s)} title="Ta bort" style={{ padding:'6px 10px', borderRadius:8, background:'#FDE8E8', border:0, fontSize:12, fontWeight:600, color:'#CC3333', cursor:'pointer' }}><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg></button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ─── Om oss — ledamöter + stadgar ────────────────────────────────────────────
function MemberFormInline({ T, data, setField, onSave, onCancel }) {
  const ROLE_OPTIONS = ['Ordförande', 'Vice ordförande', 'Kassör', 'Sekreterare', 'Ledamot', 'Suppleant', 'Revisor'];
  return (
    <div style={{ background:T.cream, borderRadius:16, padding:'24px 26px', boxShadow:`inset 0 0 0 1.5px ${T.forest}` }}>
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:14, marginBottom:14 }}>
        <div>
          <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:6, textTransform:'uppercase', letterSpacing:'0.06em' }}>Namn</label>
          <input value={data.name} onChange={e=>setField('name',e.target.value)} placeholder="Förnamn Efternamn"
            style={{ width:'100%', padding:'12px 14px', borderRadius:10, border:0, background:T.paper, color:T.ink, fontSize:14, fontFamily:'inherit', outline:'none', boxShadow:`inset 0 0 0 1.5px ${T.line}`, boxSizing:'border-box' }}/>
        </div>
        <div>
          <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:6, textTransform:'uppercase', letterSpacing:'0.06em' }}>Roll</label>
          <select value={data.role} onChange={e=>setField('role',e.target.value)}
            style={{ width:'100%', padding:'12px 14px', borderRadius:10, border:0, background:T.paper, color:T.ink, fontSize:14, fontFamily:'inherit', outline:'none', boxShadow:`inset 0 0 0 1.5px ${T.line}`, boxSizing:'border-box', appearance:'none', cursor:'pointer' }}>
            <option value="">Välj roll…</option>
            {ROLE_OPTIONS.map(r => <option key={r} value={r}>{r}</option>)}
          </select>
        </div>
      </div>
      <div style={{ marginBottom:18 }}>
        <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:8, textTransform:'uppercase', letterSpacing:'0.06em' }}>Färg</label>
        <div style={{ display:'flex', gap:8 }}>
          {ACCENT_PRESETS.map(c => (
            <button key={c.hex} onClick={()=>setField('color',c.hex)} title={c.label}
              style={{ width:32, height:32, borderRadius:'50%', background:c.hex, border: data.color===c.hex ? `3px solid ${T.ink}` : '3px solid transparent', cursor:'pointer', transition:'all .15s' }}/>
          ))}
        </div>
      </div>
      <div style={{ display:'flex', gap:10 }}>
        <button onClick={onSave} className="btn btn-primary" style={{ fontSize:14, padding:'11px 22px' }}>Spara</button>
        <button onClick={onCancel} className="btn btn-secondary" style={{ fontSize:14, padding:'11px 20px' }}>Avbryt</button>
      </div>
    </div>
  );
}

function AdminOmOss({ T }) {
  const [members,   setMembers]   = React.useState([]);
  const [editing,   setEditing]   = React.useState(null); // null | 'new' | index
  const [formData,  setFormData]  = React.useState({ name: '', role: '', color: '#4A8B5C' });
  const [saved,     setSaved]     = React.useState(false);
  const [stadgar,   setStadgar]   = React.useState(null); // URL till uppladdad PDF, annars null
  const [uploading, setUploading] = React.useState(false);
  const fileRef = React.useRef();

  React.useEffect(() => {
    API.get('board')
      .then(b => setMembers(b && b.length ? b : [...BOARD]))
      .catch(() => setMembers([...BOARD]));
    API.get('stadgar')
      .then(s => { if (s && s.url && s.url !== 'stadgar.pdf') setStadgar(s.url); })
      .catch(() => {});
  }, []);

  const flash = () => { setSaved(true); setTimeout(() => setSaved(false), 2500); };
  const setField = (k, v) => setFormData(prev => ({ ...prev, [k]: v }));

  const openNew  = () => { setFormData({ name:'', role:'', color:'#4A8B5C' }); setEditing('new'); };
  const openEdit = (i) => { setFormData({ ...members[i] }); setEditing(i); };
  const cancel   = ()  => setEditing(null);

  const saveMember = () => {
    if (!formData.name.trim() || !formData.role.trim()) return;
    const next = editing === 'new'
      ? [...members, { ...formData }]
      : members.map((m, i) => i === editing ? { ...formData } : m);
    setMembers(next); API.post('board', { items: next }).catch(() => {}); setEditing(null); flash();
  };

  const deleteMember = (i) => {
    if (!confirm(`Ta bort ${members[i].name}?`)) return;
    const next = members.filter((_, idx) => idx !== i);
    setMembers(next); API.post('board', { items: next }).catch(() => {}); flash();
  };

  const moveUp = (i) => {
    if (i === 0) return;
    const next = [...members]; [next[i-1], next[i]] = [next[i], next[i-1]];
    setMembers(next); API.post('board', { items: next }).catch(() => {}); flash();
  };

  const moveDown = (i) => {
    if (i === members.length - 1) return;
    const next = [...members]; [next[i], next[i+1]] = [next[i+1], next[i]];
    setMembers(next); API.post('board', { items: next }).catch(() => {}); flash();
  };

  const handleFileChange = (e) => {
    const file = e.target.files[0];
    if (!file) return;
    setUploading(true);
    const reader = new FileReader();
    reader.onload = async (ev) => {
      try {
        const { url } = await API.post('stadgar', { dataBase64: ev.target.result });
        setStadgar(url);
        flash();
      } catch (err) {
        alert('Uppladdning misslyckades. Försök igen.');
      }
      setUploading(false);
    };
    reader.readAsDataURL(file);
    e.target.value = '';
  };

  return (
    <div>
      {/* ── Rubrik ── */}
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', marginBottom:28 }}>
        <div>
          <h2 style={{ fontSize:28 }}>Om oss</h2>
          <p style={{ fontSize:14, color:T.muted, marginTop:6 }}>Hantera styrelsemedlemmar och ladda upp stadgar.</p>
        </div>
        <div style={{ display:'flex', alignItems:'center', gap:12 }}>
          {saved && (
            <div style={{ display:'flex', alignItems:'center', gap:8, padding:'8px 16px', borderRadius:999, background:'#E8F5EC', color:'#2D6B4E', fontSize:13, fontWeight:600 }}>
              <svg width="14" height="14" viewBox="0 0 24 24"><path d="M4 12L9 17L20 6" stroke="currentColor" strokeWidth="2.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
              Sparat
            </div>
          )}
          {editing === null && (
            <button onClick={openNew} className="btn btn-primary" style={{ padding:'11px 20px', fontSize:14 }}>
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"><path d="M12 5v14M5 12h14"/></svg>
              Ny ledamot
            </button>
          )}
        </div>
      </div>

      {/* ── Stadgar-sektion ── */}
      <div style={{ background:T.paper, borderRadius:20, padding:'22px 28px', marginBottom:24, boxShadow:`inset 0 0 0 1px ${T.line}` }}>
        <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', gap:16, flexWrap:'wrap' }}>
          <div>
            <div style={{ fontWeight:600, fontSize:15, marginBottom:5 }}>Stadgar (PDF)</div>
            {stadgar
              ? <div style={{ fontSize:13, color:'#4A8B5C', display:'flex', alignItems:'center', gap:6 }}>
                  <svg width="13" height="13" viewBox="0 0 24 24"><path d="M4 12L9 17L20 6" stroke="currentColor" strokeWidth="2.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
                  Fil uppladdad — används på hemsidan
                </div>
              : <div style={{ fontSize:13, color:T.muted }}>Ingen fil uppladdad — använder <em>stadgar.pdf</em> som standard</div>
            }
          </div>
          <div style={{ display:'flex', gap:10, flexWrap:'wrap' }}>
            {stadgar && (
              <>
                <a href={stadgar} download="stadgar.pdf" className="btn btn-secondary" style={{ padding:'9px 18px', fontSize:13 }}>
                  <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
                  Förhandsgranska
                </a>
              </>
            )}
            <button onClick={() => fileRef.current && fileRef.current.click()} className="btn btn-primary" style={{ padding:'9px 18px', fontSize:13 }} disabled={uploading}>
              <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
              {uploading ? 'Laddar upp…' : stadgar ? 'Byt fil' : 'Ladda upp PDF'}
            </button>
            <input ref={fileRef} type="file" accept=".pdf,application/pdf" style={{ display:'none' }} onChange={handleFileChange}/>
          </div>
        </div>
      </div>

      {/* ── Nytt ledamot-formulär ── */}
      {editing === 'new' && (
        <div style={{ marginBottom:16 }}>
          <div className="eyebrow" style={{ marginBottom:12, color:T.forest }}>Ny ledamot</div>
          <MemberFormInline T={T} data={formData} setField={setField} onSave={saveMember} onCancel={cancel}/>
        </div>
      )}

      {/* ── Styrelselista ── */}
      <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
        {members.map((m, i) => (
          <div key={i}>
            {editing === i ? (
              <MemberFormInline T={T} data={formData} setField={setField} onSave={saveMember} onCancel={cancel}/>
            ) : (
              <div style={{ background:T.paper, borderRadius:16, padding:'16px 20px', boxShadow:`inset 0 0 0 1px ${T.line}`, display:'flex', alignItems:'center', gap:16 }}>
                {/* Avatar */}
                <div style={{ width:44, height:44, borderRadius:'50%', background:m.color+'18', border:`2px solid ${m.color}44`, display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
                  <svg viewBox="0 0 48 48" width="26" height="26" fill="none">
                    <circle cx="24" cy="15" r="10" fill={m.color} opacity="0.85"/>
                    <path d="M5 46 C5 34 12 28 24 28 C36 28 43 34 43 46" fill={m.color} opacity="0.65"/>
                  </svg>
                </div>
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontWeight:600, fontSize:15, lineHeight:1.2 }}>{m.name}</div>
                  <div style={{ fontSize:12, color:T.muted, marginTop:2 }}>{m.role}</div>
                </div>
                {/* Sortering upp/ned */}
                <div style={{ display:'flex', flexDirection:'column', gap:2 }}>
                  <button onClick={() => moveUp(i)} disabled={i===0}
                    style={{ width:28, height:24, border:`1px solid ${T.line}`, borderRadius:'6px 6px 0 0', background:T.cream2, cursor:i===0?'default':'pointer', opacity:i===0?0.35:1, display:'flex', alignItems:'center', justifyContent:'center' }}>
                    <svg width="10" height="7" viewBox="0 0 10 7" fill="none"><path d="M1 6L5 2L9 6" stroke={T.ink2} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>
                  </button>
                  <button onClick={() => moveDown(i)} disabled={i===members.length-1}
                    style={{ width:28, height:24, border:`1px solid ${T.line}`, borderTop:'none', borderRadius:'0 0 6px 6px', background:T.cream2, cursor:i===members.length-1?'default':'pointer', opacity:i===members.length-1?0.35:1, display:'flex', alignItems:'center', justifyContent:'center' }}>
                    <svg width="10" height="7" viewBox="0 0 10 7" fill="none"><path d="M1 1L5 5L9 1" stroke={T.ink2} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>
                  </button>
                </div>
                {/* Knappar */}
                <div style={{ display:'flex', gap:8, flexShrink:0 }}>
                  <button onClick={() => openEdit(i)} title="Redigera" style={{ width:38, height:38, borderRadius:10, background:T.cream2, border:0, cursor:'pointer', color:T.ink, display:'flex', alignItems:'center', justifyContent:'center' }}>
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>
                  </button>
                  <button onClick={() => deleteMember(i)} title="Ta bort" style={{ width:38, height:38, borderRadius:10, background:'#FDE8E8', border:0, cursor:'pointer', color:'#CC3333', display:'flex', alignItems:'center', justifyContent:'center' }}>
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg>
                  </button>
                </div>
              </div>
            )}
          </div>
        ))}
        {members.length === 0 && editing !== 'new' && (
          <div style={{ textAlign:'center', padding:'48px 0', color:T.muted }}>
            <p>Inga ledamöter ännu.</p>
            <button onClick={openNew} className="btn btn-secondary" style={{ marginTop:16 }}>Lägg till ledamot</button>
          </div>
        )}
      </div>
    </div>
  );
}

// ─── Redigera medlem (modal, endast admin) ───────────────────────────────────
function MemberEditModal({ T, member, onClose, onSaved }) {
  const isCompany = member.type === 'company';
  const [f, setF] = React.useState({
    namn: member.namn || '', email: member.email || '', telefon: member.telefon || '',
    adress: member.adress || '', postnummer: member.postnummer || '', ort: member.ort || '',
    orgnr: member.orgnr || '', bransch: member.bransch || '', kontaktperson: member.kontaktperson || '',
  });
  const [saving, setSaving] = React.useState(false);
  const set = (k, v) => setF(p => ({ ...p, [k]: v }));
  const save = async () => {
    setSaving(true);
    try { await API.patch('members', { type: member.type, id: member.id, ...f }); onSaved({ ...member, ...f }); }
    catch (e) { alert('Kunde inte spara ändringen.'); setSaving(false); }
  };
  const field = (label, k, type = 'text') => (
    <div>
      <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:5, textTransform:'uppercase', letterSpacing:'0.05em' }}>{label}</label>
      <input value={f[k]} onChange={e => set(k, e.target.value)} type={type}
        style={{ width:'100%', padding:'11px 13px', borderRadius:10, border:0, background:T.cream, boxShadow:`inset 0 0 0 1.5px ${T.line}`, fontSize:14, fontFamily:'inherit', color:T.ink, outline:'none', boxSizing:'border-box' }}/>
    </div>
  );
  return (
    <div onClick={onClose} style={{ position:'fixed', inset:0, background:'rgba(31,42,36,0.55)', zIndex:5000, display:'flex', alignItems:'center', justifyContent:'center', padding:18 }}>
      <div onClick={e => e.stopPropagation()} style={{ background:T.paper, borderRadius:20, padding:26, width:'100%', maxWidth:520, maxHeight:'90vh', overflowY:'auto', boxShadow:'0 30px 70px rgba(0,0,0,0.3)' }}>
        <h3 style={{ fontSize:22, marginBottom:18 }}>Redigera {isCompany ? 'företag' : 'medlem'}</h3>
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:12 }}>
          {isCompany ? (<>
            <div style={{ gridColumn:'1 / -1' }}>{field('Företagsnamn', 'namn')}</div>
            {field('Org.nr', 'orgnr')}
            {field('Bransch', 'bransch')}
            {field('Kontaktperson', 'kontaktperson')}
            {field('E-post', 'email', 'email')}
            {field('Telefon', 'telefon', 'tel')}
            <div style={{ gridColumn:'1 / -1' }}>{field('Adress', 'adress')}</div>
          </>) : (<>
            <div style={{ gridColumn:'1 / -1' }}>{field('Namn', 'namn')}</div>
            {field('E-post', 'email', 'email')}
            {field('Telefon', 'telefon', 'tel')}
            <div style={{ gridColumn:'1 / -1' }}>{field('Adress', 'adress')}</div>
            {field('Postnummer', 'postnummer')}
            {field('Ort', 'ort')}
          </>)}
        </div>
        <div style={{ display:'flex', gap:10, marginTop:22, justifyContent:'flex-end' }}>
          <button onClick={onClose} className="btn btn-secondary" style={{ fontSize:14, padding:'10px 18px' }}>Avbryt</button>
          <button onClick={save} disabled={saving} className="btn btn-primary" style={{ fontSize:14, padding:'10px 20px', opacity:saving?0.7:1 }}>{saving ? 'Sparar…' : 'Spara'}</button>
        </div>
      </div>
    </div>
  );
}

// ─── Redigera anmälan (modal, endast admin) ──────────────────────────────────
function SignupEditModal({ T, signup, eventId, onClose, onSaved }) {
  const [f, setF] = React.useState({
    typ: signup.typ || 'Företag', namn: signup.namn || '', kontakt: signup.kontakt || '',
    mobil: signup.mobil || '', email: signup.email || '', plats: signup.plats || '', ovrigt: signup.ovrigt || '',
  });
  const [saving, setSaving] = React.useState(false);
  const set = (k, v) => setF(p => ({ ...p, [k]: v }));
  const save = async () => {
    setSaving(true);
    try { await API.patch('signups', { eventId, id: signup.id, ...f }); onSaved({ ...signup, ...f }); }
    catch (e) { alert('Kunde inte spara ändringen.'); setSaving(false); }
  };
  const inputStyle = { width:'100%', padding:'11px 13px', borderRadius:10, border:0, background:T.cream, boxShadow:`inset 0 0 0 1.5px ${T.line}`, fontSize:14, fontFamily:'inherit', color:T.ink, outline:'none', boxSizing:'border-box' };
  const lbl = (t) => <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:5, textTransform:'uppercase', letterSpacing:'0.05em' }}>{t}</label>;
  const field = (label, k, type = 'text') => (<div>{lbl(label)}<input value={f[k]} onChange={e => set(k, e.target.value)} type={type} style={inputStyle}/></div>);
  return (
    <div onClick={onClose} style={{ position:'fixed', inset:0, background:'rgba(31,42,36,0.55)', zIndex:5000, display:'flex', alignItems:'center', justifyContent:'center', padding:18 }}>
      <div onClick={e => e.stopPropagation()} style={{ background:T.paper, borderRadius:20, padding:26, width:'100%', maxWidth:520, maxHeight:'90vh', overflowY:'auto', boxShadow:'0 30px 70px rgba(0,0,0,0.3)' }}>
        <h3 style={{ fontSize:22, marginBottom:18 }}>Redigera anmälan</h3>
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:12 }}>
          <div>{lbl('Typ')}<select value={f.typ} onChange={e => set('typ', e.target.value)} style={{ ...inputStyle, appearance:'none', cursor:'pointer' }}>
            <option>Företag</option><option>Förening</option><option>Privat</option>
          </select></div>
          {field('Namn', 'namn')}
          {field('Kontaktperson', 'kontakt')}
          {field('Mobil', 'mobil', 'tel')}
          {field('E-post', 'email', 'email')}
          {field('Önskad plats', 'plats')}
          <div style={{ gridColumn:'1 / -1' }}>{lbl('Övrigt')}<textarea value={f.ovrigt} onChange={e => set('ovrigt', e.target.value)} rows={3} style={{ ...inputStyle, resize:'vertical' }}/></div>
        </div>
        <div style={{ display:'flex', gap:10, marginTop:22, justifyContent:'flex-end' }}>
          <button onClick={onClose} className="btn btn-secondary" style={{ fontSize:14, padding:'10px 18px' }}>Avbryt</button>
          <button onClick={save} disabled={saving} className="btn btn-primary" style={{ fontSize:14, padding:'10px 20px', opacity:saving?0.7:1 }}>{saving ? 'Sparar…' : 'Spara'}</button>
        </div>
      </div>
    </div>
  );
}

// ─── Användare (styrelsens konton, endast admin) ─────────────────────────────
function AdminUsers({ T, meEmail }) {
  const [rows, setRows] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [editing, setEditing] = React.useState(null); // null | 'new' | email
  const [form, setForm] = React.useState({ email:'', name:'', role:'redigerare', password:'' });

  const load = () => { setLoading(true); API.get('users').then(u => setRows(u || [])).catch(() => {}).finally(() => setLoading(false)); };
  React.useEffect(load, []);

  const openNew = () => { setForm({ email:'', name:'', role:'redigerare', password:'' }); setEditing('new'); };
  const openEdit = (u) => { setForm({ email:u.email, name:u.name || '', role:u.role, password:'' }); setEditing(u.email); };
  const save = async () => {
    if (!form.email.trim()) return alert('E-post krävs.');
    if (editing === 'new' && !form.password) return alert('Lösenord krävs för nytt konto.');
    try {
      if (editing === 'new') await API.post('users', form);
      else await API.patch('users', { email: form.email, name: form.name, role: form.role, password: form.password || undefined });
      setEditing(null); load();
    } catch (e) { alert('Kunde inte spara kontot.'); }
  };
  const remove = async (u) => {
    if (u.email === meEmail) return alert('Du kan inte ta bort ditt eget konto.');
    if (!confirm(`Ta bort kontot ${u.email}?`)) return;
    try { await API.del('users', { email: u.email }); load(); } catch (e) { alert('Kunde inte ta bort kontot.'); }
  };

  const inputStyle = { width:'100%', padding:'11px 13px', borderRadius:10, border:0, background:T.paper, boxShadow:`inset 0 0 0 1.5px ${T.line}`, fontSize:14, fontFamily:'inherit', color:T.ink, outline:'none', boxSizing:'border-box' };

  return (
    <div>
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', flexWrap:'wrap', gap:12, marginBottom:20 }}>
        <div>
          <h2 style={{ fontSize:28 }}>Användare</h2>
          <p style={{ fontSize:14, color:T.muted, marginTop:6 }}>Styrelsens inloggningar. <strong>Admin</strong> kan allt; <strong>Redigerare</strong> ser anmälningar och medlemmar (sätta betalt).</p>
        </div>
        {editing === null && <button onClick={openNew} className="btn btn-primary" style={{ padding:'11px 20px', fontSize:14 }}>Nytt konto</button>}
      </div>

      {editing !== null && (
        <div style={{ background:T.cream, borderRadius:16, padding:'22px 24px', marginBottom:20, boxShadow:`inset 0 0 0 1.5px ${T.forest}` }}>
          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:14 }}>
            <div style={{ gridColumn:'1 / -1' }}>
              <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:5, textTransform:'uppercase' }}>E-post</label>
              <input value={form.email} disabled={editing !== 'new'} onChange={e => setForm(p => ({ ...p, email:e.target.value }))} type="email" placeholder="namn@sandared.se" style={{ ...inputStyle, opacity: editing !== 'new' ? 0.6 : 1 }}/>
            </div>
            <div>
              <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:5, textTransform:'uppercase' }}>Namn</label>
              <input value={form.name} onChange={e => setForm(p => ({ ...p, name:e.target.value }))} style={inputStyle}/>
            </div>
            <div>
              <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:5, textTransform:'uppercase' }}>Roll</label>
              <select value={form.role} onChange={e => setForm(p => ({ ...p, role:e.target.value }))} style={{ ...inputStyle, appearance:'none', cursor:'pointer' }}>
                <option value="redigerare">Redigerare</option>
                <option value="admin">Admin</option>
              </select>
            </div>
            <div style={{ gridColumn:'1 / -1' }}>
              <label style={{ display:'block', fontSize:11, fontWeight:600, color:T.muted, marginBottom:5, textTransform:'uppercase' }}>Lösenord</label>
              <input value={form.password} onChange={e => setForm(p => ({ ...p, password:e.target.value }))} type="text" placeholder={editing === 'new' ? 'Ange lösenord' : 'Lämna tomt för oförändrat'} style={inputStyle}/>
            </div>
          </div>
          <div style={{ display:'flex', gap:10, marginTop:18 }}>
            <button onClick={save} className="btn btn-primary" style={{ fontSize:14, padding:'10px 20px' }}>Spara</button>
            <button onClick={() => setEditing(null)} className="btn btn-secondary" style={{ fontSize:14, padding:'10px 18px' }}>Avbryt</button>
          </div>
        </div>
      )}

      {loading ? (
        <div style={{ textAlign:'center', padding:'48px 0', color:T.muted }}>Laddar…</div>
      ) : (
        <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
          {rows.map(u => (
            <div key={u.email} style={{ background:T.paper, borderRadius:14, padding:'14px 20px', boxShadow:`inset 0 0 0 1px ${T.line}`, display:'flex', alignItems:'center', gap:14, flexWrap:'wrap' }}>
              <div style={{ flex:1, minWidth:180 }}>
                <div style={{ fontWeight:600, fontSize:15, display:'flex', alignItems:'center', gap:8, flexWrap:'wrap' }}>
                  {u.name || u.email}
                  <span style={{ fontSize:10, fontWeight:700, padding:'2px 8px', borderRadius:999, background: u.role === 'admin' ? SITE_TOKENS.coral+'22' : SITE_TOKENS.sky+'22', color:T.ink2 }}>{u.role === 'admin' ? 'ADMIN' : 'REDIGERARE'}</span>
                  {u.email === meEmail && <span style={{ fontSize:10, color:T.muted }}>(du)</span>}
                </div>
                <div style={{ fontSize:12, color:T.muted, marginTop:2 }}>{u.email}</div>
              </div>
              <div style={{ display:'flex', gap:8, flexShrink:0 }}>
                <button onClick={() => openEdit(u)} title="Redigera" style={{ width:38, height:38, borderRadius:10, background:T.cream2, border:0, cursor:'pointer', color:T.ink, display:'flex', alignItems:'center', justifyContent:'center' }}>
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>
                </button>
                <button onClick={() => remove(u)} title="Ta bort" style={{ width:38, height:38, borderRadius:10, background:'#FDE8E8', border:0, cursor:'pointer', color:'#CC3333', display:'flex', alignItems:'center', justifyContent:'center' }}>
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg>
                </button>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ─── AdminDashboard ───────────────────────────────────────────────────────────
function AdminDashboard({ adminEmail, adminRole, onLogout }) {
  const isAdmin = adminRole === 'admin';
  const [view, setView] = React.useState('anmalningar');
  const T = SITE_TOKENS;

  const [isMobile, setIsMobile] = React.useState(window.innerWidth < 768);
  React.useEffect(() => {
    const h = () => setIsMobile(window.innerWidth < 768);
    window.addEventListener('resize', h);
    return () => window.removeEventListener('resize', h);
  }, []);
  const [menuOpen, setMenuOpen] = React.useState(false);

  const [counts, setCounts] = React.useState({ signups: null, proposals: null, members: null });
  React.useEffect(() => {
    Promise.all([
      API.get('signups').catch(() => []),
      API.get('proposals').catch(() => []),
      API.get('members').catch(() => []),
    ]).then(([s, p, m]) => setCounts({ signups: (s || []).length, proposals: (p || []).length, members: (m || []).length }));
  }, []);
  const NAV = isAdmin ? [
    { id:'anmalningar', label:'Anmälningar',   badge: counts.signups },
    { id:'medlemmar',   label:'Medlemmar',      badge: counts.members },
    { id:'kalender',    label:'Kalender',       badge: null },
    { id:'forslag',     label:'Projektförslag', badge: counts.proposals },
    { id:'omoss',       label:'Om oss',         badge: null },
    { id:'info',        label:'Info-register',  badge: null },
    { id:'anvandare',   label:'Användare',      badge: null },
  ] : [
    { id:'anmalningar', label:'Anmälningar',   badge: counts.signups },
    { id:'medlemmar',   label:'Medlemmar',      badge: counts.members },
  ];

  return (
    <div style={{ position:'fixed', inset:0, zIndex:4000, display:'flex', flexDirection:'column', fontFamily:'Manrope, system-ui, sans-serif', background:'#F0F4F2' }}>

      {/* ── Top bar ── */}
      <div style={{ background:T.forestDk, flexShrink:0, paddingInline: isMobile ? 14 : 32 }}>
        {/* Row 1: branding + user */}
        <div style={{ height:58, display:'flex', alignItems:'center', gap: isMobile ? 10 : 14 }}>
          {isMobile && (
            <button onClick={() => setMenuOpen(o => !o)} aria-label="Meny" style={{ width:38, height:38, borderRadius:10, background:'rgba(251,247,240,0.12)', border:`1px solid ${T.cream}28`, display:'flex', alignItems:'center', justifyContent:'center', cursor:'pointer', flexShrink:0 }}>
              {menuOpen
                ? <svg width="15" height="15" viewBox="0 0 14 14" fill="none"><path d="M1 1L13 13M13 1L1 13" stroke={T.cream} strokeWidth="2" strokeLinecap="round"/></svg>
                : <svg width="18" height="14" viewBox="0 0 18 14"><path d="M0 1H18M0 7H18M0 13H18" stroke={T.cream} strokeWidth="2" strokeLinecap="round"/></svg>}
            </button>
          )}
          <Wordmark size={isMobile ? 26 : 30} dark/>
          {!isMobile && <div style={{ height:18, width:1, background:T.cream+'33' }}/>}
          {!isMobile && <span style={{ fontSize:11, fontWeight:700, color:T.cream+'88', letterSpacing:'0.14em', textTransform:'uppercase' }}>Styrelsepanel</span>}
          <div style={{ flex:1 }}/>
          <div style={{ display:'flex', alignItems:'center', gap:10, fontSize:13, color:T.cream+'cc' }}>
            <div style={{ width:28, height:28, borderRadius:'50%', background:T.forest, border:`1.5px solid ${T.cream}44`, display:'flex', alignItems:'center', justifyContent:'center', color:T.cream, fontSize:11, fontWeight:700 }}>
              {adminEmail.charAt(0).toUpperCase()}
            </div>
            {!isMobile && <span>{adminEmail}</span>}
          </div>
          <button onClick={onLogout} style={{ padding:'7px 14px', borderRadius:8, background:'rgba(251,247,240,0.1)', border:`1px solid ${T.cream}28`, fontSize:13, fontWeight:600, cursor:'pointer', color:T.cream+'cc', display:'flex', alignItems:'center', gap:7, transition:'background .15s' }}
            onMouseEnter={e=>e.currentTarget.style.background='rgba(251,247,240,0.18)'}
            onMouseLeave={e=>e.currentTarget.style.background='rgba(251,247,240,0.1)'}>
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
            Logga ut
          </button>
        </div>
        {/* Row 2: flikar (endast desktop — mobil använder hamburgermenyn) */}
        {!isMobile && (
        <div style={{ display:'flex', gap:4, paddingBottom:0, overflowX:'auto', WebkitOverflowScrolling:'touch', scrollbarWidth:'none' }}>
          {NAV.map(n => {
            const active = view === n.id;
            return (
              <button key={n.id} onClick={()=>setView(n.id)} style={{ padding: isMobile ? '10px 14px' : '10px 20px', borderRadius:'10px 10px 0 0', background: active ? '#F0F4F2' : 'transparent', color: active ? T.ink : T.cream+'99', border:0, cursor:'pointer', fontSize: isMobile ? 13 : 14, fontWeight: active ? 600 : 400, display:'flex', alignItems:'center', gap:8, transition:'all .15s', flexShrink:0, whiteSpace:'nowrap' }}>
                {n.label}
                {n.badge != null && (
                  <span style={{ fontSize:11, padding:'2px 7px', borderRadius:999, background: active ? T.forest+'22' : T.cream+'22', color: active ? T.forest : T.cream+'88' }}>{n.badge}</span>
                )}
              </button>
            );
          })}
        </div>
        )}
      </div>

      {/* ── Mobil hamburgermeny ── */}
      {isMobile && menuOpen && (
        <div style={{ position:'absolute', top:58, left:0, right:0, zIndex:10, background:T.forestDk, borderTop:`1px solid ${T.cream}22`, boxShadow:'0 12px 30px rgba(0,0,0,0.3)' }}>
          {NAV.map(n => {
            const active = view === n.id;
            return (
              <button key={n.id} onClick={() => { setView(n.id); setMenuOpen(false); }} style={{ width:'100%', textAlign:'left', padding:'14px 20px', background: active ? 'rgba(251,247,240,0.12)' : 'transparent', color: active ? T.cream : T.cream+'aa', border:0, borderBottom:`1px solid ${T.cream}14`, cursor:'pointer', fontSize:15, fontWeight: active ? 700 : 500, display:'flex', alignItems:'center', justifyContent:'space-between', gap:10 }}>
                <span>{n.label}</span>
                {n.badge != null && <span style={{ fontSize:11, padding:'2px 8px', borderRadius:999, background:T.cream+'22', color:T.cream+'cc' }}>{n.badge}</span>}
              </button>
            );
          })}
        </div>
      )}

      {/* ── Content (full width) ── */}
      <div style={{ flex:1, overflowY:'auto', padding: isMobile ? '20px 14px' : '32px 36px' }}>
        {view === 'anmalningar' && <AdminAnmalningar T={T} isMobile={isMobile} isAdmin={isAdmin}/>}
        {view === 'medlemmar'   && <AdminMedlemmar T={T} isAdmin={isAdmin}/>}
        {view === 'kalender'    && isAdmin && <AdminKalender T={T}/>}
        {view === 'forslag'     && isAdmin && <AdminForslag T={T}/>}
        {view === 'omoss'       && isAdmin && <AdminOmOss T={T}/>}
        {view === 'info'        && isAdmin && <AdminInfo T={T}/>}
        {view === 'anvandare'   && isAdmin && <AdminUsers T={T} meEmail={adminEmail}/>}
      </div>

    </div>
  );
}

Object.assign(window, { AdminLoginModal, AdminDashboard });
