/* ============================================================
   KODILA — Šifrant: Uporabniki
   ============================================================ */

const ROLES = [
  { value: 'administrator', label: 'Administrator' },
  { value: 'zaposleni', label: 'Zaposleni' },
];
const ROLE_LABEL = { administrator: 'Administrator', zaposleni: 'Zaposleni' };
const STATUS_LABEL = { active: 'Aktiven', inactive: 'Nedejaven' };

function userNameRenderer(p) {
  const initials = (p.value || '').split(' ').map(s => s[0]).filter(Boolean).join('').slice(0, 2).toUpperCase();
  return `<div class="cell-with-thumb"><span class="cell-thumb">${initials || '?'}</span>
    <span class="cell-strong">${p.value}</span></div>`;
}
function userRoleRenderer(p) {
  const cls = p.value === 'administrator' ? 'brand' : '';
  return `<span class="badge ${cls}"><span class="dot"></span>${ROLE_LABEL[p.value] || p.value}</span>`;
}
function userStatusRenderer(p) {
  const label = STATUS_LABEL[p.value] || p.value;
  const cls = (window.STATUS_MAP[label] || 'default');
  const c = cls === 'default' ? '' : cls;
  return `<span class="badge ${c}"><span class="dot"></span>${label}</span>`;
}
function userLastLoginRenderer(p) {
  return `<span class="cell-mono" style="font-size:12.5px">${p.value ? fmtDate(p.value.slice(0, 10)) : 'Še ni prijavljen'}</span>`;
}

const USER_COLS = [
  { field: 'id', headerName: 'ID', width: 70, cellClass: 'cell-mono', pinned: 'left' },
  { field: 'fullName', headerName: 'Ime in priimek', flex: 2, minWidth: 220, cellRenderer: userNameRenderer },
  { field: 'email', headerName: 'E-pošta', minWidth: 200 },
  { field: 'role', headerName: 'Vloga', width: 150, cellRenderer: userRoleRenderer },
  { field: 'groupName', headerName: 'Skupina', minWidth: 150, valueFormatter: p => p.value || 'Brez skupine' },
  { field: 'department', headerName: 'Oddelek', minWidth: 160, valueFormatter: p => p.value || '—' },
  { field: 'status', headerName: 'Status', width: 130, cellRenderer: userStatusRenderer },
  { field: 'lastLoginAt', headerName: 'Zadnja prijava', width: 160, cellRenderer: userLastLoginRenderer },
];

const EMPTY_USER = { id: null, fullName: '', email: '', username: '', role: 'zaposleni', groupId: null, department: '', status: 'active', password: '' };

const ERROR_MESSAGES = {
  email: { invalid: 'Vnesite veljaven e-poštni naslov.', taken: 'Ta e-poštni naslov je že v uporabi.' },
  fullName: { required: 'Ime in priimek je obvezno.' },
  role: { invalid: 'Izberite veljavno vlogo.' },
  groupId: { invalid: 'Izbrana skupina ni veljavna.' },
  password: {
    min_length: 'Geslo mora vsebovati vsaj 8 znakov.',
    min_upper: 'Geslo mora vsebovati vsaj 2 veliki črki.',
    min_digits: 'Geslo mora vsebovati vsaj 2 števki.',
    min_special: 'Geslo mora vsebovati vsaj 2 posebna znaka.',
  },
};

function passwordHint(policy) {
  if (!policy) return 'Najmanj 8 znakov, vsaj 2 veliki črki, 2 števki in 2 posebna znaka.';
  return `Najmanj ${policy.minLength} znakov, vsaj ${policy.minUpper} veliki črki, ${policy.minDigits} števki in ${policy.minSpecial} posebna znaka.`;
}

/* --- Vnosni obrazec (drawer) --- */
function UserForm({ initial, currentUser, passwordPolicy, groups, onSave, onToggleStatus, onClose }) {
  const isEdit = !!(initial && initial.id);
  const [f, setF] = useState(initial && initial.id
    ? { ...EMPTY_USER, ...initial, username: initial.username || '', department: initial.department || '', groupId: initial.groupId ?? null, password: '' }
    : { ...EMPTY_USER });
  const [changePassword, setChangePassword] = useState(!isEdit);
  const [errors, setErrors] = useState({});
  const [saving, setSaving] = useState(false);
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));

  const isSelf = isEdit && currentUser && currentUser.id === f.id;

  const save = async () => {
    setSaving(true);
    const payload = {
      fullName: f.fullName.trim(),
      email: f.email.trim(),
      username: f.username.trim() || null,
      role: f.role,
      groupId: f.role === 'administrator' ? null : f.groupId,
      department: f.department.trim() || null,
    };
    if (!isEdit || changePassword) {
      payload.password = f.password;
    }
    const ok = await onSave(f.id, payload, isEdit, setErrors);
    setSaving(false);
    if (ok) onClose();
  };

  const fieldError = (field) => {
    const codes = errors[field];
    if (!codes || !codes.length) return null;
    const map = ERROR_MESSAGES[field] || {};
    return codes.map(c => map[c] || c).join(' ');
  };

  return (
    <div className="overlay" onMouseDown={(e) => { if (e.target.classList.contains('overlay')) onClose(); }}>
      <div className="drawer" onMouseDown={e => e.stopPropagation()}>
        <div className="drawer-head">
          <div className="app-ico" style={tintStyle('brand')} dangerouslySetInnerHTML={{ __html: I('users', 20) }} />
          <div className="grow">
            <div className="drawer-title">{isEdit ? 'Uredi uporabnika' : 'Nov uporabnik'}</div>
            <div className="muted" style={{ fontSize: 12.5 }}>{isEdit ? f.email : 'Račun za prijavo v intranet'}</div>
          </div>
          <button className="btn btn-icon btn-ghost" onClick={onClose} dangerouslySetInnerHTML={{ __html: I('x', 18) }} />
        </div>

        <div className="drawer-body">
          <div className="form-grid">
            <div className="form-sec-title"><span dangerouslySetInnerHTML={{ __html: I('tag', 14) }} /> Osnovni podatki</div>

            <div className="field col-2">
              <label>Ime in priimek <span className="req">*</span></label>
              <input className="input" value={f.fullName} onChange={e => set('fullName', e.target.value)}
                placeholder="npr. Marko Kuhar"
                style={fieldError('fullName') ? { borderColor: 'var(--danger)' } : null} />
              {fieldError('fullName') && <span style={{ color: 'var(--danger)', fontSize: 12 }}>{fieldError('fullName')}</span>}
            </div>

            <div className="field">
              <label>E-pošta <span className="req">*</span></label>
              <input className="input" type="email" value={f.email} onChange={e => set('email', e.target.value)}
                placeholder="ime.priimek@kodila.si"
                style={fieldError('email') ? { borderColor: 'var(--danger)' } : null} />
              {fieldError('email') && <span style={{ color: 'var(--danger)', fontSize: 12 }}>{fieldError('email')}</span>}
            </div>
            <div className="field">
              <label>Uporabniško ime (neobvezno)</label>
              <input className="input" value={f.username} onChange={e => set('username', e.target.value)} placeholder="mkuhar" />
            </div>

            <div className="form-sec-title"><span dangerouslySetInnerHTML={{ __html: I('briefcase', 14) }} /> Vloga in oddelek</div>

            <div className="field">
              <label>Vloga</label>
              <select className="select" value={f.role} onChange={e => set('role', e.target.value)}>
                {ROLES.map(r => <option key={r.value} value={r.value}>{r.label}</option>)}
              </select>
            </div>
            <div className="field">
              <label>Oddelek / lokacija</label>
              <input className="input" value={f.department} onChange={e => set('department', e.target.value)} placeholder="npr. Trgovina MS" />
            </div>
            <div className="field col-2">
              <label>Uporabniška skupina</label>
              <select className="select" value={f.groupId ?? ''} disabled={f.role === 'administrator'}
                onChange={e => set('groupId', e.target.value ? Number(e.target.value) : null)}
                style={fieldError('groupId') ? { borderColor: 'var(--danger)' } : null}>
                <option value="">Brez skupine</option>
                {(groups || []).filter(g => !g.isSystem).map(g => <option key={g.id} value={g.id}>{g.name}</option>)}
              </select>
              {f.role === 'administrator' && <span className="muted" style={{ fontSize: 12 }}>Administratorji so samodejno v skupini "Administrator".</span>}
              {fieldError('groupId') && <span style={{ color: 'var(--danger)', fontSize: 12 }}>{fieldError('groupId')}</span>}
            </div>

            <div className="form-sec-title"><span dangerouslySetInnerHTML={{ __html: I('lock', 14) }} /> Geslo</div>

            {isEdit && (
              <div className="field col-2">
                <label className="check"><input type="checkbox" checked={changePassword} onChange={e => setChangePassword(e.target.checked)} /> Spremeni geslo</label>
              </div>
            )}
            {(!isEdit || changePassword) && (
              <div className="field col-2">
                <label>{isEdit ? 'Novo geslo' : 'Geslo'} <span className="req">*</span></label>
                <input className="input mono" type="password" value={f.password} onChange={e => set('password', e.target.value)}
                  autoComplete="new-password"
                  style={fieldError('password') ? { borderColor: 'var(--danger)' } : null} />
                <span className="muted" style={{ fontSize: 12 }}>{passwordHint(passwordPolicy)}</span>
                {fieldError('password') && <span style={{ color: 'var(--danger)', fontSize: 12 }}>{fieldError('password')}</span>}
              </div>
            )}

            {isEdit && (
              <>
                <div className="form-sec-title"><span dangerouslySetInnerHTML={{ __html: I('settings', 14) }} /> Status</div>
                <div className="field col-2" style={{ flexDirection: 'row', alignItems: 'center', gap: 12 }}>
                  <StatusBadge value={STATUS_LABEL[f.status] || f.status} />
                  {isSelf
                    ? <span className="muted" style={{ fontSize: 12.5 }}>Lastnega računa ni mogoče deaktivirati.</span>
                    : (
                      <button className="btn btn-sm" type="button" onClick={() => onToggleStatus(f.id, f.status === 'active' ? 'inactive' : 'active', (newStatus) => set('status', newStatus))}>
                        {f.status === 'active' ? 'Deaktiviraj' : 'Aktiviraj'}
                      </button>
                    )}
                </div>
              </>
            )}
          </div>
        </div>

        <div className="drawer-foot">
          <span className="muted grow" style={{ fontSize: 12.5 }}>
            <span className="req">*</span> obvezna polja
          </span>
          <button className="btn" onClick={onClose}>Prekliči</button>
          <button className="btn btn-primary" onClick={save} disabled={saving}>
            <span dangerouslySetInnerHTML={{ __html: I('save', 16) }} /> {isEdit ? 'Shrani' : 'Dodaj uporabnika'}
          </button>
        </div>
      </div>
    </div>
  );
}

function Uporabniki({ currentUser }) {
  const toast = useToast();
  const [rows, setRows] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [editing, setEditing] = useState(null);
  const [passwordPolicy, setPasswordPolicy] = useState(null);
  const [groups, setGroups] = useState([]);

  const load = async () => {
    setLoading(true);
    setError('');
    const { ok, data } = await api('/api/users');
    if (ok) {
      setRows(data.users);
    } else {
      setError('Seznama uporabnikov ni bilo mogoče naložiti.');
    }
    setLoading(false);
  };

  useEffect(() => {
    load();
    api('/api/auth/password-policy').then(({ ok, data }) => { if (ok) setPasswordPolicy(data); });
    api('/api/groups').then(({ ok, data }) => { if (ok) setGroups(data.groups); });
  }, []);

  const save = async (id, payload, isEdit, setErrors) => {
    const { ok, data } = isEdit
      ? await api(`/api/users/${id}`, { method: 'PUT', body: JSON.stringify(payload) })
      : await api('/api/users', { method: 'POST', body: JSON.stringify(payload) });

    if (!ok) {
      setErrors(data.errors || {});
      return false;
    }

    setRows(rs => isEdit ? rs.map(r => r.id === data.user.id ? data.user : r) : [data.user, ...rs]);
    toast(isEdit ? 'Uporabnik posodobljen' : 'Uporabnik dodan: ' + data.user.fullName, 'check');
    return true;
  };

  const toggleStatus = async (id, newStatus, onDone) => {
    const action = newStatus === 'inactive' ? 'deactivate' : 'reactivate';
    const { ok, data } = await api(`/api/users/${id}/${action}`, { method: 'POST' });
    if (!ok) {
      toast(data.error === 'cannot_deactivate_self' ? 'Lastnega računa ni mogoče deaktivirati.' : 'Napaka pri spremembi statusa.', 'alert');
      return;
    }
    setRows(rs => rs.map(r => r.id === data.user.id ? data.user : r));
    onDone(data.user.status);
    toast(newStatus === 'inactive' ? 'Uporabnik deaktiviran' : 'Uporabnik aktiviran', 'check');
  };

  return (
    <div>
      {error && <div className="badge dng" style={{ marginBottom: 12 }}>{error}</div>}

      <DataGrid
        columnDefs={USER_COLS}
        rowData={rows}
        getRowId={(d) => d.id}
        selectable
        exportName="kodila-uporabniki"
        exportTitle="Šifrant uporabnikov"
        searchPlaceholder="Išči po imenu, e-pošti, oddelku…"
        onRowOpen={(d) => setEditing(d)}
        actions={
          <button className="btn btn-primary btn-sm" onClick={() => setEditing({})} disabled={loading}>
            <span dangerouslySetInnerHTML={{ __html: I('plus', 15) }} /> Nov uporabnik
          </button>
        }
      />

      {editing !== null && (
        <UserForm
          initial={editing}
          currentUser={currentUser}
          passwordPolicy={passwordPolicy}
          groups={groups}
          onSave={save}
          onToggleStatus={toggleStatus}
          onClose={() => setEditing(null)}
        />
      )}
    </div>
  );
}
Object.assign(window, { Uporabniki });
