(function () {
  'use strict';

  function uniqueIndex(prefix) {
    return prefix + '-' + Date.now() + '-' + Math.floor(Math.random() * 10000);
  }

  function getRowSearchText(row) {
    const values = Array.from(row.querySelectorAll('input[type="text"], input[type="url"], textarea')).map(
      (field) => field.value || ''
    );
    return values.join(' ').toLowerCase();
  }

  function getGroupSearchText(group) {
    const values = Array.from(group.querySelectorAll('input[type="text"], input[type="url"], textarea')).map(
      (field) => field.value || ''
    );
    return values.join(' ').toLowerCase();
  }

  function updateSubItemCount(group) {
    const countTarget = group ? group.querySelector('[data-junkreco-sub-count]') : null;
    if (!countTarget) {
      return;
    }

    const activeRows = Array.from(group.querySelectorAll('[data-junkreco-row="items"]')).filter((row) => {
      const deleteInput = row.querySelector('[data-junkreco-delete-input]');
      return !deleteInput || deleteInput.value !== '1';
    });
    const count = activeRows.length;
    countTarget.textContent = count + ' ' + (count === 1 ? 'sub-item' : 'sub-items');
  }

  function refreshCategoryTitle(group) {
    const title = group ? group.querySelector('[data-junkreco-category-title]') : null;
    const input = group ? group.querySelector('[data-junkreco-category-field="category"]') : null;

    if (title && input) {
      title.textContent = input.value.trim() || 'New Category';
    }
  }

  function refreshGroupSearch(group) {
    if (!group) {
      return;
    }

    group.dataset.junkrecoSearch = getGroupSearchText(group);
    refreshCategoryTitle(group);
    updateSubItemCount(group);
  }

  function refreshRowSearch(row) {
    if (row && row.dataset.junkrecoRow === 'items') {
      row.dataset.junkrecoSearch = getRowSearchText(row);
      refreshGroupSearch(row.closest('[data-junkreco-category-group]'));
    }
  }

  function refreshPreview(input) {
    const field = input.closest('.junkreco-photo-field');
    const preview = field ? field.querySelector('[data-junkreco-image-preview]') : null;

    if (!preview) {
      return;
    }

    const url = input.value.trim();
    preview.textContent = '';
    if (url) {
      const image = document.createElement('img');
      image.src = url;
      image.alt = '';
      preview.appendChild(image);
    }
  }

  function serializeRows(type) {
    if (type === 'items') {
      return Array.from(document.querySelectorAll('[data-junkreco-row="items"]')).map((row) => {
        const group = row.closest('[data-junkreco-category-group]');
        const data = {};

        if (group) {
          const category = group.querySelector('[data-junkreco-category-field="category"]');
          const categoryImage = group.querySelector('[data-junkreco-category-field="category_image"]');
          data.category = category ? category.value || '' : '';
          data.category_image = categoryImage ? categoryImage.value || '' : '';
        }

        row.querySelectorAll('[data-junkreco-field]').forEach((field) => {
          data[field.dataset.junkrecoField] = field.value || '';
        });

        return data;
      });
    }

    return Array.from(document.querySelectorAll('[data-junkreco-row="' + type + '"]')).map((row) => {
      const data = {};

      row.querySelectorAll('[data-junkreco-field]').forEach((field) => {
        data[field.dataset.junkrecoField] = field.value || '';
      });

      return data;
    });
  }

  function prepareJsonFields(form) {
    const itemTarget = form.querySelector('[data-junkreco-json-target="items"]');
    const volumeTarget = form.querySelector('[data-junkreco-json-target="volume"]');

    if (itemTarget) {
      itemTarget.value = JSON.stringify(serializeRows('items'));
    }

    if (volumeTarget) {
      volumeTarget.value = JSON.stringify(serializeRows('volume'));
    }
  }

  function updateBookingUrlVisibility(root) {
    const scope = root || document;
    const urlField = scope.querySelector('[data-junkreco-booking-url-field]');
    const selectedMode = scope.querySelector('[data-junkreco-booking-mode]:checked');

    if (!urlField || !selectedMode) {
      return;
    }

    urlField.hidden = selectedMode.value !== 'redirect';
  }

  const designCssProperties = {
    primary_color: ['--junkreco-primary', '--junkreco-green'],
    primary_dark_color: ['--junkreco-primary-dark', '--junkreco-green-dark'],
    text_color: ['--junkreco-text', '--junkreco-ink'],
    muted_color: ['--junkreco-muted-text', '--junkreco-muted'],
    surface_color: ['--junkreco-surface', '--junkreco-soft'],
    panel_color: ['--junkreco-panel'],
    option_bg_color: ['--junkreco-option-bg'],
    option_text_color: ['--junkreco-option-text'],
    option_active_bg_color: ['--junkreco-option-active-bg'],
    option_active_text_color: ['--junkreco-option-active-text'],
    border_color: ['--junkreco-border', '--junkreco-line'],
    danger_color: ['--junkreco-danger', '--junkreco-red'],
    cta_text_color: ['--junkreco-cta-text'],
  };

  const designFontStacks = {
    inherit: 'inherit',
    system: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
    sans: 'Arial, Helvetica, sans-serif',
    serif: 'Georgia, "Times New Roman", serif',
    mono: '"SFMono-Regular", Consolas, "Liberation Mono", monospace',
  };

  const designShadows = {
    none: 'none',
    subtle: '0 18px 20px -18px rgba(0, 0, 0, 0.16)',
    soft: '0 16px 32px -24px rgba(0, 0, 0, 0.24)',
    strong: '0 24px 48px -28px rgba(0, 0, 0, 0.34)',
  };

  function getDesignFieldKey(field) {
    const match = field && field.name ? field.name.match(/^junkreco_design_options\[([^\]]+)\]$/) : null;
    return match ? match[1] : '';
  }

  function getDesignInput(key) {
    return document.querySelector('[name="junkreco_design_options[' + key + ']"]');
  }

  function getDesignValue(key) {
    const input = getDesignInput(key);
    return input ? String(input.value || '').trim() : '';
  }

  function sanitizeFontStack(value) {
    return String(value || '')
      .replace(/[;{}<>\\]/g, '')
      .replace(/[^A-Za-z0-9\s,"'._-]/g, '')
      .replace(/\s+/g, ' ')
      .trim()
      .slice(0, 160);
  }

  function resolvePreviewFont() {
    const choice = getDesignValue('font_family') || 'inherit';
    if (choice === 'custom') {
      return sanitizeFontStack(getDesignValue('custom_font_family')) || 'inherit';
    }

    return designFontStacks[choice] || designFontStacks.inherit;
  }

  function setPreviewPixelVar(preview, key, property) {
    const value = getDesignValue(key);
    if (value === '') {
      return;
    }

    const raw = Number(value);
    if (Number.isFinite(raw)) {
      preview.style.setProperty(property, Math.round(raw) + 'px');
    }
  }

  function updateDesignPreview() {
    const preview = document.querySelector('[data-junkreco-design-preview]');
    if (!preview) {
      return;
    }

    Object.keys(designCssProperties).forEach((key) => {
      const value = getDesignValue(key);
      if (/^#[0-9a-f]{6}$/i.test(value)) {
        designCssProperties[key].forEach((property) => {
          preview.style.setProperty(property, value);
        });
      }
    });

    preview.style.setProperty('--junkreco-font-family', resolvePreviewFont());
    setPreviewPixelVar(preview, 'heading_size', '--junkreco-heading-size');
    setPreviewPixelVar(preview, 'body_size', '--junkreco-body-size');
    setPreviewPixelVar(preview, 'max_width', '--junkreco-max-width');
    setPreviewPixelVar(preview, 'radius', '--junkreco-radius');
    setPreviewPixelVar(preview, 'control_radius', '--junkreco-control-radius');
    preview.style.setProperty('--junkreco-shadow', designShadows[getDesignValue('shadow')] || designShadows.subtle);
  }

  function findPreviewSubmitter(event) {
    const explicitSubmitter = event && event.submitter && event.submitter.closest ? event.submitter : null;
    const activeSubmitter = document.activeElement && document.activeElement.closest ? document.activeElement : null;
    const targetSubmitter = event && event.target && event.target.closest ? event.target : null;
    const candidates = [explicitSubmitter, activeSubmitter, targetSubmitter];

    for (const candidate of candidates) {
      const submitter = candidate
        ? candidate.closest('[data-junkreco-design-preview] .junkreco-booking-submit, [data-junkreco-design-preview] .junkreco-zip-submit')
        : null;
      if (submitter) {
        return submitter;
      }
    }

    const previewForm =
      event && event.target && event.target.closest
        ? event.target.closest('[data-junkreco-design-preview] [data-junkreco-booking-form], [data-junkreco-design-preview] [data-junkreco-zip-form]')
        : null;

    return previewForm ? previewForm.querySelector('.junkreco-booking-submit, .junkreco-zip-submit') : null;
  }

  function validatePreviewRequiredFields(container) {
    if (!container) {
      return true;
    }

    const requiredFields = Array.from(container.querySelectorAll('[required]'));
    const invalidField = requiredFields.find((field) => {
      if (field.disabled) {
        return false;
      }

      if (field.type === 'checkbox' || field.type === 'radio') {
        return !field.checked;
      }

      if (typeof field.checkValidity === 'function') {
        return !field.checkValidity();
      }

      return !String(field.value || '').trim();
    });

    if (!invalidField) {
      return true;
    }

    const status = container.querySelector('[data-junkreco-booking-status], [data-junkreco-zip-status]');
    if (status) {
      status.hidden = false;
      status.className = 'junkreco-booking-status is-error';
      status.textContent = 'Please complete the required fields before submitting.';
    }

    if (typeof invalidField.reportValidity === 'function') {
      invalidField.reportValidity();
    } else if (typeof invalidField.focus === 'function') {
      invalidField.focus();
    }

    return false;
  }

  function handlePreviewBookingSubmit(submitter) {
    if (!submitter) {
      return;
    }

    const preview = submitter.closest('[data-junkreco-design-preview]');
    const form = submitter.closest('[data-junkreco-booking-form], [data-junkreco-zip-form]');
    if (!preview) {
      return;
    }

    if (form && typeof form.reportValidity === 'function' && !form.reportValidity()) {
      return;
    }

    if (!validatePreviewRequiredFields(form)) {
      return;
    }

    const status = form
      ? form.querySelector('[data-junkreco-booking-status], [data-junkreco-zip-status]')
      : preview.querySelector('[data-junkreco-booking-status], [data-junkreco-zip-status]');
    const originalText = submitter.dataset.junkrecoOriginalText || submitter.textContent;
    const isZipSubmit = submitter.classList.contains('junkreco-zip-submit');

    submitter.dataset.junkrecoOriginalText = originalText;
    submitter.disabled = true;
    submitter.textContent = isZipSubmit ? 'ZIP Checked' : 'Request Sent';

    if (status) {
      status.hidden = false;
      status.className = 'junkreco-booking-status is-success';
      status.textContent = isZipSubmit
        ? 'Great, this ZIP code is in our service area.'
        : "Request received. We'll follow up to confirm your pickup.";
    }

    window.setTimeout(() => {
      if (!submitter.isConnected) {
        return;
      }

      submitter.disabled = false;
      submitter.textContent = originalText;
    }, 1800);
  }

  function applyFilter(input) {
    const tableKey = input.dataset.junkrecoFilter;
    const query = input.value.trim().toLowerCase();

    if (tableKey === 'items') {
      const groups = document.querySelectorAll('[data-junkreco-category-group]');
      groups.forEach((group) => {
        refreshGroupSearch(group);
        group.hidden = Boolean(query) && !String(group.dataset.junkrecoSearch || '').includes(query);
      });
      return;
    }

    const rows = document.querySelectorAll('[data-junkreco-row="' + tableKey + '"]');

    rows.forEach((row) => {
      refreshRowSearch(row);
      row.hidden = Boolean(query) && !String(row.dataset.junkrecoSearch || '').includes(query);
    });
  }

  function addCategory() {
    const template = document.getElementById('junkreco-category-group-template');
    const body = document.getElementById('junkreco-category-groups');

    if (!template || !body) {
      return;
    }

    const categoryIndex = uniqueIndex('category');
    const firstItemIndex = uniqueIndex('item');
    const html = template.innerHTML.replace(/__category__/g, categoryIndex).replace(/__index__/g, firstItemIndex);
    body.insertAdjacentHTML('beforeend', html);

    const group = body.lastElementChild;
    if (group) {
      group.open = true;
      refreshGroupSearch(group);
      group.scrollIntoView({ behavior: 'smooth', block: 'center' });
      const firstField = group.querySelector('[data-junkreco-category-field="category"]');
      if (firstField) {
        firstField.focus();
      }
    }
  }

  function addSubItem(button) {
    const group = button.closest('[data-junkreco-category-group]');
    const body = group ? group.querySelector('[data-junkreco-subitems-body]') : null;
    const template = document.getElementById('junkreco-item-row-template');

    if (!group || !body || !template) {
      return;
    }

    const html = template.innerHTML.replace(/__index__/g, uniqueIndex('item'));
    body.insertAdjacentHTML('beforeend', html);

    const newRow = body.lastElementChild;
    if (newRow) {
      newRow.scrollIntoView({ behavior: 'smooth', block: 'center' });
      const firstField = newRow.querySelector('input[type="text"], textarea');
      if (firstField) {
        firstField.focus();
      }
    }

    refreshGroupSearch(group);
  }

  function addRow(type) {
    if (type === 'item') {
      addCategory();
      return;
    }

    const template = document.getElementById(type === 'volume' ? 'junkreco-volume-row-template' : 'junkreco-item-row-template');
    const body = document.getElementById(type === 'volume' ? 'junkreco-volumes-body' : 'junkreco-items-body');

    if (!template || !body) {
      return;
    }

    const html = template.innerHTML.replace(/__index__/g, uniqueIndex(type));
    body.insertAdjacentHTML('beforeend', html);

    const newRow = body.lastElementChild;
    if (newRow) {
      newRow.scrollIntoView({ behavior: 'smooth', block: 'center' });
      const firstField = newRow.querySelector('input[type="text"], textarea');
      if (firstField) {
        firstField.focus();
      }
    }
  }

  function deleteRow(button) {
    const row = button.closest('[data-junkreco-row]');
    const deleteInput = row ? row.querySelector('[data-junkreco-delete-input]') : null;
    const group = row ? row.closest('[data-junkreco-category-group]') : null;

    if (!row) {
      return;
    }

    if (deleteInput) {
      deleteInput.value = '1';
      row.classList.add('is-deleted');
      row.hidden = true;
    } else {
      row.remove();
    }

    refreshGroupSearch(group);
  }

  function deleteCategory(button) {
    const group = button.closest('[data-junkreco-category-group]');

    if (!group || !window.confirm('Delete this category and all of its sub-items?')) {
      return;
    }

    const rows = group.querySelectorAll('[data-junkreco-row="items"]');
    rows.forEach((row) => {
      const deleteInput = row.querySelector('[data-junkreco-delete-input]');
      if (deleteInput) {
        deleteInput.value = '1';
      }
    });

    group.classList.add('is-deleted');
    group.hidden = true;
  }

  function chooseMedia(button) {
    if (!window.wp || !window.wp.media) {
      return;
    }

    const field = button.closest('.junkreco-photo-field');
    const input = field ? field.querySelector('[data-junkreco-image-input]') : null;

    if (!input) {
      return;
    }

    const frame = window.wp.media({
      title: 'Choose calculator image',
      button: {
        text: 'Use this image',
      },
      multiple: false,
    });

    frame.on('select', () => {
      const attachment = frame.state().get('selection').first();
      const image = attachment ? attachment.toJSON() : null;

      if (image && image.url) {
        input.value = image.url;
        refreshPreview(input);
        refreshRowSearch(input.closest('[data-junkreco-row]'));
      }
    });

    frame.open();
  }

  const junkpathConfig = (window.JunkrecoAdminData && window.JunkrecoAdminData.junkpath) || {};
  const junkpathStrings = Object.assign(
    {
      loading: 'Working with Junkpath...',
      accountDone: 'Junkpath account settings loaded.',
      settingsDone: 'Junkpath settings loaded.',
      settingsSaved: 'Junkpath settings saved.',
      feesDone: 'Extra fees loaded.',
      feeSaved: 'Extra fee saved.',
      feeDeleted: 'Extra fee deleted.',
      missingKey: 'Save a Junkpath API key before using live account settings.',
      error: 'Junkpath request failed. Please try again.',
    },
    junkpathConfig.strings || {}
  );

  function getJunkpathRoot(button) {
    return button ? button.closest('[data-junkpath-admin]') : document.querySelector('[data-junkpath-admin]');
  }

  function setJunkpathStatus(root, message, type) {
    const status = root ? root.querySelector('[data-junkpath-status]') : null;
    if (!status) {
      return;
    }

    status.hidden = !message;
    status.className = 'junkreco-junkpath-status' + (message ? ' is-' + (type || 'info') : '');
    status.textContent = message || '';
  }

  function hasJunkpathKey(root) {
    return Boolean(junkpathConfig.hasApiKey) || (root && root.dataset.junkpathHasKey === '1');
  }

  async function requestJunkpath(operation, payload, id) {
    if (!junkpathConfig.ajaxUrl || !junkpathConfig.nonce) {
      throw new Error(junkpathStrings.error);
    }

    const body = new FormData();
    body.append('action', 'junkreco_junkpath_admin');
    body.append('nonce', junkpathConfig.nonce);
    body.append('operation', operation);
    if (payload) {
      body.append('payload', JSON.stringify(payload));
    }
    if (id) {
      body.append('id', id);
    }

    const response = await fetch(junkpathConfig.ajaxUrl, {
      method: 'POST',
      body,
      credentials: 'same-origin',
    });
    const json = await response.json();

    if (!response.ok || !json || !json.success) {
      throw new Error((json && json.data && json.data.message) || junkpathStrings.error);
    }

    return json.data || {};
  }

  function setNumberField(root, key, value) {
    const field = root.querySelector('[data-junkpath-setting="' + key + '"]');
    if (field && typeof value !== 'undefined' && value !== null) {
      field.value = Number(value || 0);
    }
  }

  function setCheckboxField(root, key, value) {
    const field = root.querySelector('[data-junkpath-setting="' + key + '"]');
    if (field) {
      field.checked = Boolean(value);
    }
  }

  function populateJunkpathSettings(root, settings) {
    const truck = (settings && settings.truck) || {};
    const pricing = (settings && settings.pricing) || {};
    const enabled = (settings && settings.enabled) || {};

    setNumberField(root, 'landfill_price', settings.landfill_price);
    setNumberField(root, 'landfill_minimum_tons', settings.landfill_minimum_tons);
    setNumberField(root, 'threshold_percent', settings.threshold_percent);
    setCheckboxField(root, 'landfill_has_minimum', settings.landfill_has_minimum);

    setNumberField(root, 'truck_length', truck.length_ft);
    setNumberField(root, 'truck_width', truck.width_ft);
    setNumberField(root, 'truck_height', truck.height_ft);
    setNumberField(root, 'truck_cubic_yards', truck.cubic_yards);

    Object.keys(pricing).forEach((key) => {
      setNumberField(root, 'pricing_' + key, pricing[key]);
    });

    Object.keys(enabled).forEach((key) => {
      setCheckboxField(root, 'enabled_' + key, enabled[key]);
    });
  }

  function collectJunkpathSettings(root) {
    const payload = {};
    root.querySelectorAll('[data-junkpath-setting]').forEach((field) => {
      const key = field.dataset.junkpathSetting;
      if (!key) {
        return;
      }

      if (field.type === 'checkbox') {
        payload[key] = Boolean(field.checked);
        return;
      }

      if (String(field.value || '').trim() !== '') {
        payload[key] = Number(field.value || 0);
      }
    });
    return payload;
  }

  function escapeAttribute(value) {
    return String(value || '')
      .replace(/&/g, '&amp;')
      .replace(/"/g, '&quot;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;');
  }

  function renderJunkpathFeeRow(fee) {
    const data = Object.assign(
      {
        id: '',
        name: '',
        instruction: '',
        constrain_to_brushed: false,
      },
      fee || {}
    );

    return `
      <div class="junkreco-junkpath-fee-row" data-junkpath-fee-id="${escapeAttribute(data.id)}">
        <label>
          <span>Name</span>
          <input type="text" data-junkpath-fee-field="name" value="${escapeAttribute(data.name)}" maxlength="120" placeholder="Mattress disposal" />
        </label>
        <label class="junkreco-junkpath-check">
          <input type="checkbox" data-junkpath-fee-field="constrain_to_brushed" ${data.constrain_to_brushed ? 'checked' : ''} />
          <span>Only brushed regions</span>
        </label>
        <label class="junkreco-junkpath-fee-instruction">
          <span>Instruction</span>
          <textarea rows="3" data-junkpath-fee-field="instruction" maxlength="2000" placeholder="$25 per tire you see in the photos.">${String(data.instruction || '')
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')}</textarea>
        </label>
        <div class="junkreco-junkpath-fee-actions">
          <button type="button" class="button button-secondary" data-junkpath-action="save-fee">${data.id ? 'Save Fee' : 'Create Fee'}</button>
          <button type="button" class="button-link-delete" data-junkpath-action="delete-fee" ${data.id ? '' : 'hidden'}>Delete</button>
        </div>
      </div>
    `;
  }

  function renderJunkpathFees(root, fees) {
    const body = root ? root.querySelector('[data-junkpath-fees-body]') : null;
    if (!body) {
      return;
    }

    body.innerHTML = Array.isArray(fees) && fees.length ? fees.map(renderJunkpathFeeRow).join('') : '<p class="description">No extra fees returned from Junkpath yet.</p>';
  }

  function applyJunkpathAccountData(root, data) {
    if (!root || !data) {
      return;
    }

    if (data.settings) {
      populateJunkpathSettings(root, data.settings);
    }

    if (Array.isArray(data.fees)) {
      renderJunkpathFees(root, data.fees);
    }
  }

  function collectJunkpathFee(row) {
    const payload = {};
    row.querySelectorAll('[data-junkpath-fee-field]').forEach((field) => {
      const key = field.dataset.junkpathFeeField;
      if (!key) {
        return;
      }

      if (field.type === 'checkbox') {
        payload[key] = Boolean(field.checked);
      } else {
        payload[key] = String(field.value || '').trim();
      }
    });
    return payload;
  }

  async function handleJunkpathAction(button) {
    const root = getJunkpathRoot(button);
    if (!root) {
      return;
    }

    if (!hasJunkpathKey(root)) {
      setJunkpathStatus(root, junkpathStrings.missingKey, 'error');
      return;
    }

    const action = button.dataset.junkpathAction;

    if (action === 'add-fee') {
      const body = root.querySelector('[data-junkpath-fees-body]');
      if (body) {
        if (body.querySelector('.description')) {
          body.textContent = '';
        }
        body.insertAdjacentHTML('afterbegin', renderJunkpathFeeRow({}));
      }
      return;
    }

    button.disabled = true;
    setJunkpathStatus(root, junkpathStrings.loading, 'loading');

    try {
      if (action === 'load-settings') {
        const data = await requestJunkpath('get_settings');
        populateJunkpathSettings(root, data.settings || {});
        setJunkpathStatus(root, junkpathStrings.settingsDone, 'success');
      } else if (action === 'load-account') {
        const data = await requestJunkpath('get_account');
        applyJunkpathAccountData(root, data);
        setJunkpathStatus(root, data.warning || junkpathStrings.accountDone, data.warning ? 'error' : 'success');
      } else if (action === 'save-settings') {
        const data = await requestJunkpath('update_settings', collectJunkpathSettings(root));
        populateJunkpathSettings(root, data.settings || {});
        setJunkpathStatus(root, junkpathStrings.settingsSaved, 'success');
      } else if (action === 'load-fees') {
        const data = await requestJunkpath('list_fees');
        renderJunkpathFees(root, data.fees || []);
        setJunkpathStatus(root, junkpathStrings.feesDone, 'success');
      } else if (action === 'save-fee') {
        const row = button.closest('[data-junkpath-fee-id]');
        const id = row ? row.dataset.junkpathFeeId || '' : '';
        const data = await requestJunkpath(id ? 'update_fee' : 'create_fee', collectJunkpathFee(row), id);
        if (row && data.fee) {
          row.outerHTML = renderJunkpathFeeRow(data.fee);
        }
        setJunkpathStatus(root, junkpathStrings.feeSaved, 'success');
      } else if (action === 'delete-fee') {
        const row = button.closest('[data-junkpath-fee-id]');
        const id = row ? row.dataset.junkpathFeeId || '' : '';
        if (!id || !window.confirm('Delete this Junkpath extra fee?')) {
          return;
        }
        await requestJunkpath('delete_fee', null, id);
        row.remove();
        setJunkpathStatus(root, junkpathStrings.feeDeleted, 'success');
      }
    } catch (error) {
      setJunkpathStatus(root, error && error.message ? error.message : junkpathStrings.error, 'error');
    } finally {
      button.disabled = false;
    }
  }

  async function autoloadJunkpathAccount() {
    const root = document.querySelector('[data-junkpath-admin][data-junkpath-autoload="1"]');
    if (!root || !hasJunkpathKey(root) || root.dataset.junkpathAutoloaded === '1') {
      return;
    }

    root.dataset.junkpathAutoloaded = '1';
    setJunkpathStatus(root, junkpathStrings.loading, 'loading');

    try {
      const data = await requestJunkpath('get_account');
      applyJunkpathAccountData(root, data);
      setJunkpathStatus(root, data.warning || junkpathStrings.accountDone, data.warning ? 'error' : 'success');
    } catch (error) {
      setJunkpathStatus(root, error && error.message ? error.message : junkpathStrings.error, 'error');
    }
  }

  document.addEventListener('click', (event) => {
    const previewSubmitter =
      event.target && event.target.closest
        ? event.target.closest('[data-junkreco-design-preview] .junkreco-booking-submit, [data-junkreco-design-preview] .junkreco-zip-submit')
        : null;
    if (previewSubmitter) {
      event.preventDefault();
      event.stopPropagation();
      handlePreviewBookingSubmit(previewSubmitter);
      return;
    }

    const junkpathButton = event.target.closest('[data-junkpath-action]');
    if (junkpathButton) {
      event.preventDefault();
      handleJunkpathAction(junkpathButton);
      return;
    }

    const addCategoryButton = event.target.closest('[data-junkreco-add-category]');
    if (addCategoryButton) {
      addCategory();
      return;
    }

    const addSubItemButton = event.target.closest('[data-junkreco-add-sub-item]');
    if (addSubItemButton) {
      addSubItem(addSubItemButton);
      return;
    }

    const addButton = event.target.closest('[data-junkreco-add-row]');
    if (addButton) {
      addRow(addButton.dataset.junkrecoAddRow);
      return;
    }

    const deleteButton = event.target.closest('[data-junkreco-delete-row]');
    if (deleteButton) {
      deleteRow(deleteButton);
      return;
    }

    const deleteCategoryButton = event.target.closest('[data-junkreco-delete-category]');
    if (deleteCategoryButton) {
      deleteCategory(deleteCategoryButton);
      return;
    }

    const mediaButton = event.target.closest('[data-junkreco-media-button]');
    if (mediaButton) {
      chooseMedia(mediaButton);
    }
  });

  document.addEventListener('input', (event) => {
    if (event.target.matches('[data-junkreco-color-picker]')) {
      const textInput = event.target.closest('.junkreco-color-control')?.querySelector('[data-junkreco-color-text]');
      if (textInput) {
        textInput.value = event.target.value;
      }
      updateDesignPreview();
      return;
    }

    if (event.target.matches('[data-junkreco-color-text]')) {
      const picker = event.target.closest('.junkreco-color-control')?.querySelector('[data-junkreco-color-picker]');
      if (picker && /^#[0-9a-f]{6}$/i.test(event.target.value)) {
        picker.value = event.target.value;
      }
      updateDesignPreview();
      return;
    }

    if (getDesignFieldKey(event.target)) {
      updateDesignPreview();
    }

    if (event.target.matches('[data-junkreco-filter]')) {
      applyFilter(event.target);
      return;
    }

    if (event.target.matches('[data-junkreco-image-input]')) {
      refreshPreview(event.target);
    }

    refreshRowSearch(event.target.closest('[data-junkreco-row]'));
    refreshGroupSearch(event.target.closest('[data-junkreco-category-group]'));
  });

  document.addEventListener('change', (event) => {
    if (event.target.matches('[data-junkreco-booking-mode]')) {
      updateBookingUrlVisibility(event.target.closest('form'));
    }

    if (getDesignFieldKey(event.target)) {
      updateDesignPreview();
    }
  });

  document.addEventListener('submit', (event) => {
    const previewSubmitter = findPreviewSubmitter(event);
    if (previewSubmitter) {
      event.preventDefault();
      event.stopPropagation();
      handlePreviewBookingSubmit(previewSubmitter);
      return;
    }

    const form = event.target.closest('.junkreco-admin form');
    if (form) {
      prepareJsonFields(form);
    }
  }, true);

  document.querySelectorAll('[data-junkreco-row="items"]').forEach(refreshRowSearch);
  document.querySelectorAll('[data-junkreco-category-group]').forEach(refreshGroupSearch);
  updateBookingUrlVisibility(document);
  updateDesignPreview();
  autoloadJunkpathAccount();
})();
