$(function save_vril() {
  // --- boardName detection ---
  function detectBoard() {
    // vril.php always edits chud
    if (location.pathname.endsWith('/vril.php')) {
      return 'chud';
    }

    // if page has <input name="board"> use it
    var boardInput = document.getElementsByName('board')[0];
    if (boardInput) {
      return boardInput.value;
    }

    // otherwise parse URL
    var path = location.pathname;

    // remove leading /mod.php?/ if present
    path = path.replace(/^\/mod\.php\?\//, '/');

    // grab first path segment
    var m = path.match(/^\/([^\/]+)\//);
    return m ? m[1] : 'chud'; // fallback
  }

  var boardName = detectBoard();
  var vrilStorage = "vril_" + boardName;

  // --- safe storage wrapper ---
  var storage = (function () {
    var mem = {};
    try {
      var testKey = '__ls_test__';
      localStorage.setItem(testKey, '1');
      localStorage.removeItem(testKey);
      return {
        get: function (k) {
          var v = localStorage.getItem(k);
          return v === null ? null : v;
        },
        set: function (k, v) {
          if (v === undefined) return; // never save undefined
          localStorage.setItem(k, String(v));
        },
        remove: function (k) {
          localStorage.removeItem(k);
        }
      };
    } catch (e) {
      return {
        get: function (k) { return mem.hasOwnProperty(k) ? mem[k] : null; },
        set: function (k, v) {
          if (v === undefined) return;
          mem[k] = String(v);
        },
        remove: function (k) { delete mem[k]; }
      };
    }
  })();

  // --- helpers ---
  function getDefault() {
    return boardName === "chud" ? "country" : "";
  }

  // Read stored value but treat null/empty as default
  function readStoredVril() {
    var s = storage.get(vrilStorage);
    if (s === null) return getDefault();
    s = String(s);
    if (s.trim() === "") return getDefault();
    return s;
  }

  // Ensure there is at least a default in storage (useful for other code expecting a key)
  function ensureDefault() {
    var raw = storage.get(vrilStorage);
    if (raw === null || String(raw).trim() === "") {
      storage.set(vrilStorage, getDefault());
    }
  }
  ensureDefault();

  // set value and trigger events so other code notices it
  function setVrilTo($input) {
    if (!$input || !$input.length) return false;
    var stored = readStoredVril();
    $input.val(stored).trigger('input').trigger('change');
    return true;
  }

  // --- main input ---
  var mainInput = $('[name="vril"], #vrilselector').first();
  setVrilTo(mainInput);

  // Helper to normalize value before saving: if empty -> default
  function normalizeBeforeSave(val) {
    if (val === null || val === undefined) return getDefault();
    val = String(val);
    return val.trim() === "" ? getDefault() : val;
  }

  // Save on normal form submission, but only for forms that actually have a vril input or the selector.
  $('form').has('[name="vril"], #vrilselector').on('submit.vril', function () {
    var $form = $(this);
    var $vr = $form.find('[name="vril"], #vrilselector').first();
    var value = ($vr && $vr.length) ? ($vr.val() || "") : "";
    value = normalizeBeforeSave(value);
    storage.set(vrilStorage, value);
  });

  // Populate Quick Reply form on open
  $(window).on('quick-reply', function () {
    var $qrForm = $('form#quick-reply');

    // robust selector (matches input/select/textarea and the #vrilselector too)
    function findQrField() {
      return $qrForm.find('[name="vril"], #vrilselector').first();
    }

    // try to set immediately; if not found, retry a couple times (some QR code creates fields after event)
    var attempts = 0;
    function trySetQR() {
      attempts++;
      var $field = findQrField();
      var ok = setVrilTo($field);
      if (!ok && attempts < 4) {
        // small delay, let other QR init code finish
        setTimeout(trySetQR, attempts === 1 ? 30 : 100);
      } else {
        // attach submit handler once field exists (or attach to form anyway)
        $qrForm
          .off('submit.vril') // prevent duplicates
          .on('submit.vril', function () {
            var $f = $(this);
            var $vr = $f.find('[name="vril"], #vrilselector').first();
            var value = ($vr && $vr.length) ? ($vr.val() || "") : "";
            value = normalizeBeforeSave(value);
            storage.set(vrilStorage, value);
          });
      }
    }
    trySetQR();
  });

  // --- vrilselector page buttons ---
  if ($('#vrilselector').length) {
    if (!$('#vrilselector').next('input.vril-save').length) {
      // Save button
      var $saveBtn = $('<input type="button" class="vril-save" value="Save" style="margin-left: 5px;">')
        .insertAfter('#vrilselector')
        .click(function () {
          var v = $('#vrilselector').val() || "";
          v = normalizeBeforeSave(v);
          storage.set(vrilStorage, v);
          var btn = $(this);
          btn.val('Saved!');
          setTimeout(() => btn.val('Save'), 1000);
        });

      // Clear button resets to board default
      $('<input type="button" class="vril-clear" value="Clear" style="margin-left: 5px;">')
        .insertAfter($saveBtn)
        .click(function () {
          storage.set(vrilStorage, getDefault());
          $('#vrilselector').val(getDefault());
          setVrilTo(mainInput);
          var btn = $(this);
          btn.val('Cleared!');
          setTimeout(() => btn.val('Clear'), 1000);
        });
    }
  }
});
