// Adminpanel för användare.
//
// Tidigare byggde "Byt lösenord" på webbläsarens prompt() och alert() — rutor
// som ser olika ut i varje webbläsare, inte går att styla, och som vissa
// webbläsare blockerar helt. Då såg det ut som att bytet inte fungerade.
// Nu sker allt inne i panelen: lösenordsbyte, avstängning, borttagning och
// återställning, med besked på plats istället för popup-rutor.
//
// Att ta bort ett konto lämnar raden kvar i databasen (namnet ska fortsätta
// synas på gamla offerter), men kontot kan inte logga in och syns inte i
// listor. Har kontot offerter eller kunder måste någon ta över dem först.

function UsersPanel({ open, onClose, me }) {
  const [users, setUsers] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [fel, setFel] = React.useState('');
  const [ok, setOk] = React.useState('');
  const [showNew, setShowNew] = React.useState(false);
  const [visaBorttagna, setVisaBorttagna] = React.useState(false);
  // Vilken rad har en öppen underpanel, och vilken sort: 'losen' | 'tabort'
  const [oppen, setOppen] = React.useState(null);

  const load = async () => {
    setLoading(true); setFel('');
    try {
      const { users } = await api(`/api/users${visaBorttagna ? '?borttagna=1' : ''}`);
      setUsers(users);
    } catch (e) { setFel(e.message || 'Kunde inte hämta användare.'); }
    finally { setLoading(false); }
  };

  React.useEffect(() => { if (open) { setShowNew(false); setOppen(null); setOk(''); load(); } }, [open, visaBorttagna]);
  React.useEffect(() => {
    if (!open) return;
    const t = (e) => { if (e.key === 'Escape') { e.stopPropagation(); if (oppen) setOppen(null); else onClose(); } };
    window.addEventListener('keydown', t, true);
    return () => window.removeEventListener('keydown', t, true);
  }, [open, oppen, onClose]);

  if (!open) return null;

  const meddela = (text) => { setOk(text); setFel(''); setTimeout(() => setOk(''), 6000); };

  const saveUser = async (u, patch) => {
    setFel('');
    try {
      await api(`/api/users/${u.id}`, { method: 'PUT', body: JSON.stringify(patch) });
      if (patch.active === false) meddela(`${u.name} är avstängd och utloggad.`);
      else if (patch.active === true) meddela(`${u.name} kan logga in igen.`);
      else if (patch.role) meddela(`${u.name} är nu ${patch.role === 'admin' ? 'admin' : 'säljare'}.`);
      await load();
    } catch (e) { setFel(e.message || 'Kunde inte spara ändringen.'); }
  };

  const aterstall = async (u) => {
    setFel('');
    try {
      await api(`/api/users/${u.id}/aterstall`, { method: 'POST' });
      meddela(`${u.name} är återställd och kan logga in igen.`);
      await load();
    } catch (e) { setFel(e.message || 'Kunde inte återställa kontot.'); }
  };

  const aktiva = users.filter(u => u.active && !u.deleted_at);

  return (
    <div onClick={onClose} style={upOverlay}>
      <div role="dialog" aria-modal="true" aria-label="Användare" onClick={e => e.stopPropagation()} style={upDialog}>
        <div style={upHuvud}>
          <div>
            <div style={upEyebrow}>Administration</div>
            <h2 style={upRubrik}>Användare</h2>
          </div>
          <button onClick={onClose} aria-label="Stäng" style={upStangKnapp}><Icon name="close" size={22}/></button>
        </div>

        <div style={{ padding: '18px 28px 26px', overflow: 'auto' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12, flexWrap: 'wrap', marginBottom: 14 }}>
            {!showNew ? (
              <button onClick={() => { setShowNew(true); setOppen(null); }} style={upKnapp('primar')}>
                <Icon name="plus" size={14}/> Lägg till användare
              </button>
            ) : <span />}
            <label style={{ fontSize: 12.5, color: 'var(--fg-muted)', display: 'inline-flex', alignItems: 'center', gap: 6, cursor: 'pointer' }}>
              <input type="checkbox" checked={visaBorttagna} onChange={e => setVisaBorttagna(e.target.checked)} />
              Visa borttagna
            </label>
          </div>

          {showNew && <NewUserForm onDone={(namn) => { setShowNew(false); meddela(`${namn} är upplagd.`); load(); }} onCancel={() => setShowNew(false)} />}

          {fel && <div role="alert" style={upFelRuta}>{fel}</div>}
          {ok && <div role="status" style={upOkRuta}>{ok}</div>}

          {loading && !users.length ? <div style={{ color: 'var(--fg-muted)', fontSize: 13 }}>Hämtar…</div> : (
            <div style={{ border: '1px solid var(--border)', borderRadius: 'var(--radius-card)', overflow: 'hidden' }}>
              {users.map(u => {
                const jag = u.id === (me && me.id);
                const borttagen = !!u.deleted_at;
                return (
                  <div key={u.id} style={{ borderTop: '1px solid var(--border)', opacity: borttagen ? .6 : 1 }}>
                    <div style={upRad}>
                      <span style={{ ...upAvatar, background: u.role === 'admin' ? 'var(--ulab-navy)' : '#e8f1f8', color: u.role === 'admin' ? '#fff' : 'var(--ulab-navy)' }}>
                        {initialer(u.name)}
                      </span>
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--ulab-navy)', display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                          {u.name}
                          {jag && <span style={upTagg}>du</span>}
                          {borttagen && <span style={{ ...upTagg, background: '#fdf0ee', color: '#8a3b30', borderColor: '#eab5ac' }}>borttagen</span>}
                          {!borttagen && !u.active && <span style={{ ...upTagg, background: '#fff7ed', color: '#8a5a12', borderColor: '#f0b866' }}>avstängd</span>}
                          {!borttagen && u.active && u.inloggad && <span style={{ ...upTagg, background: '#eef7f4', color: '#2b7d70', borderColor: '#9fcfc1' }}>inloggad</span>}
                        </div>
                        <div style={{ fontSize: 12, color: 'var(--fg-muted)', marginTop: 2 }}>
                          {u.email}
                          {(u.antal_offerter || u.antal_kunder) ? ` · ${u.antal_offerter} offert${u.antal_offerter === 1 ? '' : 'er'}, ${u.antal_kunder} kund${u.antal_kunder === 1 ? '' : 'er'}` : ''}
                        </div>
                      </div>

                      {borttagen ? (
                        <button onClick={() => aterstall(u)} style={upKnapp()}>Återställ</button>
                      ) : (
                        <React.Fragment>
                          <RollVal
                            value={u.role}
                            disabled={jag}
                            title={jag ? 'Du kan inte ändra din egen roll' : 'Admin kommer åt allt, även andras offerter och kunder'}
                            onChange={role => saveUser(u, { role })} />
                          <button
                            onClick={() => setOppen(oppen && oppen.id === u.id && oppen.typ === 'losen' ? null : { id: u.id, typ: 'losen' })}
                            aria-expanded={!!(oppen && oppen.id === u.id && oppen.typ === 'losen')}
                            style={upKnapp()}>Byt lösenord</button>
                          <button
                            onClick={() => saveUser(u, { active: !u.active })}
                            disabled={jag}
                            title={jag ? 'Du kan inte stänga av dig själv' : u.active ? 'Kontot kan inte logga in förrän det aktiveras igen' : 'Låt kontot logga in igen'}
                            style={{ ...upKnapp(), opacity: jag ? .5 : 1, cursor: jag ? 'not-allowed' : 'pointer' }}>
                            {u.active ? 'Stäng av' : 'Aktivera'}
                          </button>
                          <button
                            onClick={() => setOppen(oppen && oppen.id === u.id && oppen.typ === 'tabort' ? null : { id: u.id, typ: 'tabort' })}
                            disabled={jag}
                            aria-label={`Ta bort ${u.name}`}
                            title={jag ? 'Du kan inte ta bort dig själv' : 'Ta bort kontot'}
                            style={{ ...upIkonKnapp, opacity: jag ? .4 : 1, cursor: jag ? 'not-allowed' : 'pointer' }}>×</button>
                        </React.Fragment>
                      )}
                    </div>

                    {oppen && oppen.id === u.id && oppen.typ === 'losen' && (
                      <LosenordsByte anvandare={u} onKlar={(t) => { setOppen(null); meddela(t); }} onAvbryt={() => setOppen(null)} />
                    )}
                    {oppen && oppen.id === u.id && oppen.typ === 'tabort' && (
                      <TaBort anvandare={u} kandidater={aktiva.filter(x => x.id !== u.id)}
                        onKlar={(t) => { setOppen(null); meddela(t); load(); }} onAvbryt={() => setOppen(null)} />
                    )}
                  </div>
                );
              })}
              {!users.length && !loading && <div style={{ padding: 16, fontSize: 13, color: 'var(--fg-muted)' }}>Inga användare.</div>}
            </div>
          )}

          <div style={{ fontSize: 11.5, color: 'var(--fg-subtle)', marginTop: 14, lineHeight: 1.6, maxWidth: '66ch' }}>
            <b style={{ color: 'var(--fg-muted)' }}>Admin</b> kommer åt allt — även andras offerter och kunder — och kan hantera användare, papperskorg och produktblad.
            <b style={{ color: 'var(--fg-muted)', marginLeft: 8 }}>Säljare</b> ser sina egna offerter och kan bara ta bort sina egna offerter och kunder.
          </div>
        </div>
      </div>
    </div>
  );
}

function RollVal({ value, onChange, disabled, title }) {
  return (
    <span role="group" aria-label="Roll" title={title} style={{ display: 'inline-flex', border: '1px solid var(--border-strong)', borderRadius: 'var(--radius-button)', overflow: 'hidden', opacity: disabled ? .55 : 1 }}>
      {[['saljare', 'Säljare'], ['admin', 'Admin']].map(([v, t]) => (
        <button key={v} type="button" disabled={disabled} aria-pressed={value === v}
          onClick={() => value !== v && onChange(v)}
          style={{
            fontFamily: 'var(--font-sans)', fontSize: 12, fontWeight: 600, padding: '6px 10px', border: 'none',
            cursor: disabled ? 'not-allowed' : 'pointer',
            background: value === v ? 'var(--ulab-navy)' : '#fff', color: value === v ? '#fff' : 'var(--fg-muted)',
          }}>{t}</button>
      ))}
    </span>
  );
}

// Nytt lösenord åt någon annan. Lösenordet visas i klartext — admin ska ju
// kunna läsa upp det — och går att slumpa fram.
function LosenordsByte({ anvandare, onKlar, onAvbryt }) {
  const [pw, setPw] = React.useState('');
  const [fel, setFel] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => { if (ref.current) ref.current.focus(); }, []);

  const slumpa = () => {
    // Läsbara tecken utan 0/O och l/1, så det går att läsa upp i telefon.
    const t = 'ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789';
    let s = '';
    const a = new Uint32Array(12); crypto.getRandomValues(a);
    for (const n of a) s += t[n % t.length];
    setPw(s);
  };
  const spara = async () => {
    if (pw.length < 8) { setFel('Minst 8 tecken.'); return; }
    setBusy(true); setFel('');
    try {
      const r = await api(`/api/users/${anvandare.id}/reset-password`, { method: 'POST', body: JSON.stringify({ password: pw }) });
      onKlar(`Nytt lösenord sparat åt ${anvandare.name}.` + (r.utloggade ? ` ${r.utloggade === 1 ? 'En öppen inloggning' : r.utloggade + ' öppna inloggningar'} loggades ut.` : ''));
    } catch (e) { setFel(e.message || 'Kunde inte byta lösenord.'); }
    finally { setBusy(false); }
  };

  return (
    <div style={upUnderpanel}>
      <div style={{ fontSize: 12.5, color: 'var(--fg-muted)', marginBottom: 10 }}>
        Nytt lösenord åt <b style={{ color: 'var(--ulab-navy)' }}>{anvandare.name}</b>. Ge det till hen — det går att byta under <i>Byt lösenord</i> i menyn sedan.
      </div>
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center' }}>
        <input ref={ref} value={pw} onChange={e => setPw(e.target.value)} placeholder="Minst 8 tecken" autoComplete="off" spellCheck={false}
          onKeyDown={e => { if (e.key === 'Enter') spara(); }}
          style={{ ...upFalt, width: 260, fontFamily: 'ui-monospace, Consolas, monospace', letterSpacing: '.04em' }} />
        <button type="button" onClick={slumpa} style={upKnapp()}>Slumpa</button>
        <button type="button" onClick={spara} disabled={busy} style={upKnapp('primar')}>{busy ? 'Sparar…' : 'Spara lösenordet'}</button>
        <button type="button" onClick={onAvbryt} style={upKnapp()}>Avbryt</button>
      </div>
      {fel && <div role="alert" style={{ ...upFelRuta, marginTop: 10, marginBottom: 0 }}>{fel}</div>}
    </div>
  );
}

// Ta bort ett konto. Har det offerter eller kunder måste någon ta över dem —
// annars blir de osynliga för alla utom admin.
function TaBort({ anvandare, kandidater, onKlar, onAvbryt }) {
  const harNagot = (anvandare.antal_offerter || 0) + (anvandare.antal_kunder || 0) > 0;
  const [till, setTill] = React.useState(kandidater[0] ? String(kandidater[0].id) : '');
  const [fel, setFel] = React.useState('');
  const [busy, setBusy] = React.useState(false);

  const taBort = async () => {
    if (harNagot && !till) { setFel('Välj vem som tar över.'); return; }
    setBusy(true); setFel('');
    try {
      const r = await api(`/api/users/${anvandare.id}`, { method: 'DELETE', body: JSON.stringify(harNagot ? { overtasAv: Number(till) } : {}) });
      onKlar(`${anvandare.name} är borttagen.` + (r.overtogsAv ? ` ${r.offerter} offerter och ${r.kunder} kunder gick till ${r.overtogsAv.name}.` : ''));
    } catch (e) { setFel(e.message || 'Kunde inte ta bort kontot.'); }
    finally { setBusy(false); }
  };

  return (
    <div style={{ ...upUnderpanel, background: '#fdf0ee', borderTop: '1px solid #eab5ac' }}>
      <div style={{ fontSize: 13, color: 'var(--ulab-navy)', marginBottom: 10 }}>
        <b>Ta bort {anvandare.name}?</b> Kontot kan inte logga in och försvinner ur listorna. Namnet står kvar på gamla offerter och anteckningar, och kontot går att återställa under <i>Visa borttagna</i>.
      </div>
      {harNagot && (
        <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap', marginBottom: 10, fontSize: 13 }}>
          <span>{anvandare.antal_offerter} offert{anvandare.antal_offerter === 1 ? '' : 'er'} och {anvandare.antal_kunder} kund{anvandare.antal_kunder === 1 ? '' : 'er'} tas över av</span>
          <select value={till} onChange={e => setTill(e.target.value)} style={{ ...upFalt, width: 'auto', minWidth: 180 }}>
            {!kandidater.length && <option value="">— ingen annan aktiv användare —</option>}
            {kandidater.map(k => <option key={k.id} value={k.id}>{k.name}{k.role === 'admin' ? ' (admin)' : ''}</option>)}
          </select>
        </div>
      )}
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
        <button type="button" onClick={taBort} disabled={busy || (harNagot && !till)} style={{ ...upKnapp('primar'), background: 'var(--ulab-coral)' }}>
          {busy ? 'Tar bort…' : 'Ta bort kontot'}</button>
        <button type="button" onClick={onAvbryt} style={upKnapp()}>Avbryt</button>
      </div>
      {fel && <div role="alert" style={{ ...upFelRuta, marginTop: 10, marginBottom: 0 }}>{fel}</div>}
    </div>
  );
}

function NewUserForm({ onDone, onCancel }) {
  const [name, setName] = React.useState('');
  const [email, setEmail] = React.useState('');
  const [password, setPassword] = React.useState('');
  const [role, setRole] = React.useState('saljare');
  const [fel, setFel] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => { if (ref.current) ref.current.focus(); }, []);

  const slumpa = () => {
    const t = 'ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789';
    let s = ''; const a = new Uint32Array(12); crypto.getRandomValues(a);
    for (const n of a) s += t[n % t.length];
    setPassword(s);
  };

  const submit = async (e) => {
    e.preventDefault();
    setFel('');
    if (!name.trim()) return setFel('Skriv ett namn.');
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(email.trim())) return setFel('E‑postadressen ser inte riktig ut.');
    if (password.length < 8) return setFel('Lösenordet måste vara minst 8 tecken.');
    setBusy(true);
    try {
      await api('/api/users', { method: 'POST', body: JSON.stringify({ name: name.trim(), email: email.trim(), password, role }) });
      onDone(name.trim());
    } catch (e) { setFel(e.message || 'Kunde inte skapa användaren.'); }
    finally { setBusy(false); }
  };

  return (
    <form onSubmit={submit} style={{ border: '1px solid var(--border)', borderRadius: 'var(--radius-card)', padding: 16, marginBottom: 16, background: 'var(--ulab-cream)' }}>
      <div style={{ ...upEyebrow, marginBottom: 10 }}>Ny användare</div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: 12 }}>
        <label style={upEtikett}>Namn
          <input ref={ref} value={name} onChange={e => setName(e.target.value)} style={upFalt} autoComplete="off" />
        </label>
        <label style={upEtikett}>E‑post
          <input type="email" value={email} onChange={e => setEmail(e.target.value)} style={upFalt} autoComplete="off" />
        </label>
        <label style={upEtikett}>Tillfälligt lösenord
          <span style={{ display: 'flex', gap: 6, marginTop: 4 }}>
            <input value={password} onChange={e => setPassword(e.target.value)} style={{ ...upFalt, marginTop: 0, fontFamily: 'ui-monospace, Consolas, monospace' }} autoComplete="new-password" spellCheck={false} />
            <button type="button" onClick={slumpa} style={upKnapp()}>Slumpa</button>
          </span>
        </label>
        <label style={upEtikett}>Roll
          <span style={{ display: 'block', marginTop: 4 }}><RollVal value={role} onChange={setRole} /></span>
        </label>
      </div>
      {fel && <div role="alert" style={{ ...upFelRuta, marginTop: 12, marginBottom: 0 }}>{fel}</div>}
      <div style={{ display: 'flex', gap: 8, marginTop: 14 }}>
        <button type="submit" disabled={busy} style={upKnapp('primar')}>{busy ? 'Skapar…' : 'Skapa användare'}</button>
        <button type="button" onClick={onCancel} style={upKnapp()}>Avbryt</button>
      </div>
    </form>
  );
}

function initialer(namn) {
  return String(namn || '?').split(/\s+/).filter(Boolean).slice(0, 2).map(o => o[0].toUpperCase()).join('');
}

const upOverlay = { position: 'fixed', inset: 0, background: 'rgba(0,54,95,.32)', zIndex: 60, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 32 };
const upDialog = { width: 'min(860px, 100%)', maxHeight: '88vh', background: '#fff', borderRadius: 8, boxShadow: 'var(--shadow-modal)', display: 'flex', flexDirection: 'column', overflow: 'hidden', fontFamily: 'var(--font-sans)' };
const upHuvud = { padding: '22px 28px', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' };
const upEyebrow = { fontSize: 11, fontWeight: 600, letterSpacing: '.16em', textTransform: 'uppercase', color: 'var(--fg-muted)' };
const upRubrik = { margin: '4px 0 0', fontFamily: 'var(--font-serif)', fontWeight: 500, fontSize: 24, color: 'var(--ulab-navy)' };
const upStangKnapp = { background: 'transparent', border: 'none', cursor: 'pointer', color: 'var(--ulab-navy)', width: 36, height: 36, display: 'flex', alignItems: 'center', justifyContent: 'center', borderRadius: 'var(--radius-button)' };
const upRad = { display: 'flex', alignItems: 'center', gap: 12, padding: '12px 14px', flexWrap: 'wrap' };
const upAvatar = { flex: 'none', width: 34, height: 34, borderRadius: 'var(--radius-button)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 12, fontWeight: 700 };
const upTagg = { fontSize: 10.5, fontWeight: 700, letterSpacing: '.06em', textTransform: 'uppercase', padding: '1px 7px', borderRadius: 'var(--radius-pill)', border: '1px solid var(--border-strong)', background: 'var(--ulab-cool-grey)', color: 'var(--fg-muted)' };
const upIkonKnapp = { width: 32, height: 32, border: '1px solid transparent', background: 'transparent', color: 'var(--fg-subtle)', fontSize: 18, lineHeight: 1, borderRadius: 'var(--radius-button)', fontFamily: 'var(--font-sans)' };
const upUnderpanel = { padding: '12px 14px 14px 60px', background: 'var(--ulab-cool-grey)', borderTop: '1px solid var(--border)' };
const upEtikett = { fontSize: 12, fontWeight: 600, color: 'var(--ulab-navy)', display: 'block' };
const upFalt = { display: 'block', width: '100%', marginTop: 4, fontSize: 13, padding: '8px 10px', border: '1px solid var(--border-strong)', borderRadius: 'var(--radius-button)', fontFamily: 'var(--font-sans)', color: 'var(--ulab-navy)', background: '#fff' };
const upFelRuta = { background: '#fdf0ee', border: '1px solid #eab5ac', color: '#8a3b30', borderRadius: 'var(--radius-button)', padding: '9px 12px', fontSize: 12.5, marginBottom: 12, lineHeight: 1.5 };
const upOkRuta = { background: '#eef7f4', border: '1px solid #9fcfc1', color: '#2b7d70', borderRadius: 'var(--radius-button)', padding: '9px 12px', fontSize: 12.5, marginBottom: 12, lineHeight: 1.5 };
function upKnapp(sort) {
  const primar = sort === 'primar';
  return {
    display: 'inline-flex', alignItems: 'center', gap: 6, fontFamily: 'var(--font-sans)', fontSize: 12.5, fontWeight: 600,
    padding: '7px 12px', borderRadius: 'var(--radius-button)', cursor: 'pointer', whiteSpace: 'nowrap',
    background: primar ? 'var(--ulab-navy)' : '#fff', color: primar ? '#fff' : 'var(--ulab-navy)',
    border: '1px solid ' + (primar ? 'var(--ulab-navy)' : 'var(--border-strong)'),
  };
}

window.UsersPanel = UsersPanel;
