// ========== CREDENTIAL MANAGEMENT ==========
(function () {

  // Inject skeleton modal — credential sections are built dynamically when opened
  injectModal('token-management-modal', `
  <div id="token-management-modal" class="weather-modal">
    <div class="weather-modal-content" style="min-width: 500px; max-width: 600px;">
      <h3>\u{1F511} DNS Credentials</h3>

      <p style="font-size: 0.85rem; color: var(--muted); margin: 0 0 16px;">
        Enter Technitium DNS login credentials. Read-only accounts are used for logs; admin accounts for restarts, records, and updates.
      </p>

      <div id="dns-cred-sections"></div>

      <div class="weather-modal-buttons modal-footer-bar">
        <button id="token-clear-all" style="margin-right: auto; background: color-mix(in srgb, var(--bad-fg) 15%, transparent); border-color: var(--bad-fg); color: var(--bad-fg);">Clear All</button>
        <button id="token-cancel">Cancel</button>
        <button id="token-save" class="btn-accent">Save</button>
      </div>
    </div>
  </div>
  `);

  // ── Helpers ──

  function getDnsIds() {
    return Object.keys(SITE.dnsServers || {});
  }

  function getDnsDisplayName(dnsId) {
    const server = (SITE.dnsServers || {})[dnsId];
    return server?.name || dnsId.toUpperCase();
  }

  /** Build per-server credential form sections from SITE.dnsServers */
  function buildCredentialSections() {
    const container = document.getElementById('dns-cred-sections');
    if (!container) return;
    container.innerHTML = '';

    const dnsIds = getDnsIds();
    if (dnsIds.length === 0) {
      container.innerHTML = '<p style="color: var(--muted); text-align: center; padding: 20px;">No DNS servers configured.</p>';
      return;
    }

    for (const id of dnsIds) {
      container.insertAdjacentHTML('beforeend', `
      <div class="token-section">
        <h4 class="token-section-title">${getDnsDisplayName(id)}</h4>
        <div class="token-grid">
          <div class="token-field">
            <label for="${id}-readonly-username">\u{1F4D6} Read-Only (Logs):</label>
            <input type="text" id="${id}-readonly-username" placeholder="Username" autocomplete="off" style="margin-bottom: 4px;" />
            <div class="token-input-row">
              <input type="password" id="${id}-readonly-token" placeholder="Password" autocomplete="off" />
              <button type="button" class="token-toggle" data-target="${id}-readonly-token">\u{1F441}</button>
            </div>
          </div>
          <div class="token-field">
            <label for="${id}-admin-username">\u{1F527} Admin:</label>
            <input type="text" id="${id}-admin-username" placeholder="Username" autocomplete="off" style="margin-bottom: 4px;" />
            <div class="token-input-row">
              <input type="password" id="${id}-admin-token" placeholder="Password" autocomplete="off" />
              <button type="button" class="token-toggle" data-target="${id}-admin-token">\u{1F441}</button>
            </div>
          </div>
        </div>
        <div class="token-status" id="${id}-token-status"></div>
      </div>
      `);
    }
  }

  // ── Credential encryption ──

  function getEncryptionKey() {
    let key = safeSessionGet('dashcaddy-encryption-key');
    if (key) return key;

    const oldKey = safeGet('dashcaddy-encryption-key');
    if (oldKey) {
      safeSessionSet('dashcaddy-encryption-key', oldKey);
      safeRemove('dashcaddy-encryption-key');
      return oldKey;
    }

    const array = new Uint8Array(32);
    crypto.getRandomValues(array);
    key = Array.from(array, b => b.toString(16).padStart(2, '0')).join('');
    safeSessionSet('dashcaddy-encryption-key', key);
    return key;
  }
  const ENCRYPTION_KEY = getEncryptionKey();

  function credentialEncrypt(text, key) {
    if (!text) return '';
    const iv = crypto.getRandomValues(new Uint8Array(8));
    const ivHex = Array.from(iv, b => b.toString(16).padStart(2, '0')).join('');
    const keyBytes = new TextEncoder().encode(key + ivHex);
    let result = '';
    for (let i = 0; i < text.length; i++) {
      const charCode = text.charCodeAt(i)
        ^ keyBytes[i % keyBytes.length]
        ^ iv[i % iv.length]
        ^ ((i * 31 + 17) & 0xFF);
      result += String.fromCharCode(charCode);
    }
    return ivHex + ':' + btoa(result);
  }

  function credentialDecrypt(encryptedText, key) {
    if (!encryptedText) return '';
    try {
      const colonIdx = encryptedText.indexOf(':');
      if (colonIdx === 16) {
        const ivHex = encryptedText.substring(0, 16);
        const iv = new Uint8Array(ivHex.match(/.{2}/g).map(h => parseInt(h, 16)));
        const decoded = atob(encryptedText.substring(17));
        const keyBytes = new TextEncoder().encode(key + ivHex);
        let result = '';
        for (let i = 0; i < decoded.length; i++) {
          const charCode = decoded.charCodeAt(i)
            ^ keyBytes[i % keyBytes.length]
            ^ iv[i % iv.length]
            ^ ((i * 31 + 17) & 0xFF);
          result += String.fromCharCode(charCode);
        }
        return result;
      }
      const decoded = atob(encryptedText);
      let result = '';
      for (let i = 0; i < decoded.length; i++) {
        const charCode = decoded.charCodeAt(i) ^ key.charCodeAt(i % key.length);
        result += String.fromCharCode(charCode);
      }
      return result;
    } catch (e) {
      return '';
    }
  }

  // ── Credential storage ──

  function getCredential(dnsId, tokenType, credType) {
    const encrypted = safeGet(`${dnsId}-${tokenType}-${credType}-enc`);
    return credentialDecrypt(encrypted, ENCRYPTION_KEY);
  }

  function setCredential(dnsId, tokenType, credType, value) {
    const key = `${dnsId}-${tokenType}-${credType}-enc`;
    if (value) {
      safeSet(key, credentialEncrypt(value, ENCRYPTION_KEY));
    } else {
      safeRemove(key);
    }
  }

  function getToken(dnsId, tokenType) {
    return getCredential(dnsId, tokenType, 'token');
  }

  function getUsername(dnsId, tokenType) {
    return getCredential(dnsId, tokenType, 'username');
  }

  function setToken(dnsId, tokenType, token) {
    setCredential(dnsId, tokenType, 'token', token);
  }

  function setUsername(dnsId, tokenType, username) {
    setCredential(dnsId, tokenType, 'username', username);
  }

  function getAllCredentials() {
    const result = {};
    for (const dnsId of getDnsIds()) {
      result[dnsId] = {
        readonly: { username: getUsername(dnsId, 'readonly'), token: getToken(dnsId, 'readonly') },
        admin: { username: getUsername(dnsId, 'admin'), token: getToken(dnsId, 'admin') }
      };
    }
    return result;
  }

  function clearAllCredentials() {
    getDnsIds().forEach(dnsId => {
      ['readonly', 'admin'].forEach(tokenType => {
        ['token', 'username'].forEach(credType => {
          safeRemove(`${dnsId}-${tokenType}-${credType}-enc`);
        });
      });
      safeRemove(`${dnsId}-token-enc`);
      safeRemove(`${dnsId}-username-enc`);
    });
  }

  function getStoredCredentials(dnsId) {
    const readonlyToken = getToken(dnsId, 'readonly');
    const readonlyUsername = getUsername(dnsId, 'readonly');
    const adminToken = getToken(dnsId, 'admin');
    const adminUsername = getUsername(dnsId, 'admin');
    const oldToken = credentialDecrypt(safeGet(`${dnsId}-token-enc`), ENCRYPTION_KEY);
    const oldUsername = credentialDecrypt(safeGet(`${dnsId}-username-enc`), ENCRYPTION_KEY);

    return {
      username: adminUsername || readonlyUsername || oldUsername,
      token: adminToken || readonlyToken || oldToken,
      readonlyToken: readonlyToken || oldToken,
      readonlyUsername: readonlyUsername || oldUsername,
      adminToken: adminToken || oldToken,
      adminUsername: adminUsername || oldUsername
    };
  }

  // ── Modal handlers ──

  // Open modal — build sections dynamically, populate from stored creds
  document.getElementById('manage-tokens')?.addEventListener('click', () => {
    buildCredentialSections();
    const modal = document.getElementById('token-management-modal');
    const creds = getAllCredentials();

    getDnsIds().forEach(dnsId => {
      const c = creds[dnsId];
      document.getElementById(`${dnsId}-readonly-username`).value = c.readonly.username;
      document.getElementById(`${dnsId}-readonly-token`).value = c.readonly.token;
      document.getElementById(`${dnsId}-admin-username`).value = c.admin.username;
      document.getElementById(`${dnsId}-admin-token`).value = c.admin.token;
      document.getElementById(`${dnsId}-token-status`).textContent = '';
    });

    modal.classList.add('show');
  });

  // Toggle password visibility + backdrop close (event delegation for dynamic elements)
  document.getElementById('token-management-modal')?.addEventListener('click', (e) => {
    const btn = e.target.closest('.token-toggle');
    if (btn) {
      const targetId = btn.dataset.target;
      const input = document.getElementById(targetId);
      if (input.type === 'password') {
        input.type = 'text';
        btn.textContent = '\u{1F648}';
      } else {
        input.type = 'password';
        btn.textContent = '\u{1F441}';
      }
      return;
    }
    if (e.target.id === 'token-management-modal') {
      e.target.classList.remove('show');
    }
  });

  // Save credentials
  document.getElementById('token-save')?.addEventListener('click', async () => {
    const dnsIds = getDnsIds();

    // Save all to localStorage
    dnsIds.forEach(dnsId => {
      setUsername(dnsId, 'readonly', document.getElementById(`${dnsId}-readonly-username`).value.trim());
      setToken(dnsId, 'readonly', document.getElementById(`${dnsId}-readonly-token`).value.trim());
      setUsername(dnsId, 'admin', document.getElementById(`${dnsId}-admin-username`).value.trim());
      setToken(dnsId, 'admin', document.getElementById(`${dnsId}-admin-token`).value.trim());
    });

    // Build per-server credentials payload for backend sync
    const servers = {};
    let hasAnyCreds = false;

    dnsIds.forEach(dnsId => {
      const entry = {};
      const roUser = document.getElementById(`${dnsId}-readonly-username`).value.trim();
      const roPass = document.getElementById(`${dnsId}-readonly-token`).value.trim();
      const adminUser = document.getElementById(`${dnsId}-admin-username`).value.trim();
      const adminPass = document.getElementById(`${dnsId}-admin-token`).value.trim();

      if (roUser && roPass) {
        entry.readonly = { username: roUser, password: roPass };
        hasAnyCreds = true;
      }
      if (adminUser && adminPass) {
        entry.admin = { username: adminUser, password: adminPass };
        hasAnyCreds = true;
      }
      if (Object.keys(entry).length > 0) {
        servers[dnsId] = entry;
      }
    });

    if (hasAnyCreds) {
      dnsIds.forEach(dnsId => {
        if (servers[dnsId]) {
          document.getElementById(`${dnsId}-token-status`).textContent = 'Verifying...';
          document.getElementById(`${dnsId}-token-status`).className = 'token-status';
        }
      });

      try {
        const res = await secureFetch('/api/v1/dns/credentials', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ servers })
        });
        const data = await res.json();

        if (data.results) {
          dnsIds.forEach(dnsId => {
            const statusEl = document.getElementById(`${dnsId}-token-status`);
            if (!servers[dnsId]) { statusEl.textContent = ''; return; }
            const result = data.results[dnsId];
            if (result?.success) {
              statusEl.textContent = '\u2713 Verified & saved';
              statusEl.className = 'token-status success';
            } else if (result?.partial) {
              statusEl.textContent = '\u2713 ' + result.partial;
              statusEl.className = 'token-status success';
            } else {
              statusEl.textContent = '\u2717 ' + (result?.error || 'Login failed');
              statusEl.className = 'token-status error';
            }
          });
        } else if (data.success) {
          dnsIds.forEach(dnsId => {
            if (servers[dnsId]) {
              document.getElementById(`${dnsId}-token-status`).textContent = '\u2713 Saved';
              document.getElementById(`${dnsId}-token-status`).className = 'token-status success';
            }
          });
        } else {
          dnsIds.forEach(dnsId => {
            if (servers[dnsId]) {
              document.getElementById(`${dnsId}-token-status`).textContent = '\u2717 ' + (data.error || 'Failed');
              document.getElementById(`${dnsId}-token-status`).className = 'token-status error';
            }
          });
        }
      } catch (e) {
        console.error('Failed to sync DNS credentials to backend:', e);
        dnsIds.forEach(dnsId => {
          if (servers[dnsId]) {
            document.getElementById(`${dnsId}-token-status`).textContent = '\u2713 Saved locally (sync failed)';
            document.getElementById(`${dnsId}-token-status`).className = 'token-status';
          }
        });
      }
    } else {
      dnsIds.forEach(dnsId => {
        document.getElementById(`${dnsId}-token-status`).textContent = '';
      });
    }

    // Auto-close after delay if all succeeded
    setTimeout(() => {
      const allGood = dnsIds.every(dnsId => {
        const status = document.getElementById(`${dnsId}-token-status`)?.textContent;
        return !status || status.includes('\u2713');
      });
      if (allGood) closeModal('token-management-modal');
    }, 1500);
  });

  document.getElementById('token-cancel')?.addEventListener('click', () => {
    closeModal('token-management-modal');
  });

  document.getElementById('token-clear-all')?.addEventListener('click', async () => {
    if (confirm('Clear all stored DNS credentials? This cannot be undone.')) {
      clearAllCredentials();
      getDnsIds().forEach(dnsId => {
        document.getElementById(`${dnsId}-readonly-username`).value = '';
        document.getElementById(`${dnsId}-readonly-token`).value = '';
        document.getElementById(`${dnsId}-admin-username`).value = '';
        document.getElementById(`${dnsId}-admin-token`).value = '';
        document.getElementById(`${dnsId}-token-status`).textContent = '\u2713 Cleared';
        document.getElementById(`${dnsId}-token-status`).className = 'token-status success';
      });
      try {
        await secureFetch('/api/v1/dns/credentials', { method: 'DELETE' });
      } catch (_) {}
    }
  });

  // ── Window exports ──
  window.getToken = getToken;
  window.getUsername = getUsername;
  window.setToken = setToken;
  window.setUsername = setUsername;
  window.getAllCredentials = getAllCredentials;
  window.getCredential = getCredential;
  window.setCredential = setCredential;
  window.getEncryptionKey = getEncryptionKey;
  window.getDnsIds = getDnsIds;
  window.getDnsDisplayName = getDnsDisplayName;

})();
