<?php
// ═══════════════════════════════════════════════════════════════════════════════════════════════
// PURPOSE
//   Settings tab. Varaverk's own configuration — storage mode, global toggles, and the conf
//   fields that are not specific to any one subsystem.
//
// DESIGN PRINCIPLES
//   Edits go through the same conf machinery the scheduler page uses (include/confform.php),
//   so a value changed here is written exactly the way a value changed anywhere else is —
//   surgically, preserving comments and ordering.
//
//   Storage mode is presented as a migration, not a setting. Changing it moves the whole
//   installation and regenerates the cron, which is why it routes through api/storage.php
//   rather than a plain conf write.
//
// OPERATIONAL SAFEGUARDS
//   The storage-mode change is confirmed before it runs. It is the most destructive operation
//   reachable from the UI — rsync --delete, rm -rf, and a rewrite of every derived path.
//
//   Conf writes are surgical. A settings page that regenerated master.conf would destroy the
//   comment blocks that document every threshold in it.
//
//   Values are escaped on render and on write-back.
//
// RENDERS
//   Storage mode selector, global toggles, general conf fields
//
// DEPENDS ON
//   api/confform.php  conf read/write   → include/confform.php
//   api/storage.php   storage-mode migration
$_myHost  = vv_detect_host();
$_vars    = vv_conf_vars();
$_myId    = strtoupper($_myHost);

// Storage
$_confKey = $_myId . '_STORAGE_MODE_INTERNAL';
$_confVal = $_vars[$_confKey] ?? null;

// Notifications
$_notifyUnraid  = ($_vars['NOTIFY_UNRAID']  ?? 'true')  !== 'false';
$_enableLogging = ($_vars['ENABLE_LOGGING'] ?? 'false') === 'true';
$_discordKey    = $_myId . '_DISCORD_WEBHOOK';
$_discordHook   = $_vars[$_discordKey] ?? '';

?>
<style>
.vv-set-card   { background:#161616;border:1px solid #2a2a2a;border-radius:6px;padding:14px 16px;margin-bottom:14px; }
.vv-set-hdr    { font-size:11px;font-weight:700;color:#666;text-transform:uppercase;letter-spacing:.07em;margin-bottom:12px; }
.vv-set-row    { display:flex;justify-content:space-between;align-items:baseline;gap:8px;margin:4px 0; }
.vv-set-lbl    { font-size:11px;color:#444; }
.vv-set-val    { font-size:12px;color:#888;text-align:right;font-family:monospace; }
.vv-set-badge  { display:inline-block;font-size:10px;padding:2px 8px;border-radius:3px;font-weight:700;letter-spacing:.04em; }
.vv-set-badge.internal { background:#0d1f0d;color:#4caf50;border:1px solid #1a3a1a; }
.vv-set-badge.flash    { background:#1a1200;color:#ffb74d;border:1px solid #3a2800; }
.vv-set-badge.custom   { background:#0a1a2a;color:#4a9eff;border:1px solid #1a3a5a; }
.vv-set-sep    { border:none;border-top:1px solid #1e1e1e;margin:10px 0; }
.vv-set-btn    { background:#1a1a1a;border:1px solid #333;color:#888;font-size:11px;padding:5px 14px;
                 border-radius:3px;cursor:pointer;transition:border-color .15s,color .15s; }
.vv-set-btn:hover { border-color:#555;color:#ccc; }
.vv-set-btn:disabled { opacity:.4;cursor:default; }
.vv-set-btn.primary { background:#1a2a1a;border-color:#2d4a2d;color:#4caf50; }
.vv-set-btn.primary:hover { background:#223a22; }
.vv-set-btn.warn  { background:#1f1500;border-color:#3a2800;color:#ffb74d; }
.vv-set-btn.warn:hover { background:#2a1e00; }
.vv-set-out   { background:#080808;border:1px solid #1a1a1a;border-radius:3px;padding:10px 12px;
                font-family:monospace;font-size:10px;color:#555;white-space:pre-wrap;word-break:break-all;
                max-height:320px;overflow-y:auto;margin-top:10px;display:none;
                scrollbar-width:none; }
.vv-set-out::-webkit-scrollbar { display:none; }
.vv-set-info  { font-size:11px;color:#444;line-height:1.6;margin-bottom:10px; }
.vv-set-warn-box { background:#1a1200;border:1px solid #3a2800;border-radius:4px;
                   padding:8px 12px;font-size:11px;color:#ffb74d;margin-top:8px;display:none; }
.vv-set-tog-wrap { display:flex;align-items:center;gap:10px;cursor:pointer;user-select:none; }
.vv-set-tog-track{ width:32px;height:18px;border-radius:9px;background:#222;border:1px solid #333;
                   position:relative;transition:background .15s,border-color .15s;flex-shrink:0; }
.vv-set-tog-track.on { background:#1a3a1a;border-color:#2d5a2d; }
.vv-set-tog-track::after { content:'';position:absolute;top:2px;left:2px;width:12px;height:12px;
                            border-radius:50%;background:#555;transition:left .15s,background .15s; }
.vv-set-tog-track.on::after { left:16px;background:#4caf50; }
.vv-set-tog-lbl  { font-size:12px;color:#888; }
.vv-set-tog-sub  { font-size:10px;color:#3a3a3a;margin-top:1px; }
.vv-set-inp      { background:#0d0d0d;border:1px solid #2a2a2a;border-radius:3px;color:#888;
                   font-size:12px;padding:5px 8px;outline:none;width:100%;box-sizing:border-box;
                   font-family:monospace; }
.vv-set-inp:focus{ border-color:#444; }
</style>

<div style="max-width:740px;margin:0 auto;">

  <!-- Storage Location card -->
  <div class="vv-set-card" id="vv-stor-card">
    <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;">
      <span class="vv-set-hdr" style="margin-bottom:0;">Storage Location</span>
      <span id="vv-stor-badge" class="vv-set-badge">…</span>
    </div>

    <div id="vv-stor-info" style="font-size:11px;color:#3a3a3a;">Loading…</div>

    <hr class="vv-set-sep">

    <div class="vv-set-info">
      Varaverk stores all scripts, configuration, state files, and the git repository in
      <code style="font-size:10px;color:#4a7a4a;background:#080808;padding:1px 4px;border-radius:2px;">SCRIPTS_DIR</code>.
      <br>
      <strong style="color:#555;">Internal NVMe/SSD</strong> — direct access, zero write-wear concern, git pull/push from boot volume.<br>
      <strong style="color:#555;">USB Flash</strong> — preserves flash lifetime. Requires array to be started. git pull syncs
      <code style="font-size:10px;color:#4a7a4a;background:#080808;padding:1px 4px;border-radius:2px;">Plugin/</code>
      back to <code style="font-size:10px;color:#4a7a4a;background:#080808;padding:1px 4px;border-radius:2px;">/boot/</code>
      after each pull so the webUI always stays current.
    </div>

    <div id="vv-stor-warn-flash" class="vv-set-warn-box">
      Array must be started for Varaverk to function in flash mode. The plugin tab is always accessible.
    </div>
    <div id="vv-stor-warn-noarray" class="vv-set-warn-box">
      Array is not started — cannot migrate to flash mode right now. Start the array first.
    </div>

    <div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:10px;">
      <button id="vv-stor-migrate-btn" class="vv-set-btn" onclick="vvStorMigrate()" style="display:none;"></button>
      <button class="vv-set-btn" onclick="vvStorLoad()" style="font-size:10px;padding:4px 10px;">↻ Refresh</button>
      <span id="vv-stor-fb" style="font-size:11px;color:#444;"></span>
    </div>

    <pre class="vv-set-out" id="vv-stor-out"></pre>
  </div>

  <!-- Notifications card -->
  <div class="vv-set-card">
    <div class="vv-set-hdr">Notifications</div>

    <div style="display:flex;flex-direction:column;gap:10px;margin-bottom:14px;">
      <label class="vv-set-tog-wrap">
        <div class="vv-set-tog-track<?= $_notifyUnraid ? ' on' : '' ?>" id="vv-ntf-unraid"
             onclick="vvNtfToggle(this,'NOTIFY_UNRAID')"></div>
        <div>
          <div class="vv-set-tog-lbl">Unraid native notifications</div>
          <div class="vv-set-tog-sub">Appears in the Unraid bell icon — job completions, warnings, errors</div>
        </div>
      </label>
      <label class="vv-set-tog-wrap">
        <div class="vv-set-tog-track<?= $_enableLogging ? ' on' : '' ?>" id="vv-ntf-logging"
             onclick="vvNtfToggle(this,'ENABLE_LOGGING')"></div>
        <div>
          <div class="vv-set-tog-lbl">Verbose logging</div>
          <div class="vv-set-tog-sub">Adds detailed [LOG] lines to script output — useful for debugging scheduled runs</div>
        </div>
      </label>
    </div>

    <hr class="vv-set-sep">

    <div style="margin-bottom:6px;">
      <div style="font-size:11px;color:#555;margin-bottom:5px;">
        Discord webhook
        <span style="color:#2a2a2a;font-size:10px;margin-left:4px;"><?= htmlspecialchars($_discordKey) ?></span>
      </div>
      <div style="display:flex;gap:6px;align-items:center;">
        <input class="vv-set-inp" id="vv-ntf-discord" type="text"
               placeholder="https://discord.com/api/webhooks/…"
               value="<?= htmlspecialchars($_discordHook) ?>">
        <button class="vv-set-btn primary" onclick="vvNtfSaveWebhook()" id="vv-ntf-save"
                style="white-space:nowrap;flex-shrink:0;">Save</button>
      </div>
      <div style="font-size:10px;color:#2a2a2a;margin-top:4px;">Leave blank to disable Discord notifications for this host</div>
    </div>
    <span id="vv-ntf-fb" style="font-size:11px;"></span>
  </div>

  <!-- Unraid API Key card -->
  <div class="vv-set-card">
    <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;">
      <span class="vv-set-hdr" style="margin-bottom:0;">Unraid API Keys</span>
      <span id="vv-api-badge" class="vv-set-badge">…</span>
    </div>

    <div id="vv-api-hosts" style="margin-bottom:12px;"></div>

    <div style="font-size:11px;color:#444;margin-bottom:12px;line-height:1.6;">
      Each host registers its key in the local Unraid registry and pushes it to all partners over SSH.
      Key values are stored in the private <code style="font-size:10px;color:#4a7a4a;background:#080808;padding:1px 4px;border-radius:2px;">host*.conf</code>
      so each host can query every other host's GraphQL API directly — real-time monitoring, no SSH.
      During offboard, partner keys are removed from each registry automatically.
    </div>

    <div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;">
      <button class="vv-set-btn" onclick="vvApiCheck()" id="vv-api-check-btn">↻ Check status</button>
      <button class="vv-set-btn primary" onclick="vvApiRenew()" id="vv-api-renew-btn">Renew</button>
      <span id="vv-api-fb" style="font-size:11px;color:#444;"></span>
    </div>
    <pre class="vv-set-out" id="vv-api-out"></pre>
  </div>

</div>

<script>
var _vvStorData = null;

function vvStorLoad() {
  const info = document.getElementById('vv-stor-info');
  const badge = document.getElementById('vv-stor-badge');
  if (info) info.textContent = 'Loading…';

  fetch('/plugins/varaverk/api/storage.php?action=status&_=' + Date.now())
    .then(r => r.json())
    .then(d => {
      _vvStorData = d;
      if (!d.ok) { if (info) info.textContent = 'Error loading status'; return; }
      _vvStorRender(d);
    })
    .catch(() => { if (info) info.textContent = 'Request failed'; });
}

function _vvStorRender(d) {
  const badge  = document.getElementById('vv-stor-badge');
  const info   = document.getElementById('vv-stor-info');
  const btn    = document.getElementById('vv-stor-migrate-btn');
  const wFlash = document.getElementById('vv-stor-warn-flash');
  const wArr   = document.getElementById('vv-stor-warn-noarray');

  // Badge
  if (badge) {
    badge.textContent = d.current_mode.toUpperCase();
    badge.className   = 'vv-set-badge ' + d.current_mode;
  }

  // Info grid
  const modeLabel  = d.current_mode === 'internal' ? 'Internal NVMe/SSD' : d.current_mode === 'flash' ? 'USB Flash' : 'Custom';
  const detLabel   = d.detected     === 'internal' ? 'internal NVMe/SSD' : 'USB flash';
  const confBadge  = d.conf_val === null ? '<span style="color:#3a3a3a;">not set</span>'
                   : d.conf_val === 'true' ? '<span style="color:#4caf50;">true (internal)</span>'
                   : '<span style="color:#ffb74d;">false (flash)</span>';
  const matchIcon  = (d.current_mode === d.detected || d.current_mode === 'custom') ? '' :
                     ' <span style="color:#ef5350;">⚠ mismatch with conf</span>';

  if (info) info.innerHTML = `
    <div style="display:grid;grid-template-columns:auto 1fr;gap:3px 16px;align-items:baseline;">
      <span style="color:#333;">Mode</span>        <span style="color:#888;">${modeLabel}${matchIcon}</span>
      <span style="color:#333;">SCRIPTS_DIR</span>  <code style="font-size:10px;color:#4a7a4a;">${d.current_dir}</code>
      <span style="color:#333;">Boot device</span>  <span style="color:#555;">${d.boot_disk} <span style="color:#2a2a2a;">(${d.transport})</span></span>
      <span style="color:#333;">Auto-detect</span>  <span style="color:#555;">${detLabel}</span>
      <span style="color:#333;">${d.conf_key}</span> <span>${confBadge}</span>
    </div>`;

  // Warnings
  if (wFlash) wFlash.style.display = (d.current_mode !== 'flash' && d.detected === 'usb') ? '' : 'none';
  if (wArr)   wArr.style.display   = 'none';

  // Migrate button
  if (btn) {
    if (d.current_mode === 'internal') {
      btn.textContent  = 'Migrate to Flash (appdata)';
      btn.className    = 'vv-set-btn warn';
      btn.dataset.to   = 'flash';
      btn.style.display = '';
    } else if (d.current_mode === 'flash') {
      btn.textContent  = 'Migrate to Internal (/boot)';
      btn.className    = 'vv-set-btn primary';
      btn.dataset.to   = 'internal';
      btn.style.display = '';
    } else {
      btn.style.display = 'none';
    }
  }
}

function vvStorMigrate() {
  const btn  = document.getElementById('vv-stor-migrate-btn');
  const out  = document.getElementById('vv-stor-out');
  const fb   = document.getElementById('vv-stor-fb');
  const wArr = document.getElementById('vv-stor-warn-noarray');
  const to   = btn?.dataset.to;
  if (!to) return;

  // Flash guard: array must be started
  if (to === 'flash' && _vvStorData && !_vvStorData.array_started) {
    if (wArr) wArr.style.display = '';
    return;
  }

  const label = to === 'flash' ? 'Flash (appdata)' : 'Internal (/boot)';
  if (!confirm(`Migrate Varaverk storage to ${label}?\n\nThis will:\n• Copy all scripts, conf, and git repo to the new location\n• Update varaverk.cfg and master.conf\n• Delete the old location\n\nThe page will need a reload after migration.`)) return;

  btn.disabled  = true;
  btn.textContent = 'Migrating…';
  if (fb) fb.textContent = '';
  if (out) { out.textContent = 'Starting migration…\n'; out.style.display = ''; }

  const fd = new FormData();
  fd.append('action', 'migrate');
  fd.append('to', to);

  fetch('/plugins/varaverk/api/storage.php', { method: 'POST', body: fd })
    .then(r => r.json())
    .then(d => {
      btn.disabled = false;
      if (out) {
        out.textContent = d.output || '(no output)';
        out.scrollTop   = out.scrollHeight;
      }
      if (d.ok) {
        btn.textContent = '✓ Done — reload page';
        btn.className   = 'vv-set-btn primary';
        btn.onclick     = () => location.reload();
        if (fb) { fb.style.color = '#4caf50'; fb.textContent = 'Migration complete — reload to apply'; }
      } else {
        btn.textContent = btn.dataset.to === 'flash' ? 'Migrate to Flash (appdata)' : 'Migrate to Internal (/boot)';
        if (fb) { fb.style.color = '#ef5350'; fb.textContent = 'Migration failed — see output above'; }
      }
    })
    .catch(e => {
      btn.disabled    = false;
      btn.textContent = btn.dataset.to === 'flash' ? 'Migrate to Flash (appdata)' : 'Migrate to Internal (/boot)';
      if (fb) { fb.style.color = '#ef5350'; fb.textContent = 'Request failed: ' + e; }
    });
}

vvStorLoad();

// ── Notifications ─────────────────────────────────────────────────────────────
function vvNtfToggle(track, key) {
  const on = !track.classList.contains('on');
  track.classList.toggle('on', on);
  const file = (key === 'NOTIFY_UNRAID' || key === 'ENABLE_LOGGING') ? 'master.conf'
             : '<?= htmlspecialchars($_myHost) ?>.conf';
  const fd = new FormData();
  fd.append('id', 'settings');
  fd.append('changes', JSON.stringify([{ file, key, value: on ? 'true' : 'false', type: 'scalar' }]));
  fetch('/plugins/varaverk/api/confform.php', { method: 'POST', body: fd })
    .then(r => r.json())
    .then(d => { if (!d.ok) track.classList.toggle('on', !on); })
    .catch(()  => track.classList.toggle('on', !on));
}

function vvNtfSaveWebhook() {
  const inp  = document.getElementById('vv-ntf-discord');
  const fb   = document.getElementById('vv-ntf-fb');
  const btn  = document.getElementById('vv-ntf-save');
  btn.disabled = true; btn.textContent = 'Saving…'; fb.textContent = '';
  const fd = new FormData();
  fd.append('id', 'settings');
  fd.append('changes', JSON.stringify([{
    file:  '<?= htmlspecialchars($_myHost) ?>.conf',
    key:   '<?= htmlspecialchars($_discordKey) ?>',
    value: inp.value.trim(),
    type:  'scalar',
  }]));
  fetch('/plugins/varaverk/api/confform.php', { method: 'POST', body: fd })
    .then(r => r.json())
    .then(d => {
      btn.disabled = false; btn.textContent = 'Save';
      fb.style.color = d.ok ? '#4caf50' : '#ef5350';
      fb.textContent  = d.ok ? 'Saved ✓' : (d.error || 'Failed');
      if (d.ok) setTimeout(() => { fb.textContent = ''; }, 3000);
    })
    .catch(() => { btn.disabled = false; btn.textContent = 'Save'; fb.style.color='#ef5350'; fb.textContent='Request failed'; });
}

// ── Unraid API Keys ───────────────────────────────────────────────────────────
function vvApiCheck() {
  const btn   = document.getElementById('vv-api-check-btn');
  const badge = document.getElementById('vv-api-badge');
  const hosts = document.getElementById('vv-api-hosts');
  btn.disabled = true; btn.textContent = 'Checking…';
  fetch('/plugins/varaverk/api/storage.php?action=api_status&_=' + Date.now())
    .then(r => r.json())
    .then(d => {
      btn.disabled = false; btn.textContent = '↻ Check status';
      if (!d.ok) return;
      const allOk      = d.hosts.every(h => h.api_ok);
      const anyMissing = d.hosts.some(h => !h.key_present);
      badge.textContent = allOk ? 'all ok' : anyMissing ? 'keys missing' : 'partial';
      badge.className   = 'vv-set-badge ' + (allOk ? 'internal' : 'flash');

      if (hosts) hosts.innerHTML = d.hosts.map(h => {
        const tag    = h.is_local
          ? `<span style="color:#2a3a2a;font-size:9px;margin-left:4px;">own</span>`
          : `<span style="color:#2a2a3a;font-size:9px;margin-left:4px;">${d.my_id}'s key on ${h.host_id}</span>`;
        const keyBit = h.key_present
          ? `<code style="font-size:9px;color:#4a6a4a;">${h.key_preview}</code>`
          : `<span style="color:#8b2a2a;font-size:10px;">not set — click Renew</span>`;
        const dot = h.api_ok ? '#4caf50' : (h.key_present ? '#ffb74d' : '#444');
        return `<div style="display:flex;align-items:center;gap:8px;padding:4px 0;border-bottom:1px solid #111;">
          <span style="width:6px;height:6px;border-radius:50%;background:${dot};flex-shrink:0;display:inline-block;"></span>
          <span style="font-size:11px;color:#666;flex-shrink:0;min-width:50px;">${h.host_id}</span>
          <code style="font-size:9px;color:#2a3a2a;flex-shrink:0;">${h.is_local ? d.key_name : h.key_var}</code>
          ${tag}
          <span style="flex:1;text-align:right;">${keyBit}</span>
        </div>`;
      }).join('');
    })
    .catch(() => { btn.disabled = false; btn.textContent = '↻ Check status'; });
}

function vvApiRenew() {
  const btn   = document.getElementById('vv-api-renew-btn');
  const out   = document.getElementById('vv-api-out');
  const fb    = document.getElementById('vv-api-fb');
  const badge = document.getElementById('vv-api-badge');
  btn.disabled = true; btn.textContent = 'Renewing…';
  fb.textContent = ''; out.textContent = ''; out.style.display = '';

  const fd = new FormData();
  fd.append('action', 'setup_apikeys');
  fetch('/plugins/varaverk/api/storage.php', { method: 'POST', body: fd })
    .then(r => r.json())
    .then(d => {
      btn.disabled = false; btn.textContent = 'Renew';
      out.textContent = d.output || '(no output)';
      out.scrollTop   = out.scrollHeight;
      fb.style.color  = d.ok ? '#4caf50' : '#ef5350';
      fb.textContent  = d.ok ? '✓ Done' : 'Failed — see output';
      if (d.ok) { badge.textContent = ''; vvApiCheck(); }
    })
    .catch(() => {
      btn.disabled = false; btn.textContent = 'Renew';
      fb.style.color = '#ef5350'; fb.textContent = 'Request failed';
    });
}

// Auto-check on load
vvApiCheck();
</script>
