/* Domains & DNS manager — async, no page reloads. */
(function () {
  'use strict';
  document.addEventListener('DOMContentLoaded', function () {
    var app = document.getElementById('dns-app');
    if (!app) return;

    var CSRF = app.dataset.csrf;
    var DEFAULT_TTL = parseInt(app.dataset.defaultTtl, 10) || 300;
    var TYPE_ORDER = { A:1, AAAA:2, CNAME:3, MX:4, TXT:5, NS:6, SRV:7, CAA:8, PTR:9, SSHFP:10, TLSA:11 };
    var state = { domain: app.dataset.selected || '', records: [], sort: 'type', filter: '', selected: {} };

    function toast(msg, kind) {
      var wrap = document.getElementById('dns-toast');
      var el = document.createElement('div');
      el.className = 'alert alert-' + (kind || 'success') + ' shadow';
      el.textContent = msg;
      wrap.appendChild(el);
      setTimeout(function () { el.remove(); }, 4000);
    }

    function api(action, params, isPost) {
      var url = '/api/dns-ajax.php';
      var opts = { method: isPost ? 'POST' : 'GET', headers: {} };
      var body = Object.assign({ action: action }, params || {});
      if (isPost) {
        body.csrf_token = CSRF;
        var fd = new FormData();
        Object.keys(body).forEach(function (k) { fd.append(k, body[k]); });
        opts.body = fd;
      } else {
        url += '?' + Object.keys(body).map(function (k) { return encodeURIComponent(k) + '=' + encodeURIComponent(body[k]); }).join('&');
      }
      return fetch(url, opts).then(function (r) { return r.json(); }).then(function (j) {
        if (j && j.error) { throw new Error(j.error); }
        return j;
      });
    }

    function recKey(r) { return r.type + '|' + r.name + '|' + r.raw_content; }

    function sortedFiltered() {
      var rows = state.records.slice();
      if (state.filter) rows = rows.filter(function (r) { return r.type === state.filter; });
      rows.sort(function (a, b) {
        if (state.sort === 'type') {
          var d = (TYPE_ORDER[a.type] || 99) - (TYPE_ORDER[b.type] || 99);
          return d !== 0 ? d : a.name.localeCompare(b.name);
        }
        if (state.sort === 'ttl') return a.ttl - b.ttl;
        return String(a[state.sort]).localeCompare(String(b[state.sort]));
      });
      return rows;
    }

    function esc(s) {
      var d = document.createElement('div');
      d.textContent = s == null ? '' : s;
      return d.innerHTML.replace(/"/g, '&quot;').replace(/'/g, '&#39;');
    }

    function badge(type) {
      // Cohesive, modern record-type palette (all meet contrast with white text).
      var colors = {
        A: '#059669', AAAA: '#0d9488', CNAME: '#2563eb', MX: '#d97706',
        TXT: '#7c3aed', NS: '#0891b2', SRV: '#4f46e5', CAA: '#e11d48',
        PTR: '#475569', SSHFP: '#64748b', TLSA: '#64748b'
      };
      return '<span class="badge" style="background:' + (colors[type] || '#475569') + '">' + esc(type) + '</span>';
    }

    function renderRecords() {
      var body = document.getElementById('dns-records-body');
      if (!body) return;
      var rows = sortedFiltered();
      if (!rows.length) { body.innerHTML = '<tr><td colspan="7" class="text-center text-muted p-4">No records — add one with "Add Record".</td></tr>'; updateBulkBar(); return; }
      var prevType = null, html = '';
      rows.forEach(function (r) {
        var key = recKey(r);
        var grouped = (r.type === prevType && (r.type === 'MX' || r.type === 'NS' || r.type === 'SRV')); prevType = r.type;
        html += '<tr data-key="' + esc(key) + '"' + (grouped ? ' class="dns-grouped"' : '') + (r.disabled ? ' style="opacity:.5"' : '') + '>'
          + '<td><input type="checkbox" class="dns-row-check"' + (state.selected[key] ? ' checked' : '') + '></td>'
          + '<td>' + badge(r.type) + '</td>'
          + '<td class="dns-name"><span title="' + esc(r.name) + '">' + esc(r.name) + '</span></td>'
          + '<td class="dns-content"><code title="' + esc(r.content) + '">' + esc(r.content) + '</code>' + (r.disabled ? ' <span class="badge bg-secondary">Disabled</span>' : '') + '</td>'
          + '<td>' + (r.priority == null ? '—' : esc(r.priority)) + '</td>'
          + '<td>' + esc(r.ttl) + '</td>'
          + '<td class="text-end"><button class="btn btn-sm btn-outline-primary dns-edit"><i class="fa fa-edit"></i></button> '
          + '<button class="btn btn-sm btn-outline-danger dns-del"><i class="fa fa-trash"></i></button></td></tr>';
      });
      body.innerHTML = html;
      updateBulkBar();
    }

    function loadRecords() {
      if (!state.domain) return;
      var body = document.getElementById('dns-records-body');
      if (body) body.innerHTML = '<tr><td colspan="7" class="text-center text-muted p-4">Loading…</td></tr>';
      api('list_records', { domain_name: state.domain }, false).then(function (j) {
        state.records = j.records || []; state.selected = {}; renderRecords();
      }).catch(function (e) { toast('Failed to load records: ' + e.message, 'danger'); });
    }

    // Expose to later-task handlers within this closure.
    window.__dns = { api: api, state: state, toast: toast, loadRecords: loadRecords, renderRecords: renderRecords, recKey: recKey, DEFAULT_TTL: DEFAULT_TTL, esc: esc };

    function updateBulkBar() { if (window.__dnsUpdateBulkBar) window.__dnsUpdateBulkBar(); }

    function editorRow(rec) {
      var isEdit = !!rec;
      var types = window.DNS_RECORD_TYPES;
      var t = rec ? rec.type : 'A';
      var showPrio = (t === 'MX' || t === 'SRV');
      var tr = document.createElement('tr');
      tr.className = 'table-active dns-editor-row';
      tr.innerHTML =
        '<td></td>'
        + '<td>' + (isEdit
            ? '<input type="hidden" class="e-type" value="' + esc(t) + '">' + esc(t)
            : '<select class="form-select form-select-sm e-type">' + types.map(function (x) { return '<option' + (x === t ? ' selected' : '') + '>' + x + '</option>'; }).join('') + '</select>') + '</td>'
        + '<td><input class="form-control form-control-sm e-name" value="' + esc(rec ? rec.name : '@') + '"></td>'
        + '<td><input class="form-control form-control-sm e-content" value="' + esc(rec ? rec.content : '') + '"></td>'
        + '<td><input class="form-control form-control-sm e-prio" type="number" min="0" max="65535" style="width:70px" value="' + esc(rec && rec.priority != null ? rec.priority : (t === 'MX' ? 10 : '')) + '"' + (showPrio ? '' : ' disabled') + '></td>'
        + '<td><input class="form-control form-control-sm e-ttl" type="number" style="width:80px" value="' + esc(rec ? rec.ttl : window.__dns.DEFAULT_TTL) + '"></td>'
        + '<td class="text-end"><button class="btn btn-sm btn-primary e-save">Save</button> <button class="btn btn-sm btn-secondary e-cancel">Cancel</button></td>';
      // Toggle priority enable on type change (add mode).
      var typeSel = tr.querySelector('select.e-type');
      if (typeSel) typeSel.addEventListener('change', function () {
        var p = tr.querySelector('.e-prio');
        var on = (this.value === 'MX' || this.value === 'SRV');
        p.disabled = !on; if (on && !p.value) p.value = (this.value === 'MX' ? 10 : '');
      });
      tr.querySelector('.e-cancel').addEventListener('click', function () { window.__dns.renderRecords(); });
      tr.querySelector('.e-save').addEventListener('click', function () {
        var type = (tr.querySelector('.e-type').value || '').toUpperCase();
        var params = {
          domain_name: state.domain, record_type: type,
          record_name: tr.querySelector('.e-name').value.trim(),
          record_content: tr.querySelector('.e-content').value.trim(),
          ttl: tr.querySelector('.e-ttl').value, priority: tr.querySelector('.e-prio').value
        };
        if (isEdit) params.original_content = rec.raw_content;
        var btn = tr.querySelector('.e-save'); btn.disabled = true; btn.textContent = 'Saving…';
        window.__dns.api(isEdit ? 'edit_record' : 'add_record', params, true)
          .then(function () { window.__dns.toast(isEdit ? 'Record updated' : 'Record added'); window.__dns.loadRecords(); })
          .catch(function (e) { window.__dns.toast(e.message, 'danger'); btn.disabled = false; btn.textContent = 'Save'; });
      });
      return tr;
    }

    var addBtn = document.getElementById('dns-add-record-btn');
    if (addBtn) addBtn.addEventListener('click', function () {
      var body = document.getElementById('dns-records-body');
      if (body.querySelector('.dns-editor-row')) return; // one editor at a time
      body.insertBefore(editorRow(null), body.firstChild);
    });

    document.getElementById('dns-records-body').addEventListener('click', function (ev) {
      var tr = ev.target.closest('tr[data-key]'); if (!tr) return;
      var rec = state.records.find(function (r) { return window.__dns.recKey(r) === tr.dataset.key; });
      if (!rec) return;
      if (ev.target.closest('.dns-edit')) {
        if (document.getElementById('dns-records-body').querySelector('.dns-editor-row')) return; // one editor at a time
        var ed = editorRow(rec); tr.replaceWith(ed);
      } else if (ev.target.closest('.dns-del')) {
        if (!confirm('Delete this ' + rec.type + ' record?')) return;
        window.__dns.api('delete_record', { domain_name: state.domain, record_type: rec.type, record_name: rec.name, raw_content: rec.raw_content, ttl: rec.ttl }, true)
          .then(function () { window.__dns.toast('Record deleted'); window.__dns.loadRecords(); })
          .catch(function (e) { window.__dns.toast(e.message, 'danger'); });
      }
    });

    function selectedRecords() {
      return state.records.filter(function (r) { return state.selected[window.__dns.recKey(r)]; });
    }
    window.__dnsUpdateBulkBar = function () {
      var bar = document.getElementById('dns-bulk-bar'); if (!bar) return;
      var n = selectedRecords().length;
      document.getElementById('dns-bulk-count').textContent = n;
      bar.classList.toggle('d-none', n === 0);
    };

    var body = document.getElementById('dns-records-body');
    body.addEventListener('change', function (ev) {
      if (!ev.target.classList.contains('dns-row-check')) return;
      var tr = ev.target.closest('tr[data-key]'); if (!tr) return;
      var rec = state.records.find(function (r) { return window.__dns.recKey(r) === tr.dataset.key; });
      if (!rec) return;
      state.selected[window.__dns.recKey(rec)] = ev.target.checked;
      window.__dnsUpdateBulkBar();
    });

    var selectAll = document.getElementById('dns-select-all');
    if (selectAll) selectAll.addEventListener('change', function () {
      state.records.forEach(function (r) { state.selected[window.__dns.recKey(r)] = selectAll.checked; });
      window.__dns.renderRecords();
    });

    function bulk(action, extra, confirmMsg) {
      var recs = selectedRecords();
      if (!recs.length) return;
      if (confirmMsg && !confirm(confirmMsg.replace('{n}', recs.length))) return;
      var refs = recs.map(function (r) { return { name: r.name, type: r.type, raw_content: r.raw_content, ttl: r.ttl }; });
      var params = Object.assign({ domain_name: state.domain, records: JSON.stringify(refs) }, extra || {});
      window.__dns.api(action, params, true)
        .then(function (j) { window.__dns.toast('Done: ' + j.done + (j.failed ? (', failed: ' + j.failed) : '')); window.__dns.loadRecords(); })
        .catch(function (e) { window.__dns.toast(e.message, 'danger'); });
    }

    document.getElementById('dns-bulk-delete').addEventListener('click', function () { bulk('bulk_delete', null, 'Delete {n} selected record(s)?'); });
    document.getElementById('dns-bulk-ttl').addEventListener('click', function () {
      var ttl = prompt('New TTL for selected records (300–86400):', window.__dns.DEFAULT_TTL);
      if (ttl) bulk('bulk_ttl', { ttl: ttl });
    });
    document.getElementById('dns-bulk-toggle').addEventListener('click', function () {
      var disable = confirm('OK = Disable selected, Cancel = Enable selected');
      bulk('bulk_toggle', { disabled: disable ? '1' : '0' });
    });
    document.getElementById('dns-bulk-clear').addEventListener('click', function () { state.selected = {}; window.__dns.renderRecords(); });

    // Column sort
    Array.prototype.forEach.call(document.querySelectorAll('.dns-sort'), function (th) {
      th.style.cursor = 'pointer';
      th.addEventListener('click', function () { state.sort = th.dataset.sort; window.__dns.renderRecords(); });
    });
    // Type filter
    var tf = document.getElementById('dns-type-filter');
    if (tf) tf.addEventListener('change', function () { state.filter = tf.value; window.__dns.renderRecords(); });

    // pushState view swap: landing <-> records, keeping URL canonical.
    function showDomain(domain, noPush) {
      state.domain = domain;
      document.getElementById('dns-landing').classList.toggle('d-none', !!domain);
      document.getElementById('dns-records-view').classList.toggle('d-none', !domain);
      if (domain) {
        document.getElementById('dns-current-domain').textContent = domain;
        document.getElementById('dns-crumb-domain').textContent = domain;
        if (!noPush) { history.pushState({ domain: domain }, '', '?page=domains&domain=' + encodeURIComponent(domain)); }
        window.__dns.loadRecords();
      } else {
        if (!noPush) { history.pushState({ domain: '' }, '', '?page=domains'); }
      }
    }
    Array.prototype.forEach.call(document.querySelectorAll('#dns-domains-table a[href*="domain="]'), function (a) {
      a.addEventListener('click', function (ev) { ev.preventDefault(); showDomain(a.closest('tr').dataset.domain); });
    });
    var back = document.getElementById('dns-breadcrumb-back');
    if (back) back.addEventListener('click', function (ev) { ev.preventDefault(); showDomain(''); });
    window.addEventListener('popstate', function (ev) { showDomain((ev.state && ev.state.domain) || '', true); });
    history.replaceState({ domain: state.domain }, '', location.href);

    // Add domain (simple prompt flow; root may set owner)
    var addDom = document.getElementById('dns-add-domain-btn');
    if (addDom) addDom.addEventListener('click', function () {
      var name = prompt('New domain name (e.g. example.com):'); if (!name) return;
      var params = { domain_name: name.trim() };
      if (app.dataset.isRoot === '1') { var o = prompt('Owner username:', ''); if (o) params.owner_username = o.trim(); }
      window.__dns.api('add_domain', params, true)
        .then(function (j) { window.__dns.toast(j.message || 'Domain added'); setTimeout(function () { location.href = '?page=domains'; }, 800); })
        .catch(function (e) { window.__dns.toast(e.message, 'danger'); });
    });
    // Landing domain search (client-side filter of the already-rendered rows)
    var domSearch = document.getElementById('dns-domain-search');
    if (domSearch) domSearch.addEventListener('input', function () {
      var q = domSearch.value.trim().toLowerCase();
      Array.prototype.forEach.call(document.querySelectorAll('#dns-domains-table tbody tr'), function (tr) {
        var name = (tr.dataset.domain || '').toLowerCase();
        tr.classList.toggle('d-none', q !== '' && name.indexOf(q) === -1);
      });
    });
    // Delete domain (landing)
    Array.prototype.forEach.call(document.querySelectorAll('.dns-delete-domain'), function (btn) {
      btn.addEventListener('click', function () {
        if (!confirm('Delete domain ' + btn.dataset.domain + '? This removes its DNS zone.')) return;
        window.__dns.api('delete_domain', { domain_id: btn.dataset.id }, true)
          .then(function (j) { window.__dns.toast(j.message || 'Domain deleted'); btn.closest('tr').remove(); })
          .catch(function (e) { window.__dns.toast(e.message, 'danger'); });
      });
    });

    if (state.domain) loadRecords();
  });
})();
