/**
 * Gestão de utilizadores — painel direito do Controle de acesso
 * Criar · Editar · Congelar · Copiar · Eliminar
 */
(function () {
  'use strict';

  const ROLE_META = [
    { value: 'super_admin', label: 'Super Admin', group: 'Ops', code: 'SU' },
    { value: 'ops_lead', label: 'Chefe Ops', group: 'Ops', code: 'CO' },
    { value: 'technician', label: 'Suporte', group: 'Ops', code: 'TEC' },
    { value: 'noc', label: 'NOC', group: 'Ops', code: 'NOC' },
    { value: 'sales_admin', label: 'Sales Admin', group: 'Comercial', code: 'SAD' },
    { value: 'sales_support', label: 'Sales Support', group: 'Comercial', code: 'SSU' },
    { value: 'finance', label: 'Financeiro', group: 'Negócio', code: 'FIN' },
    { value: 'marketing', label: 'Marketing', group: 'Negócio', code: 'MKT' },
    { value: 'seo', label: 'SEO', group: 'Negócio', code: 'SEO' },
    { value: 'developer', label: 'Developer', group: 'Plataforma', code: 'DEV' },
    { value: 'devops', label: 'DevOps', group: 'Plataforma', code: 'DVO' },
    { value: 'security_analyst', label: 'Segurança / SOC', group: 'Plataforma', code: 'SOC' },
    { value: 'content_editor', label: 'Conteúdo / CMS', group: 'Plataforma', code: 'CMS' },
    { value: 'agentic_operator', label: 'Operador Agentes IA', group: 'Plataforma', code: 'AIO' },
    { value: 'partner', label: 'Partner', group: 'Externo', code: 'PTR' },
  ];

  const ASSIGNABLE = ROLE_META.filter((r) => r.value !== 'super_admin');
  const PORTAL_ID = 'um-modal-portal';

  let users = [];
  let filterQ = '';
  let filterStatus = 'all';
  let modalMode = null;
  let modalUser = null;
  let createDefaultRole = 'technician';
  let saving = false;
  let msg = '';
  let currentHost = null;
  let currentOpts = null;

  function esc(s) {
    return String(s ?? '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
  }

  function roleMeta(roleId) {
    return ROLE_META.find((r) => r.value === roleId) || { label: roleId, group: '—', code: '?' };
  }

  function groupForRole(roleId) {
    return roleMeta(roleId).group;
  }

  function roleSelectGrouped(selected, includeSuper = false) {
    const list = includeSuper ? ROLE_META : ASSIGNABLE;
    const groups = [...new Set(list.map((r) => r.group))];
    return groups.map((g) => {
      const opts = list.filter((r) => r.group === g).map((r) =>
        `<option value="${r.value}"${r.value === selected ? ' selected' : ''}>${esc(r.label)} (${r.code})</option>`
      ).join('');
      return `<optgroup label="${esc(g)}">${opts}</optgroup>`;
    }).join('');
  }

  function filteredUsers(roleLock) {
    const q = filterQ.trim().toLowerCase();
    return users.filter((u) => {
      if (roleLock && u.role !== roleLock && !(roleLock === 'super_admin' && u.username === 'root')) return false;
      if (filterStatus === 'active' && !u.active) return false;
      if (filterStatus === 'inactive' && u.active) return false;
      if (!q) return true;
      const hay = [u.username, u.email, u.display_name, roleMeta(u.role).label, roleMeta(u.role).group].join(' ').toLowerCase();
      return hay.includes(q);
    });
  }

  async function loadUsers() {
    const r = await fetchWithTimeout('/api/v1/auth/users', { headers: authHeaders() });
    if (!r.ok) throw new Error(`${r.status}`);
    const data = await r.json();
    users = data.users || [];
    return users;
  }

  async function apiUser(path, opts = {}) {
    const r = await fetchWithTimeout(`/api/v1/auth${path}`, {
      ...opts,
      headers: authHeaders({ 'Content-Type': 'application/json', ...(opts.headers || {}) }),
    });
    if (!r.ok) {
      const t = await r.text();
      throw new Error(t.slice(0, 200) || String(r.status));
    }
    return r.json();
  }

  function renderModalHtml() {
    if (!modalMode) return '';
    const isCreate = modalMode === 'create';
    const isClone = modalMode === 'clone';
    const u = modalUser || {};
    const title = isCreate ? 'Criar utilizador' : isClone ? 'Copiar utilizador' : 'Editar utilizador';
    const defaultRole = isCreate ? createDefaultRole : (u.role || createDefaultRole);

    return `
      <div class="um-modal-root" role="dialog" aria-modal="true">
        <div class="um-backdrop" data-um-close></div>
        <article class="um-modal-card" data-um-card>
          <header class="um-modal-head">
            <h3>${title}</h3>
            <button type="button" class="um-close" data-um-close aria-label="Fechar">×</button>
          </header>
          <form class="um-form" data-um-form>
            ${!isCreate ? `<p class="um-meta"><code>${esc(u.username)}</code></p>` : ''}
            ${isCreate ? `<p class="um-hint um-hint--block">Perfil sugerido: <strong>${esc(roleMeta(createDefaultRole).label)}</strong> — pode escolher qualquer perfil abaixo.</p>` : ''}
            ${isCreate || isClone ? `
            <label class="um-field">
              <span>E-mail (login)</span>
              <input type="email" name="email" required placeholder="nome@empresa.com" autocomplete="off"/>
            </label>
            <label class="um-field">
              <span>${isClone ? 'Nova senha (opcional)' : 'Senha inicial'}</span>
              <input type="password" name="password" ${isCreate ? 'required minlength="6"' : 'minlength="6"'} placeholder="${isClone ? 'Gera automaticamente se vazio' : 'Mín. 6 caracteres'}" autocomplete="new-password"/>
            </label>` : ''}
            <label class="um-field">
              <span>Nome completo</span>
              <input type="text" name="display_name" value="${esc(u.display_name || '')}" placeholder="Nome visível"/>
            </label>
            <label class="um-field">
              <span>Perfil · Grupo</span>
              <select name="role" data-um-role-select ${u.username === 'root' ? 'disabled' : ''}>
                ${roleSelectGrouped(defaultRole, u.username === 'root' || u.role === 'super_admin' || isCreate)}
              </select>
              <small class="um-hint">Grupo: <strong data-um-group-preview>${esc(groupForRole(defaultRole))}</strong></small>
            </label>
            ${!isCreate && !isClone ? `
            <label class="um-field">
              <span>Nova senha (opcional)</span>
              <input type="password" name="password" minlength="6" placeholder="Deixe vazio para manter" autocomplete="new-password"/>
            </label>
            <label class="um-toggle-row">
              <span>Conta activa</span>
              <label class="acs-toggle">
                <input type="checkbox" name="active" ${u.active ? 'checked' : ''} ${u.username === 'root' ? 'disabled' : ''}/>
                <span class="acs-toggle-slider"></span>
              </label>
            </label>` : `
            <label class="um-toggle-row">
              <span>Activar conta já</span>
              <label class="acs-toggle">
                <input type="checkbox" name="active" checked/>
                <span class="acs-toggle-slider"></span>
              </label>
            </label>`}
            ${msg ? `<p class="um-msg um-msg--err">${esc(msg)}</p>` : ''}
            <footer class="um-modal-foot">
              <button type="button" class="um-btn-ghost" data-um-close>Cancelar</button>
              <button type="submit" class="um-btn-primary" ${saving ? 'disabled' : ''}>
                ${saving ? 'A guardar…' : isCreate ? 'Criar utilizador' : isClone ? 'Copiar' : 'Guardar'}
              </button>
            </footer>
          </form>
        </article>
      </div>`;
  }

  function syncModalPortal() {
    let portal = document.getElementById(PORTAL_ID);
    if (!modalMode) {
      if (portal) portal.innerHTML = '';
      document.body.classList.remove('um-scroll-lock');
      return;
    }
    if (!portal) {
      portal = document.createElement('div');
      portal.id = PORTAL_ID;
      document.body.appendChild(portal);
    }
    portal.innerHTML = renderModalHtml();
    document.body.classList.toggle('um-scroll-lock', true);
    bindModalEvents(portal);
  }

  function renderTable(list) {
    if (!list.length) {
      return '<p class="um-empty">Nenhum utilizador nesta função. Use «Criar utilizador» para adicionar.</p>';
    }
    const rows = list.map((u) => {
      const rm = roleMeta(u.role);
      const isRoot = u.username === 'root';
      return `
        <tr class="um-row">
          <td>
            <strong>${esc(u.display_name || u.username)}</strong>
            <span class="um-sub">${esc(u.email || u.username)}</span>
          </td>
          <td><span class="um-role-badge">${esc(rm.code)}</span></td>
          <td>${u.active ? '<span class="um-status um-status--on">Activo</span>' : '<span class="um-status um-status--off">Off</span>'}</td>
          <td class="um-actions">
            <button type="button" class="um-act" data-um-edit="${esc(u.username)}">Editar</button>
            ${!isRoot ? `<button type="button" class="um-act" data-um-freeze="${esc(u.username)}">${u.active ? 'Congelar' : 'Activar'}</button>` : ''}
            <button type="button" class="um-act" data-um-clone="${esc(u.username)}">Copiar</button>
            ${!isRoot ? `<button type="button" class="um-act um-act--danger" data-um-delete="${esc(u.username)}">Eliminar</button>` : ''}
          </td>
        </tr>`;
    }).join('');

    return `
      <div class="um-table-wrap">
        <table class="um-table um-table--compact">
          <thead>
            <tr><th>Utilizador</th><th>Perfil</th><th>Estado</th><th>Acções</th></tr>
          </thead>
          <tbody>${rows}</tbody>
        </table>
      </div>`;
  }

  function renderContent(roleLock, roleMeta, embedded) {
    const list = filteredUsers(roleLock);
    const code = window.DeskAccessControlPanel?.ROLE_CODES?.[roleLock] || '';
    const active = list.filter((u) => u.active).length;

    return `
      <div class="um-panel${embedded ? ' um-panel--embedded' : ''}" data-um-root>
        <header class="um-head um-head--embedded">
          <div>
            <span class="acs-matrix-users-title">Utilizadores</span>
            ${embedded ? `
            <span class="acs-matrix-users-meta">
              <code class="acs-role-code-inline">${esc(code)}</code>
              ${esc(roleMeta?.label || roleLock || '')}
              <span class="acs-matrix-users-count">${list.length} utilizador${list.length === 1 ? '' : 'es'}</span>
            </span>` : ''}
          </div>
          <button type="button" class="um-btn-primary um-btn-primary--sm" data-um-create>+ Criar</button>
        </header>

        <div class="um-mini-stats">
          <span><strong>${list.length}</strong> filtrados</span>
          <span><strong>${active}</strong> activos</span>
          <span><strong>${users.length}</strong> total</span>
        </div>

        <div class="um-toolbar um-toolbar--compact">
          <input type="search" class="um-search" data-um-search placeholder="Pesquisar…" value="${esc(filterQ)}"/>
          <select data-um-filter-status>
            <option value="all" ${filterStatus === 'all' ? 'selected' : ''}>Todos</option>
            <option value="active" ${filterStatus === 'active' ? 'selected' : ''}>Activos</option>
            <option value="inactive" ${filterStatus === 'inactive' ? 'selected' : ''}>Congelados</option>
          </select>
          ${currentOpts?.onRegistration ? '<button type="button" class="um-btn-ghost um-btn-ghost--sm" data-um-reg>Pedidos cadastro</button>' : ''}
        </div>

        <div data-um-list>${renderTable(list)}</div>
      </div>`;
  }

  function refreshList() {
    if (!currentHost) return;
    const roleLock = currentOpts?.roleFilter || null;
    const listEl = currentHost.querySelector('[data-um-list]');
    if (listEl) listEl.innerHTML = renderTable(filteredUsers(roleLock));
    bindRowEvents(currentHost);
  }

  let editCallback = null;

  async function handleSubmit(form) {
    const roleLock = currentOpts?.roleFilter || null;
    const fd = new FormData(form);
    saving = true;
    msg = '';
    syncModalPortal();
    try {
      if (modalMode === 'create') {
        await apiUser('/users', {
          method: 'POST',
          body: JSON.stringify({
            email: fd.get('email'),
            password: fd.get('password'),
            role: fd.get('role'),
            display_name: fd.get('display_name') || null,
            active: !!form.querySelector('[name="active"]')?.checked,
          }),
        });
      } else if (modalMode === 'clone') {
        const res = await apiUser(`/users/${encodeURIComponent(modalUser.username)}/clone`, {
          method: 'POST',
          body: JSON.stringify({
            email: fd.get('email'),
            password: fd.get('password') || null,
            display_name: fd.get('display_name') || null,
            active: !!form.querySelector('[name="active"]')?.checked,
          }),
        });
        if (res.generated_password) {
          window.alert(`Copiado.\nSenha gerada: ${res.generated_password}`);
        }
      } else {
        const payload = {
          display_name: fd.get('display_name') || null,
          role: fd.get('role'),
          active: !!form.querySelector('[name="active"]')?.checked,
        };
        const pwd = fd.get('password');
        if (pwd && String(pwd).length >= 6) payload.password = pwd;
        await apiUser(`/users/${encodeURIComponent(modalUser.username)}`, {
          method: 'PATCH',
          body: JSON.stringify(payload),
        });
      }
      modalMode = null;
      modalUser = null;
      msg = '';
      syncModalPortal();
      await loadUsers();
      refreshList();
      if (editCallback) { const cb = editCallback; editCallback = null; cb(); }
    } catch (e) {
      msg = e.message;
      syncModalPortal();
    } finally {
      saving = false;
    }
  }

  function closeModal() {
    modalMode = null;
    modalUser = null;
    msg = '';
    saving = false;
    syncModalPortal();
  }

  function bindModalEvents(portal) {
    portal.querySelector('.um-backdrop')?.addEventListener('click', (e) => {
      if (e.target !== e.currentTarget) return;
      closeModal();
    });
    portal.querySelectorAll('[data-um-close]').forEach((el) => {
      el.addEventListener('click', (e) => { e.stopPropagation(); closeModal(); });
    });
    portal.querySelector('[data-um-card]')?.addEventListener('mousedown', (e) => e.stopPropagation());
    portal.querySelector('[data-um-form]')?.addEventListener('submit', async (e) => {
      e.preventDefault();
      await handleSubmit(e.target);
    });
    portal.querySelector('[data-um-role-select]')?.addEventListener('change', (e) => {
      const preview = portal.querySelector('[data-um-group-preview]');
      if (preview) preview.textContent = groupForRole(e.target.value);
    });
  }

  function bindRowEvents(host) {
    host.querySelectorAll('[data-um-edit]').forEach((btn) => {
      btn.addEventListener('click', (e) => {
        e.stopPropagation();
        modalUser = users.find((u) => u.username === btn.dataset.umEdit);
        modalMode = 'edit';
        msg = '';
        syncModalPortal();
      });
    });
    host.querySelectorAll('[data-um-clone]').forEach((btn) => {
      btn.addEventListener('click', (e) => {
        e.stopPropagation();
        modalUser = users.find((u) => u.username === btn.dataset.umClone);
        modalMode = 'clone';
        msg = '';
        syncModalPortal();
      });
    });
    host.querySelectorAll('[data-um-freeze]').forEach((btn) => {
      btn.addEventListener('click', async (e) => {
        e.stopPropagation();
        const u = users.find((x) => x.username === btn.dataset.umFreeze);
        if (!u) return;
        const label = u.active ? 'Congelar' : 'Activar';
        if (!window.confirm(`${label} ${u.username}?`)) return;
        try {
          await apiUser(`/users/${encodeURIComponent(u.username)}`, {
            method: 'PATCH',
            body: JSON.stringify({ active: !u.active }),
          });
          await loadUsers();
          refreshList();
        } catch (err) {
          window.alert(err.message);
        }
      });
    });
    host.querySelectorAll('[data-um-delete]').forEach((btn) => {
      btn.addEventListener('click', async (e) => {
        e.stopPropagation();
        const username = btn.dataset.umDelete;
        if (!window.confirm(`Eliminar ${username}? Irreversível.`)) return;
        try {
          await apiUser(`/users/${encodeURIComponent(username)}`, { method: 'DELETE' });
          await loadUsers();
          refreshList();
        } catch (err) {
          window.alert(err.message);
        }
      });
    });
  }

  function bindEvents(host) {
    host.querySelector('[data-um-create]')?.addEventListener('click', () => {
      modalMode = 'create';
      modalUser = null;
      msg = '';
      syncModalPortal();
    });

    host.querySelector('[data-um-reg]')?.addEventListener('click', () => {
      if (typeof currentOpts?.onRegistration === 'function') currentOpts.onRegistration();
    });

    host.querySelector('[data-um-search]')?.addEventListener('input', (e) => {
      filterQ = e.target.value;
      clearTimeout(host._umTimer);
      host._umTimer = setTimeout(refreshList, 250);
    });

    host.querySelector('[data-um-filter-status]')?.addEventListener('change', (e) => {
      filterStatus = e.target.value;
      refreshList();
    });

    bindRowEvents(host);
  }

  async function paint(host, opts = {}) {
    if (!host) return;
    currentHost = host;
    currentOpts = opts;
    createDefaultRole = opts.roleFilter || 'technician';

    if (typeof canManageUsers === 'function' && !canManageUsers()) {
      host.innerHTML = '<p class="loading">Sem permissão.</p>';
      return;
    }

    const firstLoad = !users.length;
    if (firstLoad) {
      host.innerHTML = '<p class="loading">Carregando utilizadores…</p>';
      try {
        await loadUsers();
      } catch (e) {
        host.innerHTML = `<p class="loading">Erro: ${esc(e.message)}</p>`;
        return;
      }
    }

    host.innerHTML = renderContent(opts.roleFilter, opts.roleMeta, opts.embedded);
    bindEvents(host);
    syncModalPortal();
  }

  function reset() {
    users = [];
    filterQ = '';
    filterStatus = 'all';
    modalMode = null;
    modalUser = null;
    msg = '';
    currentHost = null;
    currentOpts = null;
    closeModal();
  }

  function openEdit(username, onSaved) {
    loadUsers().then(() => {
      modalUser = users.find((u) => u.username === username);
      if (!modalUser) return;
      modalMode = 'edit';
      msg = '';
      editCallback = onSaved || null;
      syncModalPortal();
    }).catch((e) => window.alert(e.message));
  }

  window.DeskUserManagement = { paint, reset, loadUsers, openEdit, ROLE_META };
})();
