const flash = document.getElementById('flash');

function showFlash(message, ok) {
  flash.hidden = false;
  flash.className = 'flash ' + (ok ? 'ok' : 'error');
  flash.textContent = message;
}

function fillForm(s) {
  document.getElementById('organizationName').value = s.organizationName || '';
  document.getElementById('uiRefreshSeconds').value = s.uiRefreshSeconds ?? 30;
  document.getElementById('enrollmentToken').value = s.enrollmentToken || '';
  document.getElementById('outageTimeoutSeconds').value = s.outageTimeoutSeconds ?? 180;
  document.getElementById('adminUsername').value = s.adminUsername || 'admin';
  document.getElementById('requireHttpsCookies').checked = !!s.requireHttpsCookies;
  document.getElementById('newPassword').value = '';
  if (s.organizationName)
    document.getElementById('orgName').textContent = s.organizationName;
}

async function loadSettings() {
  const res = await api('/api/settings');
  if (!res.ok) throw new Error('Einstellungen konnten nicht geladen werden.');
  const payload = await res.json();
  fillForm(payload.settings || payload);
  if (payload.license) renderLicenseBanner(payload.license);
}

document.getElementById('settingsForm').addEventListener('submit', async (e) => {
  e.preventDefault();
  const body = {
    organizationName: document.getElementById('organizationName').value.trim(),
    uiRefreshSeconds: Number(document.getElementById('uiRefreshSeconds').value),
    enrollmentToken: document.getElementById('enrollmentToken').value.trim(),
    outageTimeoutSeconds: Number(document.getElementById('outageTimeoutSeconds').value),
    adminUsername: document.getElementById('adminUsername').value.trim(),
    requireHttpsCookies: document.getElementById('requireHttpsCookies').checked,
    newPassword: document.getElementById('newPassword').value || null
  };

  const res = await api('/api/settings', {
    method: 'PUT',
    body: JSON.stringify(body)
  });

  const data = await res.json().catch(() => ({}));
  if (!res.ok) {
    showFlash(data.error || 'Speichern fehlgeschlagen.', false);
    return;
  }

  fillForm(data);
  showFlash('Einstellungen gespeichert.', true);
});

document.getElementById('btnRotateToken').addEventListener('click', async () => {
  const ok = await confirmDialog({
    title: 'Enrollment-Token erneuern',
    message: 'Neuen Enrollment-Token erzeugen?\nBestehende Agents müssen den neuen Token erhalten.',
    confirmLabel: 'Token erzeugen',
    danger: true
  });
  if (!ok) return;

  const res = await api('/api/settings/rotate-enrollment-token', { method: 'POST' });
  const data = await res.json().catch(() => ({}));
  if (!res.ok) {
    showFlash(data.error || 'Token-Rotation fehlgeschlagen.', false);
    return;
  }

  fillForm(data);
  showFlash('Neuer Enrollment-Token erzeugt. Agents aktualisieren.', true);
});

document.getElementById('btnCopyToken').addEventListener('click', async () => {
  const token = document.getElementById('enrollmentToken').value;
  try {
    await navigator.clipboard.writeText(token);
    showFlash('Token in die Zwischenablage kopiert.', true);
  } catch {
    showFlash('Kopieren nicht möglich — Token manuell markieren.', false);
  }
});

function updateDbProviderFields() {
  const provider = document.getElementById('dbProvider').value;
  document.getElementById('fieldSqlServer').hidden = provider !== 'SqlServer';
  document.getElementById('fieldOracle').hidden = provider !== 'Oracle';
  updateMssqlAuthFields();
}

function updateMssqlAuthFields() {
  const integrated = document.getElementById('mssqlIntegrated').checked;
  document.getElementById('mssqlUserField').hidden = integrated;
  document.getElementById('mssqlPassField').hidden = integrated;
}

/** Parse key=value;key=value connection strings (case-insensitive keys). */
function parseConnParts(cs) {
  const map = {};
  String(cs || '').split(';').forEach(part => {
    const p = part.trim();
    if (!p) return;
    const eq = p.indexOf('=');
    if (eq < 0) return;
    const key = p.slice(0, eq).trim().toLowerCase();
    map[key] = p.slice(eq + 1).trim();
  });
  return map;
}

function connGet(map, ...keys) {
  for (const k of keys) {
    if (map[k.toLowerCase()] != null && map[k.toLowerCase()] !== '')
      return map[k.toLowerCase()];
  }
  return '';
}

function isTruthy(v) {
  return /^(true|yes|1)$/i.test(String(v || '').trim());
}

function parseSqlServerFields(cs) {
  const m = parseConnParts(cs);
  let server = connGet(m, 'server', 'data source', 'addr', 'address', 'network address');
  let port = '';
  // tcp:host,port or host,port
  server = server.replace(/^tcp:/i, '');
  const comma = server.lastIndexOf(',');
  if (comma > 0 && /^\d+$/.test(server.slice(comma + 1).trim())) {
    port = server.slice(comma + 1).trim();
    server = server.slice(0, comma).trim();
  }
  document.getElementById('mssqlHost').value = server;
  document.getElementById('mssqlPort').value = port;
  document.getElementById('mssqlDatabase').value = connGet(m, 'database', 'initial catalog');
  const integrated = isTruthy(connGet(m, 'integrated security', 'trusted_connection'));
  document.getElementById('mssqlIntegrated').checked = integrated;
  document.getElementById('mssqlUser').value = connGet(m, 'user id', 'uid', 'user');
  document.getElementById('mssqlPassword').value = connGet(m, 'password', 'pwd');
  const encrypt = connGet(m, 'encrypt');
  document.getElementById('mssqlEncrypt').checked = encrypt === '' ? true : isTruthy(encrypt);
  const trust = connGet(m, 'trustservercertificate');
  document.getElementById('mssqlTrustCert').checked = trust === '' ? true : isTruthy(trust);
  updateMssqlAuthFields();
}

function buildSqlServerCs() {
  const host = document.getElementById('mssqlHost').value.trim();
  const port = document.getElementById('mssqlPort').value.trim();
  const database = document.getElementById('mssqlDatabase').value.trim();
  const integrated = document.getElementById('mssqlIntegrated').checked;
  const user = document.getElementById('mssqlUser').value.trim();
  const password = document.getElementById('mssqlPassword').value;
  const encrypt = document.getElementById('mssqlEncrypt').checked;
  const trust = document.getElementById('mssqlTrustCert').checked;

  if (!host && !database && !user && !password) return '';

  let server = host;
  if (host && port) server = `${host},${port}`;

  const parts = [];
  if (server) parts.push('Server=' + server);
  if (database) parts.push('Database=' + database);
  if (integrated) {
    parts.push('Integrated Security=True');
  } else {
    if (user) parts.push('User Id=' + user);
    if (password) parts.push('Password=' + password);
  }
  parts.push('Encrypt=' + (encrypt ? 'True' : 'False'));
  parts.push('TrustServerCertificate=' + (trust ? 'True' : 'False'));
  return parts.join(';') + (parts.length ? ';' : '');
}

function parseOracleFields(cs) {
  const m = parseConnParts(cs);
  document.getElementById('oraUser').value = connGet(m, 'user id', 'uid', 'user');
  document.getElementById('oraPassword').value = connGet(m, 'password', 'pwd');

  let ds = connGet(m, 'data source', 'server');
  // //host:port/service  or  host:port/service  or  TNS name
  ds = ds.replace(/^\/\//, '');
  let host = '', port = '1521', service = '';
  const m1 = ds.match(/^([^:/]+):(\d+)\/(.+)$/);
  const m2 = ds.match(/^([^:/]+)\/(.+)$/);
  if (m1) {
    host = m1[1];
    port = m1[2];
    service = m1[3];
  } else if (m2) {
    host = m2[1];
    service = m2[2];
  } else if (ds) {
    // TNS alias or bare host — put in service/host heuristically
    if (ds.includes('.')) host = ds;
    else service = ds;
  }
  document.getElementById('oraHost').value = host;
  document.getElementById('oraPort').value = port || '1521';
  document.getElementById('oraService').value = service;
}

function buildOracleCs() {
  const host = document.getElementById('oraHost').value.trim();
  const port = document.getElementById('oraPort').value.trim() || '1521';
  const service = document.getElementById('oraService').value.trim();
  const user = document.getElementById('oraUser').value.trim();
  const password = document.getElementById('oraPassword').value;

  if (!host && !service && !user && !password) return '';

  let dataSource = '';
  if (host && service) dataSource = `${host}:${port}/${service}`;
  else if (service) dataSource = service;
  else if (host) dataSource = `${host}:${port}`;

  const parts = [];
  if (user) parts.push('User Id=' + user);
  if (password) parts.push('Password=' + password);
  if (dataSource) parts.push('Data Source=' + dataSource);
  return parts.join(';') + (parts.length ? ';' : '');
}

let _csSyncLock = false;

function syncSqlServerCsFromFields() {
  if (_csSyncLock) return;
  _csSyncLock = true;
  document.getElementById('sqlServerConnectionString').value = buildSqlServerCs();
  _csSyncLock = false;
}

function syncOracleCsFromFields() {
  if (_csSyncLock) return;
  _csSyncLock = true;
  document.getElementById('oracleConnectionString').value = buildOracleCs();
  _csSyncLock = false;
}

function bindDbBuilders() {
  const mssqlIds = ['mssqlHost', 'mssqlPort', 'mssqlDatabase', 'mssqlUser', 'mssqlPassword', 'mssqlEncrypt', 'mssqlTrustCert'];
  mssqlIds.forEach(id => {
    const el = document.getElementById(id);
    el.addEventListener('input', syncSqlServerCsFromFields);
    el.addEventListener('change', syncSqlServerCsFromFields);
  });
  document.getElementById('mssqlIntegrated').addEventListener('change', () => {
    updateMssqlAuthFields();
    syncSqlServerCsFromFields();
  });

  ['oraHost', 'oraPort', 'oraService', 'oraUser', 'oraPassword'].forEach(id => {
    const el = document.getElementById(id);
    el.addEventListener('input', syncOracleCsFromFields);
    el.addEventListener('change', syncOracleCsFromFields);
  });

  // Manual CS edit → refresh fields
  document.getElementById('sqlServerConnectionString').addEventListener('change', () => {
    if (_csSyncLock) return;
    _csSyncLock = true;
    parseSqlServerFields(document.getElementById('sqlServerConnectionString').value);
    _csSyncLock = false;
  });
  document.getElementById('oracleConnectionString').addEventListener('change', () => {
    if (_csSyncLock) return;
    _csSyncLock = true;
    parseOracleFields(document.getElementById('oracleConnectionString').value);
    _csSyncLock = false;
  });
}

document.getElementById('dbProvider').addEventListener('change', updateDbProviderFields);

async function loadDatabaseSettings() {
  const res = await api('/api/settings/database');
  if (!res.ok) return;
  const db = await res.json();
  document.getElementById('dbProvider').value = db.provider || 'Sqlite';
  const mssqlCs = db.sqlServerConnectionString || '';
  const oraCs = db.oracleConnectionString || '';
  document.getElementById('sqlServerConnectionString').value = mssqlCs;
  document.getElementById('oracleConnectionString').value = oraCs;
  if (mssqlCs) parseSqlServerFields(mssqlCs);
  if (oraCs) parseOracleFields(oraCs);
  const hint = document.getElementById('dbProviderHint');
  if (hint && db.restartRequiredHint) hint.textContent = db.restartRequiredHint;
  updateDbProviderFields();
}

function dbBody() {
  // Ensure CS reflects latest field values before send
  if (document.getElementById('dbProvider').value === 'SqlServer')
    syncSqlServerCsFromFields();
  if (document.getElementById('dbProvider').value === 'Oracle')
    syncOracleCsFromFields();

  return {
    provider: document.getElementById('dbProvider').value,
    sqlServerConnectionString: document.getElementById('sqlServerConnectionString').value.trim(),
    oracleConnectionString: document.getElementById('oracleConnectionString').value.trim()
  };
}

document.getElementById('btnTestDb').addEventListener('click', async () => {
  const res = await api('/api/settings/database/test', { method: 'POST', body: JSON.stringify(dbBody()) });
  const data = await res.json().catch(() => ({}));
  showFlash(res.ok ? (data.message || 'OK') : (data.error || 'Test fehlgeschlagen'), res.ok);
});

document.getElementById('btnSaveDb').addEventListener('click', async () => {
  const res = await api('/api/settings/database', { method: 'PUT', body: JSON.stringify(dbBody()) });
  const data = await res.json().catch(() => ({}));
  showFlash(res.ok ? (data.message || 'DB-Einstellungen gespeichert.') : (data.error || 'Speichern fehlgeschlagen'), res.ok);
});

async function loadSmtpSettings() {
  const res = await api('/api/settings/smtp');
  if (!res.ok) return;
  const s = await res.json();
  document.getElementById('smtpEnabled').checked = !!s.enabled;
  document.getElementById('smtpHost').value = s.host || '';
  document.getElementById('smtpPort').value = s.port || 587;
  document.getElementById('smtpUseSsl').checked = s.useSsl !== false;
  document.getElementById('smtpUsername').value = s.username || '';
  document.getElementById('smtpPassword').value = '';
  document.getElementById('smtpPassword').placeholder = s.hasPassword ? 'Unverändert (bereits gesetzt)' : 'Leer lassen = unverändert';
  document.getElementById('smtpFromAddress').value = s.fromAddress || '';
  document.getElementById('smtpFromName').value = s.fromName || 'SensorPulse Enterprise';
}

function smtpBody() {
  return {
    enabled: document.getElementById('smtpEnabled').checked,
    host: document.getElementById('smtpHost').value.trim(),
    port: Number(document.getElementById('smtpPort').value) || 587,
    useSsl: document.getElementById('smtpUseSsl').checked,
    username: document.getElementById('smtpUsername').value.trim(),
    password: document.getElementById('smtpPassword').value || null,
    fromAddress: document.getElementById('smtpFromAddress').value.trim(),
    fromName: document.getElementById('smtpFromName').value.trim()
  };
}

document.getElementById('btnSaveSmtp').addEventListener('click', async () => {
  const res = await api('/api/settings/smtp', { method: 'PUT', body: JSON.stringify(smtpBody()) });
  const data = await res.json().catch(() => ({}));
  showFlash(res.ok ? 'SMTP-Einstellungen gespeichert.' : (data.error || 'Speichern fehlgeschlagen'), res.ok);
  if (res.ok) await loadSmtpSettings();
});

document.getElementById('btnSendTestMail').addEventListener('click', async () => {
  const to = document.getElementById('smtpTestTo').value.trim();
  if (!to) {
    showFlash('Bitte Empfängeradresse für die Test-E-Mail angeben.', false);
    return;
  }
  const res = await api('/api/settings/smtp/test-mail', { method: 'POST', body: JSON.stringify({ to }) });
  const data = await res.json().catch(() => ({}));
  showFlash(res.ok ? (data.message || 'Test-E-Mail gesendet.') : (data.error || 'Versand fehlgeschlagen'), res.ok);
});

async function init() {
  await initLocale();
  const nav = document.querySelector('.nav');
  if (nav) {
    const logoutBtn = document.getElementById('btnLogout');
    nav.innerHTML = chromeNav('settings');
    if (logoutBtn) /* logout via chromeNav */
  }
  setActiveNav('settings');
  document.getElementById('btnLogout').addEventListener('click', logout);
  bindDbBuilders();
  try {
    const me = await loadMe();
    if (me?.role) applyRoleNav(me.role);
    if (me?.role !== 'Administrator') {
      location.href = '/';
      return;
    }
    await loadSettings();
    await loadDatabaseSettings();
    await loadSmtpSettings();
  } catch (e) {
    showFlash(e.message, false);
  }
}

init();
