'use strict';

(() => {
  const CONFIG = globalThis.ReinosAdminConfig || {
    enabled: true,
    logLimit: 250
  };
  const PERMISSIONS = globalThis.ReinosAdminPermissions;

  const RESOURCE_ALIASES = {
    madeira: 'wood', wood: 'wood',
    pedra: 'stone', stone: 'stone',
    comida: 'food', food: 'food',
    moedas: 'coins', moeda: 'coins', coins: 'coins',
    coroas: 'gems', coroa: 'gems', gems: 'gems'
  };

  const TROOP_ALIASES = {
    lanceiro: 'spearman', lanceiros: 'spearman', spearman: 'spearman',
    espadachim: 'swordsman', espadachins: 'swordsman', swordsman: 'swordsman',
    arqueiro: 'archer', arqueiros: 'archer', archer: 'archer',
    cavaleiro: 'knight', cavaleiros: 'knight', knight: 'knight'
  };

  const RESOURCE_LABELS = {
    wood: 'Madeira', stone: 'Pedra', food: 'Comida', coins: 'Moedas', gems: 'Coroas'
  };

  const TROOP_LABELS = {
    spearman: 'Lanceiros', swordsman: 'Espadachins', archer: 'Arqueiros', knight: 'Cavaleiros'
  };

  const WORLD_COORDINATES = globalThis.ReinosWorldCoordinates;
  const WORLD_COORD_MIN = WORLD_COORDINATES?.COORD_MIN ?? -1000;
  const WORLD_COORD_MAX = WORLD_COORDINATES?.COORD_MAX ?? 1000;
  const WORLD_COORD_CENTER = WORLD_COORDINATES?.COORD_CENTER ?? 0;

  function normalizeWorldCoordinate(value, fallback = WORLD_COORD_CENTER) {
    if (WORLD_COORDINATES?.normalizeCoordinate) return WORLD_COORDINATES.normalizeCoordinate(value, fallback);
    const number = Number(value);
    return Math.max(WORLD_COORD_MIN, Math.min(WORLD_COORD_MAX, Math.round(Number.isFinite(number) ? number : fallback)));
  }

  let context = null;
  let active = false;
  let selectedUserId = null;
  let selectedResourceKey = 'wood';
  let selectedTroopKey = 'spearman';
  let activeAdminTab = 'overview';
  let consoleMessage = 'Escreve /ajuda para consultar todos os comandos disponíveis.';
  let listenersReady = false;
  let mutationInFlight = false;

  function adminScrollTargets(content) {
    const targets = [];
    if (content) targets.push(['content', content]);
    const view = content?.querySelector?.('.admin-view');
    if (view) targets.push(['view', view]);
    const logs = content?.querySelector?.('.admin-logs');
    if (logs) targets.push(['logs', logs]);
    const output = content?.querySelector?.('.admin-console-output');
    if (output) targets.push(['console', output]);
    return targets;
  }

  function captureAdminScroll(content) {
    return adminScrollTargets(content).map(([name, element]) => ({
      name,
      top: element.scrollTop || 0,
      left: element.scrollLeft || 0
    }));
  }

  function restoreAdminScroll(content, state) {
    if (!state || !state.length) return;
    const apply = () => {
      const targets = Object.fromEntries(adminScrollTargets(content));
      state.forEach(item => {
        const element = targets[item.name];
        if (!element) return;
        element.scrollTop = item.top || 0;
        element.scrollLeft = item.left || 0;
      });
    };
    apply();
    requestAnimationFrame(apply);
    setTimeout(apply, 40);
  }

  function normalizeName(value) {
    return String(value || '').trim().toLocaleLowerCase('pt-PT');
  }

  function isAdminUser(user) {
    return Boolean(CONFIG.enabled && user && PERMISSIONS?.isAdmin?.(db(), user));
  }

  function isSuperAdmin(user) {
    return Boolean(CONFIG.enabled && user && PERMISSIONS?.isOwner?.(db(), user));
  }

  function db() { return context?.getDb?.(); }
  function currentUser() { return context?.getCurrentUser?.(); }
  function currentProfile() { return context?.getProfile?.(); }
  function esc(value) { return context?.escapeHtml ? context.escapeHtml(value) : String(value ?? ''); }
  function fmt(value) { return context?.format ? context.format(value) : String(Math.floor(Number(value) || 0)); }

  function resourceSummary(resources) {
    const icons = globalThis.ReinosResourceIcons;
    if (icons?.list) return icons.list(resources, ['wood', 'stone', 'food', 'coins', 'gems'], fmt);
    return `Madeira ${fmt(resources.wood)} · Pedra ${fmt(resources.stone)} · Comida ${fmt(resources.food)} · Moedas ${fmt(resources.coins)} · Coroas ${fmt(resources.gems)}`;
  }

  function ensureDbShape(database) {
    if (!database) return;
    if (!Array.isArray(database.users)) database.users = [];
    if (!database.profiles || typeof database.profiles !== 'object') database.profiles = {};
    if (!Array.isArray(database.adminLogs)) database.adminLogs = [];
    PERMISSIONS?.ensure?.(database);
  }

  function getUsers() {
    const database = db();
    ensureDbShape(database);
    return database?.users || [];
  }

  function userById(userId) {
    return getUsers().find(user => user.id === userId) || null;
  }

  function findUser(reference) {
    const users = getUsers();
    const normalized = normalizeName(reference);
    return users.find(user => user.id === reference)
      || users.find(user => normalizeName(user.username) === normalized)
      || users.find(user => normalizeName(user.username).includes(normalized))
      || null;
  }

  function profileFor(userId) {
    const database = db();
    ensureDbShape(database);
    return database?.profiles?.[userId] || null;
  }

  function selectedUser() {
    const users = getUsers();
    if (!selectedUserId || !users.some(user => user.id === selectedUserId)) {
      selectedUserId = currentUser()?.id || users[0]?.id || null;
    }
    return userById(selectedUserId);
  }

  function selectedProfile() {
    const user = selectedUser();
    return user ? profileFor(user.id) : null;
  }

  function safeInteger(value, fallback = 0) {
    const number = Number(value);
    return Number.isFinite(number) ? Math.trunc(number) : fallback;
  }

  function ensureProfileShape(targetProfile) {
    if (!targetProfile) return;
    targetProfile.resources = { wood: 0, stone: 0, food: 0, coins: 0, gems: 0, ...(targetProfile.resources || {}) };
    targetProfile.troops = { spearman: 0, swordsman: 0, archer: 0, knight: 0, ...(targetProfile.troops || {}) };
    globalThis.ReinosAdminSiegeTools?.ensure?.(targetProfile);
    globalThis.ReinosAdminEquipment?.ensure?.(targetProfile);
    if (!targetProfile.worldPosition) targetProfile.worldPosition = { x: WORLD_COORD_CENTER, y: WORLD_COORD_CENTER };
    if (!targetProfile.worldView) targetProfile.worldView = { ...targetProfile.worldPosition };
  }

  function writeLog(action, targetUser, details) {
    const database = db();
    ensureDbShape(database);
    database.adminLogs.unshift({
      id: `admin_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`,
      at: Date.now(),
      actor: currentUser()?.username || 'Administrador',
      target: targetUser?.username || 'Sistema',
      action,
      details: String(details || '')
    });
    database.adminLogs = database.adminLogs.slice(0, Math.max(20, Number(CONFIG.logLimit) || 250));
  }

  async function commit(message, targetUser, action, details) {
    writeLog(action, targetUser, details);
    consoleMessage = message;
    await context?.persist?.(true);
    context?.toast?.(message, 'success');
    if (active) renderPanel({ preserveScroll: true });
    else context?.renderGame?.();
  }

  function resourceOptions() {
    if (!RESOURCE_LABELS[selectedResourceKey]) selectedResourceKey = 'wood';
    return Object.entries(RESOURCE_LABELS)
      .map(([key, label]) => `<option value="${key}" ${key === selectedResourceKey ? 'selected' : ''}>${label}</option>`)
      .join('');
  }

  function troopOptions() {
    if (!TROOP_LABELS[selectedTroopKey]) selectedTroopKey = 'spearman';
    return Object.entries(TROOP_LABELS)
      .map(([key, label]) => `<option value="${key}" ${key === selectedTroopKey ? 'selected' : ''}>${label}</option>`)
      .join('');
  }

  function playerOptions() {
    return getUsers().map(user => {
      const role = isAdminUser(user) ? ' • Admin' : '';
      return `<option value="${esc(user.id)}" ${user.id === selectedUserId ? 'selected' : ''}>${esc(user.username)}${role}</option>`;
    }).join('');
  }

  function renderTargetSummary(user, targetProfile) {
    if (!user || !targetProfile) return '<p class="admin-note">Nenhum jogador selecionado.</p>';
    ensureProfileShape(targetProfile);
    const r = targetProfile.resources;
    const t = targetProfile.troops;
    return `
      <div class="admin-target-card">
        <div class="admin-stat"><small>Jogador</small><strong>${esc(user.username)}${isAdminUser(user) ? ' • Administrador' : ''}</strong></div>
        <div class="admin-stat"><small>Reino</small><strong>${esc(targetProfile.kingdomName || '-')}</strong></div>
        <div class="admin-stat"><small>Nível / XP</small><strong>${fmt(targetProfile.level)} / ${fmt(targetProfile.xp)}</strong></div>
        <div class="admin-stat"><small>Honra</small><strong>${fmt(targetProfile.honor)}</strong></div>
        <div class="admin-stat"><small>Recursos</small><strong>${resourceSummary(r)}</strong></div>
        <div class="admin-stat"><small>Tropas</small><strong>🔱 ${fmt(t.spearman)} · 🗡️ ${fmt(t.swordsman)} · 🏹 ${fmt(t.archer)} · 🐴 ${fmt(t.knight)}</strong></div>
        ${globalThis.ReinosAdminSiegeTools?.renderSummary?.({ profile: targetProfile, fmt }) || ''}
        ${globalThis.ReinosAdminEquipment?.renderSummary?.({ profile: targetProfile, fmt }) || ''}
        <div class="admin-stat"><small>Coordenadas</small><strong>X ${safeInteger(targetProfile.worldPosition.x)} · Y ${safeInteger(targetProfile.worldPosition.y)}</strong></div>
        <div class="admin-stat"><small>Conta criada</small><strong>${user.createdAt ? new Date(user.createdAt).toLocaleString('pt-PT') : '-'}</strong></div>
      </div>`;
  }

  function renderLogs() {
    const logs = db()?.adminLogs || [];
    if (!logs.length) return '<div class="empty-state">Ainda não existem ações administrativas.</div>';
    return logs.slice(0, 100).map(log => `
      <div class="admin-log">
        <span>${new Date(log.at).toLocaleString('pt-PT')}</span>
        <strong>${esc(log.actor)}</strong>
        <span>${esc(log.target)}</span>
        <span><b>${esc(log.action)}</b> — ${esc(log.details)}</span>
      </div>`).join('');
  }

  function adminTabButtons(superAdmin) {
    const tabs = [
      ['overview', '🏰', 'Resumo'],
      ['inventory', '📦', 'Recursos e exército'],
      ['progress', '📍', 'Progresso'],
      ...(superAdmin ? [['access', '🔐', 'Acessos']] : []),
      ['console', '⌨️', 'Consola'],
      ['logs', '🧾', 'Registo']
    ];
    if (!tabs.some(([key]) => key === activeAdminTab)) activeAdminTab = 'overview';
    return tabs.map(([key, icon, label]) => `
      <button type="button" class="admin-tab-btn ${activeAdminTab === key ? 'active' : ''}" data-admin-tab="${key}">
        <span class="admin-tab-icon">${icon}</span><span>${label}</span>
      </button>`).join('');
  }

  function renderAdminTab(user, targetProfile, superAdmin) {
    if (activeAdminTab === 'inventory') {
      return `
        <section class="admin-window admin-window-wide">
          <div class="admin-window-title">
            <div><span class="admin-window-icon">📦</span><div><h3>Recursos e exército</h3><p>Adiciona ou retira bens ao jogador selecionado.</p></div></div>
          </div>
          <div class="admin-window-body">
            <p class="admin-note admin-note-highlight">Usa valores positivos para adicionar e valores negativos para retirar. Os recursos administrativos não ficam limitados pela capacidade do armazém.</p>
            <div class="admin-control-groups">
              <div class="admin-control-card">
                <h4>🪵 Recursos</h4>
                <div class="admin-form-row">
                  <select id="admin-resource-type">${resourceOptions()}</select>
                  <input id="admin-resource-amount" type="number" value="1000" step="1" />
                  <button class="action-btn" data-admin-action="resource-apply">Aplicar</button>
                </div>
              </div>
              <div class="admin-control-card">
                <h4>⚔️ Tropas</h4>
                <div class="admin-form-row">
                  <select id="admin-troop-type">${troopOptions()}</select>
                  <input id="admin-troop-amount" type="number" value="100" step="1" />
                  <button class="action-btn" data-admin-action="troop-apply">Aplicar</button>
                </div>
              </div>
              <div class="admin-control-card">
                <h4>🛠️ Ferramentas de cerco</h4>
                ${globalThis.ReinosAdminSiegeTools?.renderControls?.({ profile: targetProfile, esc, fmt }) || '<p class="admin-note">Sistema de ferramentas indisponível.</p>'}
              </div>
              <div class="admin-control-card admin-control-card-full">
                <h4>🛡️ Equipamentos</h4>
                ${globalThis.ReinosAdminEquipment?.renderControls?.({ profile: targetProfile, esc, fmt }) || '<p class="admin-note">Sistema de equipamentos indisponível.</p>'}
              </div>
            </div>
            <div class="admin-danger-zone">
              <strong>Reposição rápida</strong>
              <span>Estas ações colocam os valores a zero.</span>
              <div class="admin-danger-row">
                <button class="danger-btn" data-admin-action="resources-reset">Zerar recursos</button>
                <button class="danger-btn" data-admin-action="troops-reset">Zerar tropas</button>
              </div>
            </div>
          </div>
        </section>`;
    }

    if (activeAdminTab === 'progress') {
      return `
        <section class="admin-window">
          <div class="admin-window-title">
            <div><span class="admin-window-icon">📍</span><div><h3>Progresso e localização</h3><p>Altera a evolução e a posição do jogador no mapa.</p></div></div>
          </div>
          <div class="admin-window-body">
            <div class="admin-setting-list">
              <div class="admin-setting-row">
                <div><strong>Nível</strong><small>Ao definir o nível, o XP atual volta a zero.</small></div>
                <div class="admin-setting-control"><input id="admin-level-value" type="number" min="1" value="${Math.max(1, safeInteger(targetProfile?.level, 1))}" /><button class="secondary-btn" data-admin-action="level-set">Definir</button></div>
              </div>
              <div class="admin-setting-row">
                <div><strong>Honra</strong><small>Define diretamente a honra total da conta.</small></div>
                <div class="admin-setting-control"><input id="admin-honor-value" type="number" min="0" value="${Math.max(0, safeInteger(targetProfile?.honor, 0))}" /><button class="secondary-btn" data-admin-action="honor-set">Definir</button></div>
              </div>
              <div class="admin-setting-row admin-setting-row-coords">
                <div><strong>Coordenadas</strong><small>Valores permitidos entre ${WORLD_COORD_MIN} e ${WORLD_COORD_MAX}.</small></div>
                <div class="admin-setting-control admin-setting-coords"><label>X<input id="admin-coordinate-x" type="number" min="${WORLD_COORD_MIN}" max="${WORLD_COORD_MAX}" value="${safeInteger(targetProfile?.worldPosition?.x, WORLD_COORD_CENTER)}" /></label><label>Y<input id="admin-coordinate-y" type="number" min="${WORLD_COORD_MIN}" max="${WORLD_COORD_MAX}" value="${safeInteger(targetProfile?.worldPosition?.y, WORLD_COORD_CENTER)}" /></label><button class="secondary-btn" data-admin-action="coordinates-set">Mover</button></div>
              </div>
            </div>
          </div>
        </section>`;
    }

    if (activeAdminTab === 'access' && superAdmin) {
      return `
        <section class="admin-window">
          <div class="admin-window-title">
            <div><span class="admin-window-icon">🔐</span><div><h3>Acessos administrativos</h3><p>Controla quem pode abrir e utilizar este painel.</p></div></div>
          </div>
          <div class="admin-window-body">
            <p class="admin-note admin-note-highlight">${esc(globalThis.ReinosOwnerPrivacy?.accessNote?.() || 'A gestão de acessos é reservada à conta principal.')}</p>
            <div class="admin-access-state ${user && isAdminUser(user) ? 'has-access' : 'no-access'}">
              <span>${user && isSuperAdmin(user) ? (globalThis.ReinosOwnerPrivacy?.permanentAccessLabel?.() || 'Esta conta tem acesso administrativo permanente.') : user && isAdminUser(user) ? 'Este jogador tem acesso à Administração.' : 'Este jogador não tem acesso à Administração.'}</span>
              ${user && !isSuperAdmin(user) ? `<button class="${isAdminUser(user) ? 'danger-btn' : 'action-btn'}" data-admin-action="admin-toggle">${isAdminUser(user) ? 'Retirar acesso' : 'Dar acesso'}</button>` : ''}
            </div>
          </div>
        </section>`;
    }

    if (activeAdminTab === 'console') {
      return `
        <section class="admin-window admin-window-wide">
          <div class="admin-window-title">
            <div><span class="admin-window-icon">⌨️</span><div><h3>Consola de comandos</h3><p>Executa comandos avançados sem abandonar o painel.</p></div></div>
          </div>
          <div class="admin-window-body">
            <div class="admin-console">
              <div class="admin-console-head">
                <input id="admin-command-input" class="admin-console-input" autocomplete="off" placeholder='/recursos "Nome do jogador" madeira 5000' />
                <button class="action-btn" data-admin-action="command-run">Executar</button>
              </div>
              <div class="admin-console-output">${esc(consoleMessage)}</div>
            </div>
            <details class="admin-command-help" open>
              <summary>Ver exemplos de comandos</summary>
              <div class="admin-help">
                <code>/recursos "Jogador" madeira 5000</code>
                <code>/tropas "Jogador" lanceiro 250</code>
                <code>/ferramentas "Jogador" escada 100</code>
                <code>/equipamentos "Jogador" comandante todos lendário 60 1</code>
                <code>/nivel "Jogador" 10</code>
                <code>/honra "Jogador" 3000</code>
                <code>/xp "Jogador" 1500</code>
                <code>/coordenadas "Jogador" -450 700</code>
                <code>/reset "Jogador" recursos</code>
                ${superAdmin ? '<code>/admin "Jogador" on</code>' : ''}
                <code>/info "Jogador"</code><code>/ajuda</code>
              </div>
            </details>
          </div>
        </section>`;
    }

    if (activeAdminTab === 'logs') {
      return `
        <section class="admin-window admin-window-wide">
          <div class="admin-window-title admin-window-title-actions">
            <div><span class="admin-window-icon">🧾</span><div><h3>Registo de ações</h3><p>Consulta as alterações realizadas pelos administradores.</p></div></div>
            <button class="secondary-btn" data-admin-action="logs-clear">Limpar registo</button>
          </div>
          <div class="admin-window-body admin-window-body-flush">
            <div class="admin-log-header"><span>Data</span><span>Administrador</span><span>Jogador</span><span>Ação</span></div>
            <div class="admin-logs">${renderLogs()}</div>
          </div>
        </section>`;
    }

    return `
      <section class="admin-window admin-window-wide">
        <div class="admin-window-title">
          <div><span class="admin-window-icon">🏰</span><div><h3>Resumo do jogador</h3><p>Visão rápida da conta atualmente selecionada.</p></div></div>
        </div>
        <div class="admin-window-body">
          ${renderTargetSummary(user, targetProfile)}
          <div class="admin-overview-actions">
            <button class="admin-shortcut" data-admin-tab="inventory"><span>📦</span><strong>Recursos e exército</strong><small>Dar recursos, tropas, ferramentas e equipamentos</small></button>
            <button class="admin-shortcut" data-admin-tab="progress"><span>📍</span><strong>Progresso</strong><small>Alterar nível, honra e coordenadas</small></button>
            ${superAdmin ? '<button class="admin-shortcut" data-admin-tab="access"><span>🔐</span><strong>Acessos</strong><small>Dar ou retirar permissões administrativas</small></button>' : ''}
            <button class="admin-shortcut" data-admin-tab="console"><span>⌨️</span><strong>Consola</strong><small>Executar comandos administrativos avançados</small></button>
          </div>
        </div>
      </section>`;
  }

  function renderPanel(options = {}) {
    if (!context || !isAdminUser(currentUser())) return;
    const content = document.querySelector('#content');
    if (!content) return;
    const scrollState = options.preserveScroll === false ? null : captureAdminScroll(content);
    const user = selectedUser();
    const targetProfile = selectedProfile();
    const superAdmin = isSuperAdmin(currentUser());

    document.querySelectorAll('.nav-btn').forEach(button => button.classList.remove('active'));
    document.querySelector('.admin-nav-btn')?.classList.add('active');

    content.innerHTML = `
      <div class="view admin-view">
        <div class="view-title admin-main-title">
          <div><h2>Painel de Administração</h2><p>Gestão organizada por janelas para encontrares cada função rapidamente.</p></div>
          <div class="admin-badge">🛡️ ADMINISTRADOR</div>
        </div>

        <section class="admin-player-bar">
          <div class="admin-player-bar-label"><span>👤</span><div><small>Jogador selecionado</small><strong>${esc(user?.username || 'Nenhum jogador')}</strong></div></div>
          <select id="admin-player-select" class="admin-player-select">${playerOptions()}</select>
          <div class="admin-player-mini-stats">
            <span><small>Nível</small><strong>${fmt(targetProfile?.level || 0)}</strong></span>
            <span><small>Honra</small><strong>${fmt(targetProfile?.honor || 0)}</strong></span>
            <span><small>Posição</small><strong>X ${safeInteger(targetProfile?.worldPosition?.x, WORLD_COORD_CENTER)} · Y ${safeInteger(targetProfile?.worldPosition?.y, WORLD_COORD_CENTER)}</strong></span>
          </div>
        </section>

        <nav class="admin-tabs" aria-label="Janelas de administração">
          ${adminTabButtons(superAdmin)}
        </nav>

        <div class="admin-tab-content" data-active-tab="${activeAdminTab}">
          ${renderAdminTab(user, targetProfile, superAdmin)}
        </div>
      </div>`;
    restoreAdminScroll(content, scrollState);
  }

  function tokenize(command) {
    const tokens = [];
    const regex = /"([^"]*)"|'([^']*)'|(\S+)/g;
    let match;
    while ((match = regex.exec(String(command || '').trim()))) tokens.push(match[1] ?? match[2] ?? match[3]);
    return tokens;
  }

  function commandHelp() {
    return [
      'COMANDOS ADMINISTRATIVOS',
      '/recursos "Jogador" <madeira|pedra|comida|moedas|coroas|todos> <quantidade>',
      '/tropas "Jogador" <lanceiro|espadachim|arqueiro|cavaleiro|todos> <quantidade>',
      ...(globalThis.ReinosAdminSiegeTools?.helpLines?.() || []),
      ...(globalThis.ReinosAdminEquipment?.helpLines?.() || []),
      '/nivel "Jogador" <nível>',
      '/honra "Jogador" <quantidade>',
      '/xp "Jogador" <quantidade>',
      '/coordenadas "Jogador" <X> <Y>',
      '/reset "Jogador" <recursos|tropas>',
      '/info "Jogador"',
      ...(isSuperAdmin(currentUser()) ? ['/admin "Jogador" <on|off>'] : [])
    ].join('\n');
  }

  async function runCommand(rawCommand) {
    const tokens = tokenize(rawCommand);
    if (!tokens.length) throw new Error('Escreve um comando. Usa /ajuda para consultar os comandos.');
    const command = tokens.shift().replace(/^\//, '').toLocaleLowerCase('pt-PT');
    if (command === 'ajuda' || command === 'help') {
      consoleMessage = commandHelp();
      renderPanel();
      return;
    }

    const playerReference = tokens.shift();
    if (!playerReference) throw new Error('Indica o nome do jogador entre aspas.');
    const targetUser = findUser(playerReference);
    if (!targetUser) throw new Error(`Jogador não encontrado: ${playerReference}`);
    const targetProfile = profileFor(targetUser.id);
    if (!targetProfile) throw new Error('O jogador selecionado não possui perfil.');
    ensureProfileShape(targetProfile);

    if (command === 'recursos' || command === 'resource' || command === 'resources') {
      const requested = normalizeName(tokens.shift());
      const amount = safeInteger(tokens.shift(), NaN);
      if (!Number.isFinite(amount)) throw new Error('Indica uma quantidade válida.');
      const keys = requested === 'todos' ? Object.keys(RESOURCE_LABELS) : [RESOURCE_ALIASES[requested]];
      if (!keys[0]) throw new Error('Recurso inválido. Usa madeira, pedra, comida, moedas, coroas ou todos.');
      const resources = {};
      keys.forEach(key => { resources[key] = amount; });
      if (context?.adminGrantInventory) {
        await context.adminGrantInventory(targetUser.id, { resources });
        consoleMessage = `${amount >= 0 ? 'Adicionados' : 'Retirados'} ${fmt(Math.abs(amount))} a ${requested} de ${targetUser.username}.`;
        context?.toast?.(consoleMessage, 'success');
        renderPanel({ preserveScroll: true });
      } else if (context?.adminGrantResources) {
        await context.adminGrantResources(targetUser.id, resources);
        consoleMessage = `${amount >= 0 ? 'Adicionados' : 'Retirados'} ${fmt(Math.abs(amount))} a ${requested} de ${targetUser.username}.`;
        context?.toast?.(consoleMessage, 'success');
        renderPanel({ preserveScroll: true });
      } else {
        keys.forEach(key => { targetProfile.resources[key] = Math.max(0, safeInteger(targetProfile.resources[key]) + amount); });
        await commit(`${amount >= 0 ? 'Adicionados' : 'Retirados'} ${fmt(Math.abs(amount))} a ${requested} de ${targetUser.username}.`, targetUser, 'RECURSOS', `${requested}: ${amount >= 0 ? '+' : ''}${amount}`);
      }
      return;
    }

    if (command === 'tropas' || command === 'troops') {
      const requested = normalizeName(tokens.shift());
      const amount = safeInteger(tokens.shift(), NaN);
      if (!Number.isFinite(amount)) throw new Error('Indica uma quantidade válida.');
      const keys = requested === 'todos' ? Object.keys(TROOP_LABELS) : [TROOP_ALIASES[requested]];
      if (!keys[0]) throw new Error('Tropa inválida. Usa lanceiro, espadachim, arqueiro, cavaleiro ou todos.');
      const troops = {};
      keys.forEach(key => { troops[key] = amount; });
      if (context?.adminGrantInventory) {
        await context.adminGrantInventory(targetUser.id, { troops });
        consoleMessage = `${amount >= 0 ? 'Adicionadas' : 'Retiradas'} ${fmt(Math.abs(amount))} unidades (${requested}) a ${targetUser.username}.`;
        context?.toast?.(consoleMessage, 'success');
        renderPanel({ preserveScroll: true });
      } else {
        keys.forEach(key => { targetProfile.troops[key] = Math.max(0, safeInteger(targetProfile.troops[key]) + amount); });
        await commit(`${amount >= 0 ? 'Adicionadas' : 'Retiradas'} ${fmt(Math.abs(amount))} unidades (${requested}) a ${targetUser.username}.`, targetUser, 'TROPAS', `${requested}: ${amount >= 0 ? '+' : ''}${amount}`);
      }
      return;
    }

    if (await globalThis.ReinosAdminSiegeTools?.handleCommand?.({
      command,
      tokens,
      targetUser,
      targetProfile,
      normalizeName,
      safeInteger,
      fmt,
      commit,
      adminGrantInventory: context?.adminGrantInventory
    })) return;

    if (await globalThis.ReinosAdminEquipment?.handleCommand?.({
      command,
      tokens,
      targetUser,
      targetProfile,
      normalizeName,
      safeInteger,
      fmt,
      commit
    })) return;

    if (command === 'nivel' || command === 'level') {
      const value = Math.max(1, safeInteger(tokens.shift(), NaN));
      if (!Number.isFinite(value)) throw new Error('Indica um nível válido.');
      targetProfile.level = value;
      targetProfile.xp = 0;
      targetProfile.xpToNext = Math.max(300, Math.round(300 * Math.pow(1.45, value - 1)));
      await commit(`Nível de ${targetUser.username} definido para ${value}.`, targetUser, 'NÍVEL', `Definido para ${value}`);
      return;
    }

    if (command === 'honra' || command === 'honor') {
      const value = Math.max(0, safeInteger(tokens.shift(), NaN));
      if (!Number.isFinite(value)) throw new Error('Indica um valor de honra válido.');
      targetProfile.honor = value;
      await commit(`Honra de ${targetUser.username} definida para ${fmt(value)}.`, targetUser, 'HONRA', `Definida para ${value}`);
      return;
    }

    if (command === 'xp') {
      const value = Math.max(0, safeInteger(tokens.shift(), NaN));
      if (!Number.isFinite(value)) throw new Error('Indica um valor de XP válido.');
      targetProfile.xp = value;
      await commit(`XP de ${targetUser.username} definido para ${fmt(value)}.`, targetUser, 'XP', `Definido para ${value}`);
      return;
    }

    if (command === 'coordenadas' || command === 'coords' || command === 'coordinates') {
      const rawX = safeInteger(tokens.shift(), NaN);
      const rawY = safeInteger(tokens.shift(), NaN);
      if (!Number.isFinite(rawX) || !Number.isFinite(rawY) || rawX < WORLD_COORD_MIN || rawX > WORLD_COORD_MAX || rawY < WORLD_COORD_MIN || rawY > WORLD_COORD_MAX) throw new Error(`Indica coordenadas X e Y válidas entre ${WORLD_COORD_MIN} e ${WORLD_COORD_MAX}.`);
      const x = normalizeWorldCoordinate(rawX);
      const y = normalizeWorldCoordinate(rawY);
      targetProfile.worldPosition = { x, y };
      targetProfile.worldView = { x, y };
      await commit(`${targetUser.username} foi movido para X ${x}, Y ${y}.`, targetUser, 'COORDENADAS', `X ${x}, Y ${y}`);
      return;
    }

    if (command === 'reset') {
      const type = normalizeName(tokens.shift());
      if (type === 'recursos') {
        Object.keys(RESOURCE_LABELS).forEach(key => { targetProfile.resources[key] = 0; });
        await commit(`Recursos de ${targetUser.username} foram zerados.`, targetUser, 'RESET', 'Recursos zerados');
        return;
      }
      if (type === 'tropas') {
        Object.keys(TROOP_LABELS).forEach(key => { targetProfile.troops[key] = 0; });
        await commit(`Tropas de ${targetUser.username} foram zeradas.`, targetUser, 'RESET', 'Tropas zeradas');
        return;
      }
      if (type === 'ferramentas') {
        await globalThis.ReinosAdminSiegeTools?.resetTools?.({ targetUser, targetProfile, commit });
        return;
      }
      if (type === 'equipamentos') {
        await globalThis.ReinosAdminEquipment?.resetEquipment?.({ targetUser, targetProfile, commit });
        return;
      }
      throw new Error('Usa /reset "Jogador" recursos, /reset "Jogador" tropas, /reset "Jogador" ferramentas ou /reset "Jogador" equipamentos.');
    }

    if (command === 'admin') {
      if (!isSuperAdmin(currentUser())) throw new Error('Apenas a conta principal pode alterar permissões.');
      const mode = normalizeName(tokens.shift());
      if (!['on', 'off'].includes(mode)) throw new Error('Usa on para ativar ou off para remover.');
      if (context?.adminSetAccess) {
        const enabled = mode === 'on';
        const result = await context.adminSetAccess(targetUser.id, enabled);
        consoleMessage = `Acesso administrativo de ${targetUser.username}: ${enabled ? 'ativado' : 'removido'}.`;
        context?.toast?.(consoleMessage, 'success');
        if (result?.data) renderPanel();
      } else {
        PERMISSIONS.setAdmin(db(), currentUser(), targetUser.id, mode === 'on');
        await commit(`Acesso administrativo de ${targetUser.username}: ${mode === 'on' ? 'ativado' : 'removido'}.`, targetUser, 'PERMISSÃO ADMIN', mode.toUpperCase());
      }
      return;
    }

    if (command === 'info') {
      consoleMessage = [
        `Jogador: ${targetUser.username}`,
        `Reino: ${targetProfile.kingdomName}`,
        `Nível: ${targetProfile.level} | XP: ${targetProfile.xp} | Honra: ${targetProfile.honor}`,
        `Coordenadas: X ${targetProfile.worldPosition.x}, Y ${targetProfile.worldPosition.y}`,
        `Recursos: madeira ${targetProfile.resources.wood}, pedra ${targetProfile.resources.stone}, comida ${targetProfile.resources.food}, moedas ${targetProfile.resources.coins}, coroas ${targetProfile.resources.gems}`,
        `Tropas: lanceiros ${targetProfile.troops.spearman}, espadachins ${targetProfile.troops.swordsman}, arqueiros ${targetProfile.troops.archer}, cavaleiros ${targetProfile.troops.knight}`,
        globalThis.ReinosAdminSiegeTools?.infoLine?.(targetProfile),
        globalThis.ReinosAdminEquipment?.infoLine?.(targetProfile),
        `Administrador: ${isAdminUser(targetUser) ? 'sim' : 'não'}`
      ].join('\n');
      selectedUserId = targetUser.id;
      renderPanel();
      return;
    }

    throw new Error(`Comando desconhecido: /${command}. Usa /ajuda.`);
  }

  async function selectedMutation(action) {
    const user = selectedUser();
    const targetProfile = selectedProfile();
    if (!user || !targetProfile) throw new Error('Seleciona um jogador válido.');
    ensureProfileShape(targetProfile);

    if (action === 'resource-apply') {
      const key = document.querySelector('#admin-resource-type')?.value || selectedResourceKey;
      selectedResourceKey = RESOURCE_LABELS[key] ? key : 'wood';
      const amount = safeInteger(document.querySelector('#admin-resource-amount')?.value, NaN);
      if (!RESOURCE_LABELS[key] || !Number.isFinite(amount)) throw new Error('Recurso ou quantidade inválida.');
      if (context?.adminGrantInventory) {
        await context.adminGrantInventory(user.id, { resources: { [key]: amount } });
        consoleMessage = `${RESOURCE_LABELS[key]} de ${user.username}: ${amount >= 0 ? '+' : ''}${fmt(amount)}.`;
        context?.toast?.(consoleMessage, 'success');
        renderPanel({ preserveScroll: true });
      } else if (context?.adminGrantResources) {
        await context.adminGrantResources(user.id, { [key]: amount });
        consoleMessage = `${RESOURCE_LABELS[key]} de ${user.username}: ${amount >= 0 ? '+' : ''}${fmt(amount)}.`;
        context?.toast?.(consoleMessage, 'success');
        renderPanel({ preserveScroll: true });
      } else {
        targetProfile.resources[key] = Math.max(0, safeInteger(targetProfile.resources[key]) + amount);
        await commit(`${RESOURCE_LABELS[key]} de ${user.username}: ${amount >= 0 ? '+' : ''}${fmt(amount)}.`, user, 'RECURSOS', `${RESOURCE_LABELS[key]} ${amount >= 0 ? '+' : ''}${amount}`);
      }
      return;
    }

    if (action === 'troop-apply') {
      const key = document.querySelector('#admin-troop-type')?.value || selectedTroopKey;
      selectedTroopKey = TROOP_LABELS[key] ? key : 'spearman';
      const amount = safeInteger(document.querySelector('#admin-troop-amount')?.value, NaN);
      if (!TROOP_LABELS[key] || !Number.isFinite(amount)) throw new Error('Tropa ou quantidade inválida.');
      if (context?.adminGrantInventory) {
        await context.adminGrantInventory(user.id, { troops: { [key]: amount } });
        consoleMessage = `${TROOP_LABELS[key]} de ${user.username}: ${amount >= 0 ? '+' : ''}${fmt(amount)}.`;
        context?.toast?.(consoleMessage, 'success');
        renderPanel({ preserveScroll: true });
      } else {
        targetProfile.troops[key] = Math.max(0, safeInteger(targetProfile.troops[key]) + amount);
        await commit(`${TROOP_LABELS[key]} de ${user.username}: ${amount >= 0 ? '+' : ''}${fmt(amount)}.`, user, 'TROPAS', `${TROOP_LABELS[key]} ${amount >= 0 ? '+' : ''}${amount}`);
      }
      return;
    }

    if (await globalThis.ReinosAdminSiegeTools?.handleAction?.({
      action,
      user,
      targetProfile,
      safeInteger,
      fmt,
      commit,
      adminGrantInventory: context?.adminGrantInventory
    })) return;

    if (await globalThis.ReinosAdminEquipment?.handleAction?.({
      action,
      user,
      targetProfile,
      safeInteger,
      fmt,
      commit
    })) return;

    if (action === 'level-set') {
      const value = Math.max(1, safeInteger(document.querySelector('#admin-level-value')?.value, NaN));
      if (!Number.isFinite(value)) throw new Error('Nível inválido.');
      targetProfile.level = value;
      targetProfile.xp = 0;
      targetProfile.xpToNext = Math.max(300, Math.round(300 * Math.pow(1.45, value - 1)));
      await commit(`Nível de ${user.username} definido para ${value}.`, user, 'NÍVEL', `Definido para ${value}`);
      return;
    }

    if (action === 'honor-set') {
      const value = Math.max(0, safeInteger(document.querySelector('#admin-honor-value')?.value, NaN));
      if (!Number.isFinite(value)) throw new Error('Honra inválida.');
      targetProfile.honor = value;
      await commit(`Honra de ${user.username} definida para ${fmt(value)}.`, user, 'HONRA', `Definida para ${value}`);
      return;
    }

    if (action === 'coordinates-set') {
      const rawX = safeInteger(document.querySelector('#admin-coordinate-x')?.value, NaN);
      const rawY = safeInteger(document.querySelector('#admin-coordinate-y')?.value, NaN);
      if (!Number.isFinite(rawX) || !Number.isFinite(rawY) || rawX < WORLD_COORD_MIN || rawX > WORLD_COORD_MAX || rawY < WORLD_COORD_MIN || rawY > WORLD_COORD_MAX) throw new Error(`As coordenadas devem estar entre ${WORLD_COORD_MIN} e ${WORLD_COORD_MAX}.`);
      const x = normalizeWorldCoordinate(rawX);
      const y = normalizeWorldCoordinate(rawY);
      targetProfile.worldPosition = { x, y };
      targetProfile.worldView = { x, y };
      await commit(`${user.username} foi movido para X ${x}, Y ${y}.`, user, 'COORDENADAS', `X ${x}, Y ${y}`);
      return;
    }

    if (action === 'resources-reset') {
      Object.keys(RESOURCE_LABELS).forEach(key => { targetProfile.resources[key] = 0; });
      await commit(`Recursos de ${user.username} foram zerados.`, user, 'RESET', 'Recursos zerados');
      return;
    }

    if (action === 'troops-reset') {
      Object.keys(TROOP_LABELS).forEach(key => { targetProfile.troops[key] = 0; });
      await commit(`Tropas de ${user.username} foram zeradas.`, user, 'RESET', 'Tropas zeradas');
      return;
    }

    if (action === 'admin-toggle') {
      if (!isSuperAdmin(currentUser())) throw new Error('Apenas a conta principal pode alterar permissões.');
      const enabled = !isAdminUser(user);
      if (context?.adminSetAccess) {
        const result = await context.adminSetAccess(user.id, enabled);
        consoleMessage = `Acesso administrativo de ${user.username}: ${enabled ? 'ativado' : 'removido'}.`;
        context?.toast?.(consoleMessage, 'success');
        if (result?.data) renderPanel({ preserveScroll: true });
        else await commit(consoleMessage, user, 'PERMISSÃO ADMIN', enabled ? 'ON' : 'OFF');
      } else {
        PERMISSIONS.setAdmin(db(), currentUser(), user.id, enabled);
        await commit(`Acesso administrativo de ${user.username}: ${enabled ? 'ativado' : 'removido'}.`, user, 'PERMISSÃO ADMIN', enabled ? 'ON' : 'OFF');
      }
    }
  }

  async function handleAdminAction(action) {
    if (!isAdminUser(currentUser())) return;
    if (mutationInFlight && action !== 'open') return;
    mutationInFlight = action !== 'open';
    try {
      if (action === 'open') {
        active = true;
        selectedUser();
        renderPanel({ preserveScroll: false });
        return;
      }
      if (action === 'command-run') {
        const input = document.querySelector('#admin-command-input');
        await runCommand(input?.value || '');
        return;
      }
      if (action === 'logs-clear') {
        const database = db();
        database.adminLogs = [];
        consoleMessage = 'Registo administrativo limpo.';
        await context.persist(true);
        renderPanel();
        return;
      }
      await selectedMutation(action);
    } catch (error) {
      consoleMessage = `ERRO: ${error.message}`;
      context?.toast?.(error.message, 'error');
      renderPanel();
    } finally {
      mutationInFlight = false;
    }
  }

  function installListeners() {
    if (listenersReady) return;
    listenersReady = true;

    document.addEventListener('click', event => {
      const tabElement = event.target.closest('[data-admin-tab]');
      if (tabElement && isAdminUser(currentUser())) {
        event.preventDefault();
        event.stopPropagation();
        activeAdminTab = tabElement.dataset.adminTab || 'overview';
        renderPanel({ preserveScroll: false });
        return;
      }
      const adminElement = event.target.closest('[data-admin-action]');
      if (adminElement) {
        event.preventDefault();
        event.stopPropagation();
        handleAdminAction(adminElement.dataset.adminAction);
        return;
      }
      if (event.target.closest('[data-action="nav"]')) active = false;
    }, true);

    document.addEventListener('change', event => {
      if (event.target.id === 'admin-player-select') {
        selectedUserId = event.target.value;
        renderPanel();
        return;
      }
      if (event.target.id === 'admin-resource-type') {
        const next = event.target.value;
        if (RESOURCE_LABELS[next]) selectedResourceKey = next;
        return;
      }
      if (event.target.id === 'admin-troop-type') {
        const next = event.target.value;
        if (TROOP_LABELS[next]) selectedTroopKey = next;
      }
    });

    document.addEventListener('keydown', event => {
      if (event.ctrlKey && event.shiftKey && event.key.toLocaleLowerCase('pt-PT') === 'a' && isAdminUser(currentUser())) {
        event.preventDefault();
        active = true;
        renderPanel();
        return;
      }
      if (active && event.key === 'Enter' && event.target.id === 'admin-command-input') {
        event.preventDefault();
        handleAdminAction('command-run');
      }
    });
  }

  function afterRender(gameContext) {
    context = gameContext;
    installListeners();
    const user = currentUser();
    if (!isAdminUser(user)) {
      active = false;
      return;
    }

    const nav = document.querySelector('.sidebar nav');
    if (nav && !nav.querySelector('.admin-nav-btn')) {
      nav.insertAdjacentHTML('beforeend', `
        <button class="nav-btn admin-nav-btn ${active ? 'active' : ''}" data-admin-action="open">
          <span class="nav-icon">🛡️</span><span>Administração</span>
        </button>`);
    }

    // A função administrativa continua interna, mas não é apresentada no painel do jogador.

    if (active) {
      const content = document.querySelector('#content');
      if (!content?.querySelector('.admin-view')) renderPanel({ preserveScroll: false });
      else {
        document.querySelectorAll('.nav-btn').forEach(button => button.classList.remove('active'));
        document.querySelector('.admin-nav-btn')?.classList.add('active');
      }
    }
  }

  globalThis.ReinosAdmin = Object.freeze({
    afterRender,
    isAdminUser,
    isPanelOpen: () => Boolean(active && isAdminUser(currentUser()))
  });
})();
