import { useState, useEffect, useRef, useCallback } from 'react';
import { useToast } from '../contexts/ToastContext.jsx';
import { api } from '../utils/api.js';
import Avatar from '../components/Avatar.jsx';
import UserFooter from '../components/UserFooter.jsx';
import PasswordInput from '../components/PasswordInput.jsx';

const SIDEBAR_W = 320;

function isValidEmail(e) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e); }
function isValidPhone(p) {
  if (!p || !p.trim()) return true;
  const digits = p.replace(/[\s\-\(\)\+\.x#]/g, '');
  return /^\d{7,15}$/.test(digits);
}

function parseCSV(text) {
  const lines = text.split(/\r?\n/).map(l => l.trim()).filter(Boolean);
  const rows = [], invalid = [];
  for (let i = 0; i < lines.length; i++) {
    const line = lines[i];
    if (i === 0 && /^name\s*,/i.test(line)) continue;
    const parts = line.split(',').map(p => p.trim());
    if (parts.length < 2 || parts.length > 4) { invalid.push({ line, reason: 'Must have 2–4 comma-separated fields' }); continue; }
    const [name, email, password, role] = parts;
    if (!name || !/\S+\s+\S+/.test(name)) { invalid.push({ line, reason: 'Name must be two words (First Last)' }); continue; }
    if (!email || !isValidEmail(email)) { invalid.push({ line, reason: `Invalid email: "${email}"` }); continue; }
    rows.push({ name: name.trim(), email: email.trim().toLowerCase(), password: (password || '').trim(), role: (role || 'member').trim().toLowerCase() });
  }
  return { rows, invalid };
}

// ── User Row (accordion list item) ───────────────────────────────────────────
function UserRow({ u, onUpdated, onEdit }) {
  const toast = useToast();
  const [open, setOpen] = useState(false);

  const handleSuspend = async () => {
    if (!confirm(`Suspend ${u.name}?`)) return;
    try { await api.suspendUser(u.id); toast('User suspended', 'success'); onUpdated(); }
    catch (e) { toast(e.message, 'error'); }
  };
  const handleActivate = async () => {
    try { await api.activateUser(u.id); toast('User activated', 'success'); onUpdated(); }
    catch (e) { toast(e.message, 'error'); }
  };
  const handleDelete = async () => {
    if (u.role === 'admin') return toast('Demote to member before deleting an admin', 'error');
    if (!confirm(`Delete ${u.name}?\n\nThis will:\n• Anonymise their account and free their email for re-use\n• Remove all their messages from conversations\n• Freeze any direct messages they were part of\n• Remove all their group memberships\n\nThis cannot be undone.`)) return;
    try { await api.deleteUser(u.id); toast('User deleted', 'success'); onUpdated(); }
    catch (e) { toast(e.message, 'error'); }
  };

  return (
    <div style={{ borderBottom: '1px solid var(--border)' }}>
      <button onClick={() => setOpen(o => !o)}
        style={{ width:'100%', display:'flex', alignItems:'center', gap:10, padding:'10px 12px',
          background:'none', border:'none', cursor:'pointer', textAlign:'left', color:'var(--text-primary)' }}>
        <Avatar user={u} size="sm" />
        <div style={{ flex:1, minWidth:0 }}>
          <div style={{ display:'flex', alignItems:'center', gap:6, flexWrap:'wrap' }}>
            <span style={{ fontWeight:600, fontSize:14 }}>{u.display_name || u.name}</span>
            {u.display_name && <span style={{ fontSize:12, color:'var(--text-tertiary)' }}>({u.name})</span>}
            <span className={`role-badge role-${u.role}`}>{u.role}</span>
            {u.status !== 'active' && <span className="role-badge status-suspended">{u.status}</span>}
            {!!u.is_default_admin && <span className="text-xs" style={{ color:'var(--text-tertiary)' }}>Default Admin</span>}
          </div>
          <div style={{ fontSize:12, color:'var(--text-secondary)', marginTop:1, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{u.email}</div>
        </div>
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"
          style={{ flexShrink:0, transition:'transform 0.2s', transform:open?'rotate(180deg)':'none', color:'var(--text-tertiary)' }}>
          <polyline points="6 9 12 15 18 9"/>
        </svg>
      </button>

      {open && !u.is_default_admin && (
        <div style={{ padding:'6px 12px 12px', display:'flex', alignItems:'center', gap:8 }}>
          <button className="btn btn-primary btn-sm" onClick={() => { setOpen(false); onEdit(u); }}>Edit User</button>
          <div style={{ marginLeft:'auto', display:'flex', gap:8 }}>
            {u.status === 'active' ? (
              <button className="btn btn-sm" style={{ background:'var(--warning)', color:'white' }} onClick={handleSuspend}>Suspend</button>
            ) : u.status === 'suspended' ? (
              <button className="btn btn-sm" style={{ background:'var(--success)', color:'white' }} onClick={handleActivate}>Activate</button>
            ) : null}
            <button className="btn btn-danger btn-sm" onClick={handleDelete}>Delete</button>
          </div>
        </div>
      )}
    </div>
  );
}

// ── User Form (create / edit) ─────────────────────────────────────────────────
function UserForm({ user, userPass, onDone, onCancel, isMobile, onIF, onIB }) {
  const toast = useToast();
  const isEdit = !!user;

  const [firstName, setFirstName] = useState(user?.first_name || '');
  const [lastName,  setLastName]  = useState(user?.last_name  || '');
  const [email,     setEmail]     = useState(user?.email      || '');
  const [phone,     setPhone]     = useState(user?.phone      || '');
  const [role,      setRole]      = useState(user?.role       || 'member');
  const [isMinor,   setIsMinor]   = useState(!!user?.is_minor);
  const [password,  setPassword]  = useState('');
  const [pwEnabled, setPwEnabled] = useState(!isEdit);
  const [saving,    setSaving]    = useState(false);

  const fmtLastLogin = (ts) => {
    if (!ts) return 'Never';
    const d = new Date(ts); const today = new Date(); today.setHours(0,0,0,0);
    const yesterday = new Date(today); yesterday.setDate(yesterday.getDate() - 1);
    const dd = new Date(d); dd.setHours(0,0,0,0);
    if (dd >= today) return 'Today';
    if (dd >= yesterday) return 'Yesterday';
    return dd.toISOString().slice(0, 10);
  };

  const handleSubmit = async () => {
    if (!isEdit && (!email.trim() || !isValidEmail(email.trim())))
      return toast('Valid email address required', 'error');
    if (!firstName.trim()) return toast('First name is required', 'error');
    if (!lastName.trim())  return toast('Last name is required',  'error');
    if (!isValidPhone(phone)) return toast('Invalid phone number', 'error');
    if (!['member', 'admin', 'manager'].includes(role)) return toast('Role is required', 'error');
    if (!isEdit && (!password || password.length < 6))
      return toast('Password must be at least 6 characters', 'error');
    if (isEdit && pwEnabled && (!password || password.length < 6))
      return toast('New password must be at least 6 characters', 'error');

    setSaving(true);
    try {
      if (isEdit) {
        await api.updateUser(user.id, {
          firstName: firstName.trim(),
          lastName:  lastName.trim(),
          phone:     phone.trim(),
          isMinor,
          role,
          ...(pwEnabled && password ? { password } : {}),
        });
        toast('User updated', 'success');
      } else {
        await api.createUser({
          firstName: firstName.trim(),
          lastName:  lastName.trim(),
          email:     email.trim(),
          phone:     phone.trim(),
          isMinor,
          role,
          password,
        });
        toast('User created', 'success');
      }
      onDone();
    } catch (e) {
      toast(e.message, 'error');
    } finally {
      setSaving(false);
    }
  };

  const colGrid = isMobile ? '1fr' : '1fr 1fr';
  const lbl = (text, required, note) => (
    <label className="text-sm font-medium" style={{ color:'var(--text-secondary)', display:'block', marginBottom:4 }}>
      {text}
      {required && <span style={{ color:'var(--error)', marginLeft:2 }}>*</span>}
      {note && <span style={{ fontSize:11, color:'var(--text-tertiary)', fontWeight:400, marginLeft:6 }}>{note}</span>}
    </label>
  );

  return (
    <div style={{ maxWidth: isMobile ? '100%' : 580 }}>

      {/* Back + title */}
      <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:20 }}>
        <button onClick={onCancel} className="btn btn-secondary btn-sm"
          style={{ display:'flex', alignItems:'center', gap:4, flexShrink:0 }}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
            <polyline points="15 18 9 12 15 6"/>
          </svg>
          Back
        </button>
        <span style={{ fontSize:16, fontWeight:700, color:'var(--text-primary)' }}>
          {isEdit ? 'Edit User' : 'Create User'}
        </span>
      </div>

      {/* Row 1: Login (email) — full width */}
      <div style={{ marginBottom:12 }}>
        {lbl('Login (email)', !isEdit)}
        <input className="input" type="email" placeholder="user@example.com"
          value={email} onChange={e => setEmail(e.target.value)}
          disabled={isEdit}
          style={{ width:'100%', ...(isEdit ? { opacity:0.6, cursor:'not-allowed' } : {}) }}
          autoComplete="new-password" onFocus={onIF} onBlur={onIB} />
      </div>

      {/* Row 2: First Name + Last Name */}
      <div style={{ display:'grid', gridTemplateColumns:colGrid, gap:12, marginBottom:12 }}>
        <div>
          {lbl('First Name', true)}
          <input className="input" placeholder="Jane"
            value={firstName} onChange={e => setFirstName(e.target.value)}
            autoComplete="new-password" autoCapitalize="words" onFocus={onIF} onBlur={onIB} />
        </div>
        <div>
          {lbl('Last Name', true)}
          <input className="input" placeholder="Smith"
            value={lastName} onChange={e => setLastName(e.target.value)}
            autoComplete="new-password" autoCapitalize="words" onFocus={onIF} onBlur={onIB} />
        </div>
      </div>

      {/* Row 3: Phone + Role */}
      <div style={{ display:'grid', gridTemplateColumns:colGrid, gap:12, marginBottom:12 }}>
        <div>
          {lbl('Phone', false, '(optional)')}
          <input className="input" type="tel" placeholder="+1 555 000 0000"
            value={phone} onChange={e => setPhone(e.target.value)}
            autoComplete="new-password" onFocus={onIF} onBlur={onIB} />
        </div>
        <div>
          {lbl('App Role', true)}
          <select className="input" value={role} onChange={e => setRole(e.target.value)}>
            <option value="member">Member</option>
            <option value="manager">Manager</option>
            <option value="admin">Admin</option>
          </select>
        </div>
      </div>

      {/* Row 4: Is minor */}
      <div style={{ marginBottom:12 }}>
        <label style={{ display:'flex', alignItems:'center', gap:8, cursor:'pointer', fontSize:14, color:'var(--text-primary)', userSelect:'none' }}>
          <input type="checkbox" checked={isMinor} onChange={e => setIsMinor(e.target.checked)}
            style={{ accentColor:'var(--primary)', width:15, height:15 }} />
          User is a minor
        </label>
      </div>

      {/* Row 5: Password */}
      <div style={{ marginBottom:16 }}>
        {lbl('Password',
          (!isEdit) || (isEdit && pwEnabled),
          isEdit && !pwEnabled ? '(not changing — click Reset Password to set a new one)' :
          !isEdit ? `(blank = ${userPass})` : null
        )}
        <div style={{ opacity: pwEnabled ? 1 : 0.55 }}>
          <PasswordInput
            value={password} onChange={e => setPassword(e.target.value)}
            placeholder={isEdit && !pwEnabled ? '••••••••' : 'Min 6 characters'}
            disabled={!pwEnabled}
            autoComplete="new-password"
            onFocus={onIF} onBlur={onIB}
          />
        </div>
      </div>

      {/* Row 6: Buttons */}
      <div style={{ display:'flex', alignItems:'center', gap:8, flexWrap:'wrap', marginBottom:10 }}>
        <button className="btn btn-primary" onClick={handleSubmit} disabled={saving}>
          {saving ? 'Saving…' : isEdit ? 'Save Changes' : 'Create User'}
        </button>
        {isEdit && !pwEnabled && (
          <button className="btn btn-sm" style={{ background:'var(--error)', color:'white' }}
            onClick={() => setPwEnabled(true)}>
            Reset Password
          </button>
        )}
        {isEdit && pwEnabled && (
          <button className="btn btn-secondary btn-sm"
            onClick={() => { setPwEnabled(false); setPassword(''); }}>
            Cancel Reset
          </button>
        )}
        <button className="btn btn-secondary" onClick={onCancel} style={{ marginLeft:'auto' }}>
          Cancel
        </button>
      </div>

      {/* Row 7 (edit only): Last login + must change password */}
      {isEdit && (
        <div style={{ display:'flex', alignItems:'center', gap:14, flexWrap:'wrap', fontSize:12, color:'var(--text-tertiary)', paddingTop:4, borderTop:'1px solid var(--border)' }}>
          <span>Last Login: <strong style={{ color:'var(--text-secondary)' }}>{fmtLastLogin(user.last_online)}</strong></span>
          {!!user.must_change_password && (
            <span style={{ color:'var(--warning)', fontWeight:600 }}>⚠ Must change password</span>
          )}
        </div>
      )}
    </div>
  );
}

// ── Bulk Import Form ──────────────────────────────────────────────────────────
function BulkImportForm({ userPass, onCreated }) {
  const toast = useToast();
  const fileRef = useRef(null);
  const [csvFile, setCsvFile] = useState(null);
  const [csvRows, setCsvRows] = useState([]);
  const [csvInvalid, setCsvInvalid] = useState([]);
  const [bulkResult, setBulkResult] = useState(null);
  const [loading, setLoading] = useState(false);
  const handleFile = e => {
    const file = e.target.files?.[0]; if (!file) return;
    setCsvFile(file); setBulkResult(null);
    const reader = new FileReader();
    reader.onload = ev => { const { rows, invalid } = parseCSV(ev.target.result); setCsvRows(rows); setCsvInvalid(invalid); };
    reader.readAsText(file);
  };
  const handleImport = async () => {
    if (!csvRows.length) return;
    setLoading(true);
    try {
      const result = await api.bulkUsers(csvRows);
      setBulkResult(result); setCsvRows([]); setCsvFile(null); setCsvInvalid([]);
      if (fileRef.current) fileRef.current.value = '';
      onCreated();
    } catch(e) { toast(e.message, 'error'); }
    finally { setLoading(false); }
  };
  return (
    <div style={{ maxWidth:560 }} className="flex-col gap-4">
      <div className="card" style={{ background:'var(--background)', border:'1px dashed var(--border)' }}>
        <p className="text-sm font-medium" style={{ marginBottom:6 }}>CSV Format</p>
        <code style={{ fontSize:12, color:'var(--text-secondary)', display:'block', background:'var(--surface)', padding:8, borderRadius:4, border:'1px solid var(--border)', whiteSpace:'pre' }}>{"name,email,password,role\nJane Smith,jane@company.com,,member\nBob Jones,bob@company.com,TempPass1,admin"}</code>
        <p className="text-xs" style={{ color:'var(--text-tertiary)', marginTop:8 }}>Name and email required. Blank password defaults to <strong>{userPass}</strong>, blank role defaults to member.</p>
      </div>
      <div style={{ display:'flex', alignItems:'center', gap:10, flexWrap:'wrap' }}>
        <label className="btn btn-secondary" style={{ cursor:'pointer', margin:0 }}>
          Select CSV File<input ref={fileRef} type="file" accept=".csv,.txt" style={{ display:'none' }} onChange={handleFile} />
        </label>
        {csvFile && <span className="text-sm" style={{ color:'var(--text-secondary)' }}>{csvFile.name}{csvRows.length > 0 && <span style={{ color:'var(--text-tertiary)', marginLeft:6 }}>({csvRows.length} valid)</span>}</span>}
        {csvRows.length > 0 && <button className="btn btn-primary" onClick={handleImport} disabled={loading}>{loading ? 'Creating…' : `Create ${csvRows.length} User${csvRows.length!==1?'s':''}`}</button>}
      </div>
      {csvInvalid.length > 0 && (
        <div style={{ background:'rgba(229,57,53,0.07)', border:'1px solid #e53935', borderRadius:'var(--radius)', padding:10 }}>
          <p className="text-sm font-medium" style={{ color:'#e53935', marginBottom:6 }}>{csvInvalid.length} line{csvInvalid.length!==1?'s':''} skipped</p>
          <div style={{ maxHeight:100, overflowY:'auto' }}>
            {csvInvalid.map((e,i) => <div key={i} style={{ fontSize:12, padding:'2px 0', color:'var(--text-secondary)' }}><code style={{ fontSize:11 }}>{e.line}</code><span style={{ color:'#e53935', marginLeft:8 }}>— {e.reason}</span></div>)}
          </div>
        </div>
      )}
      {bulkResult && (
        <div style={{ border:'1px solid var(--border)', borderRadius:'var(--radius)', padding:12 }}>
          <p className="text-sm font-medium" style={{ color:'var(--success)', marginBottom: bulkResult.skipped.length ? 8 : 0 }}>✓ {bulkResult.created.length} user{bulkResult.created.length!==1?'s':''} created</p>
          {bulkResult.skipped.length > 0 && (
            <>
              <p className="text-sm font-medium" style={{ color:'var(--text-secondary)', marginBottom:6 }}>{bulkResult.skipped.length} skipped:</p>
              <div style={{ maxHeight:112, overflowY:'auto', border:'1px solid var(--border)', borderRadius:'var(--radius)' }}>
                {bulkResult.skipped.map((s,i) => (
                  <div key={i} style={{ display:'flex', justifyContent:'space-between', padding:'5px 10px', borderBottom: i<bulkResult.skipped.length-1?'1px solid var(--border)':'none', fontSize:13, gap:12 }}>
                    <span>{s.email}</span><span style={{ color:'var(--text-tertiary)', flexShrink:0 }}>{s.reason}</span>
                  </div>
                ))}
              </div>
            </>
          )}
          <button className="btn btn-secondary btn-sm" style={{ marginTop:10 }} onClick={() => setBulkResult(null)}>Dismiss</button>
        </div>
      )}
    </div>
  );
}

// ── Main page ─────────────────────────────────────────────────────────────────
export default function UserManagerPage({ isMobile = false, onProfile, onHelp, onAbout }) {
  const [users,      setUsers]      = useState([]);
  const [loading,    setLoading]    = useState(true);
  const [loadError,  setLoadError]  = useState('');
  const [search,     setSearch]     = useState('');
  const [view,       setView]       = useState('list'); // 'list' | 'create' | 'edit' | 'bulk'
  const [editUser,   setEditUser]   = useState(null);
  const [userPass,   setUserPass]   = useState('user@1234');
  const [inputFocused, setInputFocused] = useState(false);
  const onIF = () => setInputFocused(true);
  const onIB = () => setInputFocused(false);

  const load = useCallback(async () => {
    setLoadError(''); setLoading(true);
    try { const { users } = await api.getUsers(); setUsers(users || []); }
    catch(e) { setLoadError(e.message || 'Failed to load users'); }
    finally { setLoading(false); }
  }, []);

  useEffect(() => {
    load();
    api.getSettings().then(({ settings }) => { if (settings.user_pass) setUserPass(settings.user_pass); }).catch(() => {});
  }, [load]);

  const filtered = users
    .filter(u =>
      !search || u.name?.toLowerCase().includes(search.toLowerCase()) ||
      u.display_name?.toLowerCase().includes(search.toLowerCase()) ||
      u.email?.toLowerCase().includes(search.toLowerCase())
    )
    .sort((a, b) => a.name.localeCompare(b.name));

  const goList   = ()  => { setView('list');   setEditUser(null); };
  const goCreate = ()  => { setView('create'); setEditUser(null); };
  const goEdit   = (u) => { setView('edit');   setEditUser(u); };
  const goBulk   = ()  => { setView('bulk');   setEditUser(null); };

  const navItem = (label, active, onClick) => (
    <button onClick={onClick}
      style={{ display:'block', width:'100%', textAlign:'left', padding:'8px 10px',
        borderRadius:'var(--radius)', border:'none',
        background: active ? 'var(--primary-light)' : 'transparent',
        color: active ? 'var(--primary)' : 'var(--text-primary)',
        cursor:'pointer', fontWeight: active ? 600 : 400, fontSize:14, marginBottom:2 }}>
      {label}
    </button>
  );

  const isFormView = view === 'create' || view === 'edit';

  return (
    <div style={{ display:'flex', flex:1, overflow:'hidden', minHeight:0 }}>

      {/* ── Desktop sidebar ── */}
      {!isMobile && (
        <div style={{ width:SIDEBAR_W, flexShrink:0, borderRight:'1px solid var(--border)', display:'flex', flexDirection:'column', background:'var(--surface)', overflow:'hidden' }}>
          <div style={{ padding:'16px 16px 0' }}>
            <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:16 }}>
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--primary)" strokeWidth="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
              <span style={{ fontSize:16, fontWeight:700, color:'var(--text-primary)' }}>User Manager</span>
            </div>
            <div className="section-label" style={{ marginBottom:6 }}>View</div>
            {navItem(`All Users${!loading ? ` (${users.length})` : ''}`, view === 'list' || view === 'edit', goList)}
            {navItem('+ Create User', view === 'create', goCreate)}
            {navItem('Bulk Import CSV', view === 'bulk', goBulk)}
          </div>
          <div style={{ flex:1 }} />
          <UserFooter onProfile={onProfile} onHelp={onHelp} onAbout={onAbout} />
        </div>
      )}

      {/* ── Right panel ── */}
      <div style={{ flex:1, display:'flex', flexDirection:'column', overflow:'hidden', minWidth:0, background:'var(--background)' }}>

        {/* Mobile tab bar */}
        {isMobile && (
          <div style={{ background:'var(--surface)', borderBottom:'1px solid var(--border)', padding:'0 12px', display:'flex', gap:6, height:48, alignItems:'center', flexShrink:0 }}>
            <span style={{ fontWeight:700, fontSize:14, marginRight:4, color:'var(--text-primary)' }}>Users</span>
            <button className={`btn btn-sm ${!isFormView && view !== 'bulk' ? 'btn-primary' : 'btn-secondary'}`} onClick={goList}>All</button>
            <button className={`btn btn-sm ${isFormView ? 'btn-primary' : 'btn-secondary'}`} onClick={goCreate}>+ Create</button>
          </div>
        )}

        {/* Content */}
        <div style={{ flex:1, display:'flex', flexDirection:'column', overflow:'hidden', minHeight:0, background:'var(--background)' }}>

          {/* LIST VIEW */}
          {view === 'list' && (
            <>
              <div style={{ padding:'16px 16px 8px', flexShrink:0 }}>
                <input className="input" placeholder="Search users…" value={search} onChange={e => setSearch(e.target.value)}
                  onFocus={onIF} onBlur={onIB}
                  autoComplete="new-password" autoCorrect="off" spellCheck={false}
                  style={{ width:'100%', maxWidth: isMobile ? '100%' : 400 }} />
              </div>
              <div style={{ flex:1, overflowY:'auto', padding:'0 16px', paddingBottom: isMobile ? 'calc(82px + env(safe-area-inset-bottom, 0px))' : 16, overscrollBehavior:'contain' }}>
                <div style={{ background:'var(--surface)', borderRadius:'var(--radius)', boxShadow:'var(--shadow-sm)', overflow:'hidden' }}>
                  {loading ? (
                    <div style={{ padding:48, textAlign:'center' }}><div className="spinner" /></div>
                  ) : loadError ? (
                    <div style={{ padding:32, textAlign:'center', color:'var(--error)' }}>
                      <div style={{ marginBottom:12 }}>⚠ {loadError}</div>
                      <button className="btn btn-secondary btn-sm" onClick={load}>Retry</button>
                    </div>
                  ) : filtered.length === 0 ? (
                    <div style={{ padding:32, textAlign:'center', color:'var(--text-tertiary)', fontSize:14 }}>
                      {search ? 'No users match your search.' : 'No users yet.'}
                    </div>
                  ) : (
                    filtered.map(u => <UserRow key={u.id} u={u} onUpdated={load} onEdit={goEdit} />)
                  )}
                </div>
              </div>
            </>
          )}

          {/* CREATE / EDIT FORM */}
          {isFormView && (
            <div style={{ flex:1, overflowY:'auto', padding:16, paddingBottom: isMobile ? 'calc(82px + env(safe-area-inset-bottom, 0px))' : 16, overscrollBehavior:'contain' }}>
              <UserForm
                user={view === 'edit' ? editUser : null}
                userPass={userPass}
                onDone={() => { load(); goList(); }}
                onCancel={goList}
                isMobile={isMobile}
                onIF={onIF}
                onIB={onIB}
              />
            </div>
          )}

          {/* BULK IMPORT */}
          {view === 'bulk' && (
            <div style={{ flex:1, overflowY:'auto', padding:16, paddingBottom: isMobile ? 'calc(82px + env(safe-area-inset-bottom, 0px))' : 16, overscrollBehavior:'contain' }}>
              <BulkImportForm userPass={userPass} onCreated={load} />
            </div>
          )}
        </div>

        {/* Mobile footer — fixed, hidden when keyboard is up */}
        {isMobile && !inputFocused && (
          <div style={{ position:'fixed', bottom:0, left:0, right:0, zIndex:20, background:'var(--surface)', borderTop:'1px solid var(--border)' }}>
            <UserFooter onProfile={onProfile} onHelp={onHelp} onAbout={onAbout} />
          </div>
        )}
      </div>
    </div>
  );
}
