// Config Shared Functions - Common functionality used across all config components
class ConfigShared {
  
  // Toggle switch system - handles different types of toggles with proper layout
  static createToggleSwitch(fieldId, key, value, title, description, options = {}) {
    const isChecked = value === 'true';
    const tooltipHtml = description ? `<span class="tooltip" title="${description}">ℹ️</span>` : '';
    
    // Determine toggle type and layout
    const toggleType = options.type || 'standard';
    const layout = options.layout || 'inline';
    
    let toggleHTML = '';
    
    switch (toggleType) {
      case 'master':
        toggleHTML = this.createMasterToggle(fieldId, key, title, isChecked, tooltipHtml, options);
        break;
      case 'section':
        toggleHTML = this.createSectionToggle(fieldId, key, title, isChecked, tooltipHtml, options);
        break;
      case 'standard':
      default:
        toggleHTML = this.createStandardToggle(fieldId, key, title, isChecked, tooltipHtml, options);
        break;
    }
    
    // Wrap in layout container
    return this.wrapToggleInLayout(toggleHTML, layout, options);
  }
  
  // Standard toggle switch (most common)
  static createStandardToggle(fieldId, key, title, isChecked, tooltipHtml, options) {
    return `
      <div class="checkbox-field">
        <label class="checkbox-label">
          <input type="checkbox" id="${fieldId}" name="${key}" value="true" ${isChecked ? 'checked' : ''} onchange="ConfigShared.handleToggleChange(this, '${key}', '${options.category || ''}')">
            <span class="checkbox-custom"></span>
            <span class="checkbox-text">
              ${title}
              ${tooltipHtml}
            </span>
          </label>
        </div>
    `;
  }
  
  // Master toggle (for enabling/disabling entire sections)
  static createMasterToggle(fieldId, key, title, isChecked, tooltipHtml, options) {
    return `
      <div class="field-group">
        <label for="${fieldId}">
          ${title}
          ${tooltipHtml}
        </label>
        <label class="checkbox-label master-toggle">
          <input type="checkbox" id="${fieldId}" name="${key}" value="true" ${isChecked ? 'checked' : ''} onchange="ConfigShared.handleMasterToggle(this, '${options.sectionId || ''}', '${options.fieldIds || []}')">
            <span class="checkbox-custom"></span>
            <span class="checkbox-text">
              ${title}
              ${tooltipHtml}
            </span>
          </label>
        </div>
    `;
  }
  
  // Section toggle (for showing/hiding sections)
  static createSectionToggle(fieldId, key, title, isChecked, tooltipHtml, options) {
    return `
      <div class="hidden-options-toggle">
        <label class="checkbox-label">
          <input type="checkbox" id="${fieldId}" name="${key}" value="true" ${isChecked ? 'checked' : ''} onchange="ConfigShared.handleSectionToggle(this, '${options.sectionId || ''}')">
            <span class="checkbox-custom"></span>
            ${title}
        </label>
      </div>
    `;
  }
  
  // Wrap toggle in layout container
  static wrapToggleInLayout(toggleHTML, layout, options) {
    switch (layout) {
      case 'grid':
        return `<div class="toggle-grid">${toggleHTML}</div>`;
      case 'flex':
        return `<div class="toggle-flex">${toggleHTML}</div>`;
      case 'inline':
      default:
        return toggleHTML;
    }
  }
  
  // Auto-detect and create appropriate field type
  static createSmartField(fieldId, key, value, title, description, options = {}) {
    //console.log(`createSmartField: key=${key}, value=${value}, config=${!!options.config}`);
    
    // Check if value is boolean (true/false strings)
    const isBoolean = value === 'true' || value === 'false';
    
    if (isBoolean) {
      // Auto-create toggle switch for boolean values
      return this.createToggleSwitch(fieldId, key, value, title, description, {
        type: options.type || 'standard',
        layout: options.layout || 'inline',
        category: options.category || '',
        sectionId: options.sectionId || '',
        fieldIds: options.fieldIds || []
      });
    }
    
    // Fall back to regular field generation for non-boolean values
    return this.generateField(fieldId, key, value, title, description, options.selectOptions, options.config);
  }
  
  // Handle standard toggle changes
  static handleToggleChange(checkbox, key, category) {
    //console.log(`Toggle changed: ${key} = ${checkbox.checked} (category: ${category})`);
    
    // Trigger custom event for other components to listen to
    const event = new CustomEvent('configToggleChanged', {
      detail: { key, value: checkbox.checked, category }
    });
    document.dispatchEvent(event);
    
    // Auto-save if enabled
    if (checkbox.dataset.autoSave === 'true') {
      this.saveToggleValue(key, checkbox.checked);
    }
  }
  
  // Handle master toggle changes (enables/disables multiple fields)
  static handleMasterToggle(checkbox, sectionId, fieldIds) {
    //console.log(`Master toggle changed: ${sectionId} = ${checkbox.checked}`);
    
    // Enable/disable related fields
    if (fieldIds && fieldIds.length > 0) {
      fieldIds.forEach(fieldId => {
        const field = document.getElementById(`config-${fieldId}`);
        if (field) {
          field.disabled = !checkbox.checked;
          field.closest('.config-field')?.classList.toggle('disabled', !checkbox.checked);
        }
      });
    }
    
    // Show/hide section content
    if (sectionId) {
      const sectionContent = document.getElementById(`${sectionId}-content`);
      if (sectionContent) {
        sectionContent.style.display = checkbox.checked ? 'block' : 'none';
      }
    }
    
    // Trigger custom event
    const event = new CustomEvent('configMasterToggleChanged', {
      detail: { sectionId, enabled: checkbox.checked, fieldIds }
    });
    document.dispatchEvent(event);
  }
  
  // Handle section toggle changes (shows/hides sections)
  static handleSectionToggle(checkbox, sectionId) {
    //console.log(`Section toggle changed: ${sectionId} = ${checkbox.checked}`);
    
    const content = document.getElementById(`${sectionId}-content`);
    if (content) {
      content.style.display = checkbox.checked ? 'block' : 'none';
    }
    
    // Trigger custom event
    const event = new CustomEvent('configSectionToggleChanged', {
      detail: { sectionId, visible: checkbox.checked }
    });
    document.dispatchEvent(event);
  }
  
  // Save toggle value immediately
  static async saveToggleValue(key, value) {
    try {
      // For now, just log the change - local implementation
      //console.log('Toggle value changed:', key, value ? 'true' : 'false');
      
      // TODO: Implement local config file update
      // This would require backend integration to write to actual config files
      
    } catch (error) {
      console.error('Error saving toggle value:', error);
    }
  }
  
  // Create custom range field with start-end inputs
  static createRangeField(fieldId, key, value, title, description) {
    // Parse range value (format: "start-end")
    let startRange = '';
    let endRange = '';
    
    if (value && value.includes('-')) {
      const parts = value.split('-');
      startRange = parts[0] || '';
      endRange = parts[1] || '';
    }
    
    return `
      <div class="range-field" style="display: flex; gap: 8px; align-items: center; width: 100%;">
        <input type="number" 
               id="${fieldId}-start" 
               class="form-control" 
               placeholder="Start" 
               value="${startRange}" 
               min="1" 
               max="65535"
               onchange="ConfigShared.updateRangeValue('${key}')"
               style="flex: 1; min-width: 0;">
        <span style="color: #6c757d; font-weight: bold; font-size: 16px; padding: 0 4px;">-</span>
        <input type="number" 
               id="${fieldId}-end" 
               class="form-control" 
               placeholder="End" 
               value="${endRange}" 
               min="1" 
               max="65535"
               onchange="ConfigShared.updateRangeValue('${key}')"
               style="flex: 1; min-width: 0;">
        <input type="hidden" id="${fieldId}" name="${key}" value="${value}">
      </div>
      <style>
        .range-field {
          display: flex;
          align-items: center;
          gap: 8px;
          width: 100%;
        }
        .range-field input[type="number"] {
          text-align: center;
        }
        .range-field span {
          color: var(--text-secondary, #6c757d);
          font-weight: bold;
          font-size: 16px;
          user-select: none;
        }
      </style>
    `;
  }

  // Update range value when inputs change
  static updateRangeValue(key) {
    const startInput = document.getElementById(`config-${key}-start`);
    const endInput = document.getElementById(`config-${key}-end`);
    const hiddenInput = document.getElementById(`config-${key}`);
    
    if (startInput && endInput && hiddenInput) {
      const startValue = startInput.value || '';
      const endValue = endInput.value || '';
      
      if (startValue && endValue) {
        hiddenInput.value = `${startValue}-${endValue}`;
      } else if (startValue) {
        hiddenInput.value = `${startValue}-`;
      } else if (endValue) {
        hiddenInput.value = `-${endValue}`;
      } else {
        hiddenInput.value = '';
      }
    }
  }

  // Create custom crontab field with hour/minutes/AM-PM
  static createCrontabField(fieldId, key, value, title, description) {
    // Parse crontab value (format: "minute hour * * *")
    const parts = value.split(' ');
    let hour = '5';
    let minute = '0';
    let period = 'AM';
    
    if (parts.length >= 2) {
      minute = parts[0] || '0';
      const cronHour = parseInt(parts[1]) || 0;
      
      // Convert 24-hour to 12-hour format
      if (cronHour === 0) {
        hour = '12';
        period = 'AM';
      } else if (cronHour < 12) {
        hour = cronHour.toString();
        period = 'AM';
      } else if (cronHour === 12) {
        hour = '12';
        period = 'PM';
      } else {
        hour = (cronHour - 12).toString();
        period = 'PM';
      }
    }
    
    return `
      <div class="crontab-field" style="display: flex; gap: 4px; align-items: center; width: 100%;">
        <select id="${fieldId}-hour" class="form-control" onchange="ConfigShared.updateCrontabValue('${key}')" style="flex: 1; min-width: 0;">
          ${Array.from({length: 12}, (_, i) => i + 1).map(h => 
            `<option value="${h}" ${h === parseInt(hour) ? 'selected' : ''}>${h}</option>`
          ).join('')}
        </select>
        <span style="color: #6c757d; font-weight: bold; font-size: 16px; padding: 0 2px;">:</span>
        <select id="${fieldId}-minute" class="form-control" onchange="ConfigShared.updateCrontabValue('${key}')" style="flex: 1; min-width: 0;">
          ${Array.from({length: 60}, (_, i) => i.toString().padStart(2, '0')).map(m => 
            `<option value="${m}" ${m === minute ? 'selected' : ''}>${m}</option>`
          ).join('')}
        </select>
        <span style="color: #6c757d; font-weight: bold; font-size: 16px; padding: 0 2px;">/</span>
        <select id="${fieldId}-period" class="form-control" onchange="ConfigShared.updateCrontabValue('${key}')" style="flex: 1; min-width: 0;">
          <option value="AM" ${period === 'AM' ? 'selected' : ''}>AM</option>
          <option value="PM" ${period === 'PM' ? 'selected' : ''}>PM</option>
        </select>
        <input type="hidden" id="${fieldId}" name="${key}" value="${value}">
      </div>
      <style>
        .crontab-field {
          margin-bottom: 0 !important;
        }
        .crontab-field select {
          font-size: 14px;
          height: 38px;
        }
      </style>
    `;
  }

  // Update crontab value when fields change
  static updateCrontabValue(key) {
    const fieldId = `config-${key}`;
    const hourSelect = document.getElementById(`${fieldId}-hour`);
    const minuteSelect = document.getElementById(`${fieldId}-minute`);
    const periodSelect = document.getElementById(`${fieldId}-period`);
    const hiddenInput = document.getElementById(fieldId);
    
    if (!hourSelect || !minuteSelect || !periodSelect || !hiddenInput) {
      console.warn(`Crontab field elements not found for: ${key}`);
      return;
    }
    
    const hour = parseInt(hourSelect.value);
    const minute = minuteSelect.value;
    const period = periodSelect.value;
    
    // Convert 12-hour to 24-hour format
    let cronHour;
    if (period === 'AM') {
      cronHour = hour === 12 ? 0 : hour;
    } else {
      cronHour = hour === 12 ? 12 : hour + 12;
    }
    
    // Create crontab format: "minute hour * * *"
    const crontabValue = `${minute} ${cronHour} * * *`;
    hiddenInput.value = crontabValue;
    
    //console.log(`Updated crontab for ${key}: ${crontabValue}`);
  }

  // Toggle password visibility
  static togglePasswordVisibility(fieldId) {
    const passwordField = document.getElementById(fieldId);
    const icon = document.getElementById(`${fieldId}-icon`);
    
    if (!passwordField || !icon) {
      console.warn(`Password field or icon not found: ${fieldId}`);
      return;
    }
    
    if (passwordField.type === 'password') {
      passwordField.type = 'text';
      icon.textContent = '👁‍🗨'; // Eye with strikethrough (hidden)
    } else {
      passwordField.type = 'password';
      icon.textContent = '👁'; // Regular eye (visible)
    }
  }

  static setPasswordMode(fieldId, mode) {
    const wrapper = document.querySelector(`.password-mode-wrapper[data-field-id="${fieldId}"]`);
    const input = document.getElementById(fieldId);
    const tokenInput = document.getElementById(`${fieldId}-token`);
    if (!wrapper || !input || !tokenInput) return;

    const key = wrapper.dataset.fieldKey;

    if (mode === 'random') {
      input.dataset.previousCustom = input.value || '';
      input.value = '';
      input.readOnly = true;
      input.type = 'password';
      input.setAttribute('placeholder', 'Will generate on save');
      input.removeAttribute('name');
      tokenInput.setAttribute('name', key);
      const icon = document.getElementById(`${fieldId}-icon`);
      if (icon) icon.textContent = '👁';
    } else {
      input.readOnly = false;
      input.removeAttribute('placeholder');
      input.value = input.dataset.previousCustom || '';
      input.setAttribute('name', key);
      tokenInput.removeAttribute('name');
      input.focus();
    }
  }

  // Format config key to readable label
  static formatConfigLabel(key) {
    // Special handling for domain configuration
    if (key.startsWith('CFG_DOMAIN_')) {
      const domainNum = key.replace('CFG_DOMAIN_', '');
      return `Domain ${domainNum}`;
    }
    
    // Special handling for requirement configuration - remove REQUIREMENT and format nicely
    if (key.startsWith('CFG_REQUIREMENT_')) {
      const requirement = key.replace('CFG_REQUIREMENT_', '');
      return requirement
        .replace(/_/g, ' ')
        .replace(/\b\w/g, l => l.toUpperCase());
    }
    
    return key
      .replace(/^CFG_/, '')
      .replace(/_/g, ' ')
      .replace(/\b\w/g, l => l.toUpperCase());
  }

  // Group config keys by category
  static groupConfigKeys(config) {
    const groups = {};

    // Group by category field from JSON config
    for (const key of Object.keys(config)) {
      const configItem = config[key] || {};
      const category = configItem.category;

      if (!groups[category]) {
        groups[category] = [];
      }
      groups[category].push(key);
    }

    // Pin any per-app `*_BACKUP` toggle to the top of its category so the
    // user always sees it first when configuring an app. Matches both
    // `CFG_BACKUP` and `CFG_<APP>_BACKUP` (but not `*_BACKUP_*` like
    // `CFG_BACKUP_CRONTAB_APP`, which would otherwise bubble up too).
    for (const cat of Object.keys(groups)) {
      groups[cat].sort((a, b) => {
        const aBackup = /^CFG_(?:[A-Z0-9]+_)?BACKUP$/.test(a);
        const bBackup = /^CFG_(?:[A-Z0-9]+_)?BACKUP$/.test(b);
        if (aBackup && !bBackup) return -1;
        if (!aBackup && bBackup) return 1;
        return 0;
      });
    }

    return groups;
  }

  // Extract category order from config
  static extractCategoryOrder(config) {
    const order = [];
    const seen = new Set();
    
    // Get categories in the order they appear in config
    for (const key of Object.keys(config)) {
      const configItem = config[key] || {};
      const category = configItem.category;
      
      if (category && !seen.has(category)) {
        seen.add(category);
        order.push(category);
      }
    }
    
    return order;
  }

  // Format category name for display
  static formatCategoryName(category) {
    return category
      .replace(/_/g, ' ')
      .replace(/\b\w/g, l => l.toUpperCase());
  }

  /* Subcategory titles often come back as "<Category> <Sub>" — e.g.
     "General Basic" under the General category, "Webui Logins" under
     the Webui category. The redundant leading category word is noisy
     when the user is already viewing that category page, so strip it.
     Comparison is case-insensitive and only strips a clean leading
     whole-word match (won't turn "Configuration" into "iguration"). */
  static stripCategoryPrefix(title, parentCategory) {
    if (!title || !parentCategory) return title;
    const prefix = ConfigShared.formatCategoryName(parentCategory) + ' ';
    if (title.toLowerCase().startsWith(prefix.toLowerCase())) {
      return title.substring(prefix.length);
    }
    return title;
  }

  // Get category description from config or fallback
  static async getCategoryDescription(category) {
    try {
      // First try to get description from the unified config
      const response = await fetch('/data/config/generated/configs.json');
      const data = await response.json();
      
      // Check if categories exist in this config
      if (data.categories) {
        // Categories are stored as simple key-value pairs: "CATEGORY": "description"
        const categoryDescription = data.categories[category];
        if (categoryDescription) {
          return categoryDescription;
        }
      }
      
      // Fallback to unified config for general descriptions
      const unifiedConfigResponse = await fetch('/data/config/generated/configs.json');
      const unifiedConfigData = await unifiedConfigResponse.json();
      const fallbackCategoryData = unifiedConfigData.categories[category] || null;
      
      return fallbackCategoryData ? fallbackCategoryData.description : `${this.formatCategoryName(category)} settings and configuration`;
    } catch (error) {
      console.error('Error loading category descriptions:', error);
      return `${this.formatCategoryName(category)} settings and configuration`;
    }
  }

  // Generate appropriate field based on value type and key
  static generateField(fieldId, key, value, title, description, options = {}, allConfig = {}) {
    //console.log(`generateField: key=${key}, value=${value}, CFG_INSTALL_MODE=${allConfig.CFG_INSTALL_MODE?.value}`);
    
    // Note: Git fields (CFG_GIT_*) are now handled by the toggle system in renderGitSection
    // They don't need to be hidden here since the section itself is toggled
    
    // Handle boolean toggle fields from options
    const { onchange, oninput, onblur, className, placeholder, ...fieldOptions } = options;
    
    // Check if value is boolean (true/false strings)
    const isBoolean = value === 'true' || value === 'false';
    
    if (isBoolean) {
      // Auto-create toggle switch for boolean values
      return this.createToggleSwitch(fieldId, key, value, title, description, {
        type: 'standard',
        layout: 'inline',
        category: ''
      });
    }
    
    // Non-boolean fields - use exact old config structure
    const tooltipHtml = description ? `<span class="tooltip" title="${description}">ℹ️</span>` : '';
    
    let fieldHTML = `
      <div class="field-group">
        <label for="${fieldId}">
          ${title}
          ${tooltipHtml}
        </label>
    `;
    
    // Determine field type based on key or options
    ////console.log(`Checking field type for key: ${key}`); // Debug log
    ////console.log(`Password check: ${key.includes('PASS') && !key.includes('LENGTH')}, ${key.includes('SECRET')}`); // Debug log
    
    // Custom crontab fields for backup schedules
    if (key === 'CFG_BACKUP_CRONTAB_APP') {
      fieldHTML += this.createCrontabField(fieldId, key, value, title, description);
    } else if (key.includes('PORT_RANGE')) {
      fieldHTML += this.createRangeField(fieldId, key, value, title, description);
    } else if ((key.includes('PASS') && !key.includes('LENGTH')) || key.includes('SECRET') || key.endsWith('_API_KEY') || key.endsWith('_PRIVATE_KEY')) {
      ////console.log(`Creating password field for: ${key}`); // Debug log
      const randomMatch = typeof value === 'string' && /^RANDOMIZEDPASSWORD\d+$/.test(value);
      const placeholderToken = randomMatch ? value : `RANDOMIZEDPASSWORD1`;
      const initialMode = randomMatch ? 'random' : 'custom';
      const inputValue = randomMatch ? '' : value;
      const visibleName = initialMode === 'custom' ? `name="${key}"` : '';
      const hiddenName = initialMode === 'random' ? `name="${key}"` : '';
      fieldHTML += `
        <div class="password-mode-wrapper" data-field-id="${fieldId}" data-field-key="${key}" data-placeholder-token="${placeholderToken}" style="display: flex; gap: 6px; align-items: stretch;">
          <select class="form-control password-mode-select" style="max-width: 140px;" onchange="ConfigShared.setPasswordMode('${fieldId}', this.value)">
            <option value="random" ${initialMode === 'random' ? 'selected' : ''}>Random</option>
            <option value="custom" ${initialMode === 'custom' ? 'selected' : ''}>Custom</option>
          </select>
          <div class="password-input-wrapper" style="position: relative; flex: 1;">
            <input type="password" id="${fieldId}" ${visibleName} value="${inputValue}" class="form-control password-field" style="padding-right: 35px;" ${initialMode === 'random' ? 'readonly placeholder="Will generate on save"' : ''}>
            <input type="hidden" id="${fieldId}-token" ${hiddenName} value="${placeholderToken}">
            <button class="password-toggle" type="button" onclick="togglePasswordVisibility('${fieldId}')" style="position: absolute; right: 8px; top: 50%; transform: translateY(-50%); border: none; background: transparent; cursor: pointer; padding: 4px; border-radius: 3px; display: flex; align-items: center; justify-content: center; width: 24px; height: 24px;">
              <span id="${fieldId}-icon" style="font-size: 14px; color: var(--text-primary); font-weight: bold; user-select: none;">👁</span>
            </button>
          </div>
        </div>
        <style>
          .password-toggle {
            opacity: 1 !important;
            transition: all 0.2s ease;
          }
          .password-toggle:focus {
            outline: none;
            box-shadow: none;
          }
          .password-toggle:active {
            transform: translateY(-50%) scale(0.95);
          }
          .password-toggle span {
            opacity: 1 !important;
            color: var(--text-primary) !important;
          }
          .password-toggle:hover {
            background-color: rgba(var(--text-rgb), 0.12) !important;
          }
          .password-toggle:active {
            background-color: rgba(var(--text-rgb), 0.22) !important;
          }
        </style>
      `;
    } else if (key.includes('EMAIL') || key.includes('MAIL')) {
      // Special handling for CFG_MAIL_SECURE - it's a dropdown
      if (key === 'CFG_MAIL_SECURE') {
        const selectOptions = ConfigOptions.getSelectOptions(key);
        fieldHTML += `<select id="${fieldId}" name="${key}" class="form-control">${selectOptions.map(opt => `<option value="${opt.value}" ${opt.value === value ? 'selected' : ''}>${opt.label}</option>`).join('')}</select>`;
      } else {
        // Different validation for different mail fields
        let validationAttrs = '';
        let fieldType = 'email';
        let placeholder = 'user@example.com';
        
        if (key === 'CFG_MAIL_HOST') {
          fieldType = 'text';
          placeholder = 'mail.domain.com';
          validationAttrs = `onchange="window.configManager.validateHostnameFormat(this, true)" oninput="window.configManager.validateHostnameFormat(this, true)" onblur="window.configManager.validateHostnameFormat(this, true)"`;
        } else if (key === 'CFG_MAIL_PORT') {
          fieldType = 'number';
          placeholder = '587';
          validationAttrs = `onchange="window.configManager.validatePortNumber(this, true)" oninput="window.configManager.validatePortNumber(this, true)" onblur="window.configManager.validatePortNumber(this, true)"`;
        } else if (key === 'CFG_MAIL_USERNAME' || key === 'CFG_MAIL_FROM') {
          validationAttrs = `onchange="window.configManager.validateEmailFormat(this, true)" oninput="window.configManager.validateEmailFormat(this, true)" onblur="window.configManager.validateEmailFormat(this, true)"`;
        } else {
          validationAttrs = `onchange="window.configManager.validateEmailFormat(this, true)" oninput="window.configManager.validateEmailFormat(this, true)" onblur="window.configManager.validateEmailFormat(this, true)"`;
        }
        
        fieldHTML += `
          <input type="${fieldType}" id="${fieldId}" name="${key}" value="${value}" class="form-control" placeholder="${placeholder}" ${validationAttrs}>
        `;
      }
    } else if (key.includes('URL') || key.includes('LINK') || key.includes('HOST') || key.startsWith('CFG_DOMAIN_')) {
      const placeholder = key.startsWith('CFG_DOMAIN_') ? 'example.com' : 'https://example.com';
      fieldHTML += `
        <input type="url" id="${fieldId}" name="${key}" value="${value}" class="form-control" placeholder="${placeholder}">
      `;
    } else if (/^CFG_BACKUP(_LOC_[0-9]+)?_KEEP_(LAST|DAILY|WEEKLY|MONTHLY|YEARLY)$/.test(key)) {
      const unitLabel = key.endsWith('_KEEP_LAST') ? 'snapshots' :
                        key.endsWith('_KEEP_DAILY') ? 'days' :
                        key.endsWith('_KEEP_WEEKLY') ? 'weeks' :
                        key.endsWith('_KEEP_MONTHLY') ? 'months' : 'years';
      fieldHTML += `
        <div class="input-group">
          <input type="number" id="${fieldId}" name="${key}" value="${value}" class="form-control" min="0" max="9999">
          <span class="input-group-text">${unitLabel}</span>
        </div>
      `;
    } else if (key === 'CFG_BACKUP_VERIFY_DATA_PERCENT') {
      fieldHTML += `
        <div class="input-group">
          <input type="number" id="${fieldId}" name="${key}" value="${value}" class="form-control" min="1" max="100" placeholder="5">
          <span class="input-group-text">%</span>
        </div>
      `;
    } else if (key === 'CFG_UPDATER_CHECK') {
      fieldHTML += `
        <div class="input-group">
          <input type="number" id="${fieldId}" name="${key}" value="${value}" class="form-control" min="1" max="600" placeholder="60">
          <span class="input-group-text">minutes</span>
        </div>
      `;
    } else if (key === 'CFG_GENERATED_PASS_LENGTH') {
      fieldHTML += `
        <div class="input-group">
          <input type="number" id="${fieldId}" name="${key}" value="${value}" class="form-control" min="8" max="128" placeholder="26">
          <span class="input-group-text">characters</span>
        </div>
      `;
    } else if (key === 'CFG_WEBUI_LOG_STREAM_IDLE_TIMEOUT_MINUTES') {
      fieldHTML += `
        <div class="input-group">
          <input type="number" id="${fieldId}" name="${key}" value="${value}" class="form-control" min="0" max="1440" placeholder="10">
          <span class="input-group-text">minutes</span>
        </div>
      `;
    } else if (key === 'CFG_WEBUI_LOG_STREAM_MAX_DURATION_MINUTES') {
      fieldHTML += `
        <div class="input-group">
          <input type="number" id="${fieldId}" name="${key}" value="${value}" class="form-control" min="0" max="1440" placeholder="60">
          <span class="input-group-text">minutes</span>
        </div>
      `;
    } else if (key === 'CFG_WEBUI_LOG_STREAM_MAX_LINES_PER_SEC') {
      fieldHTML += `
        <div class="input-group">
          <input type="number" id="${fieldId}" name="${key}" value="${value}" class="form-control" min="1" max="10000" placeholder="200">
          <span class="input-group-text">lines</span>
        </div>
      `;
    } else if (key === 'CFG_SWAPFILE_SIZE') {
      // Extract numeric value from "2G" format
      let numericValue = value.replace(/[^0-9.]/g, '');
      fieldHTML += `
        <div class="input-group">
          <input type="number" id="${fieldId}" name="${key}" value="${numericValue}" class="form-control" min="0" max="" placeholder="2">
          <span class="input-group-text">GB</span>
        </div>
      `;
    } else if (key.includes('SIZE') || key.includes('LENGTH') || key.includes('CHECK') || key.includes('MTU') || key.includes('PORT')) {
      let min = '';
      let max = '';
      
      if (key.includes('PORT')) {
        min = '1';
        max = '65535';
      } else if (key.includes('SIZE') || key.includes('LENGTH')) {
        min = '0';
        max = key.includes('PASS_LENGTH') ? '128' : '';
      }
      
      fieldHTML += `
        <input type="number" id="${fieldId}" name="${key}" value="${value}" class="form-control" min="${min}" max="${max}">
      `;
    } else if (key.includes('TIMEZONE')) {
      // Special handling for Timezone - create comprehensive timezone dropdown
      const timezoneOptions = ConfigOptions.getTimezoneOptions();
      //console.log('Timezone key:', key, 'Current value:', value, 'Type:', typeof value);
      //console.log('Available timezone options:', timezoneOptions.map(opt => ({value: opt.value, label: opt.label})));
      fieldHTML += `
        <select id="${fieldId}" name="${key}" class="form-control">
          ${timezoneOptions.map(opt => `<option value="${opt.value}" ${opt.value === value ? 'selected' : ''}>${opt.label}</option>`).join('')}
        </select>
      `;
      //console.log('Generated timezone dropdown HTML for', key, 'with value', value);
    } else if (key === 'CFG_INSTALL_MODE') {
      const selectOptions = ConfigOptions.getSelectOptions(key);
      fieldHTML += `<select id="${fieldId}" name="${key}" class="form-control" onchange="handleInstallModeChange(this)">${selectOptions.map(opt => `<option value="${opt.value}" ${opt.value === value ? 'selected' : ''}>${opt.label}</option>`).join('')}</select>`;
    } else if (/^CFG_BACKUP_LOC_[0-9]+_TYPE$/.test(key)) {
      const selectOptions = ConfigOptions.getSelectOptions(key);
      fieldHTML += `<select id="${fieldId}" name="${key}" class="form-control">${selectOptions.map(opt => `<option value="${opt.value}" ${opt.value === value ? 'selected' : ''}>${opt.label}</option>`).join('')}</select>`;
    } else if (ConfigOptions.isDropdownKey(key) || (options && Object.keys(options).length > 0)) {
      //console.log('=== GENERIC DROPDOWN BLOCK ENTERED for key:', key);
      //console.log('Dropdown detected for key:', key);
      //console.log('isDropdownKey result:', ConfigOptions.isDropdownKey(key));
      //console.log('options available:', options);
      const selectOptions = (options && typeof options === 'string') ? this.parseOptions(options) : ConfigOptions.getSelectOptions(key);
      //console.log('selectOptions:', selectOptions);
      fieldHTML += `
        <select id="${fieldId}" name="${key}" class="form-control">
          ${selectOptions.map(opt => `<option value="${opt.value}" ${opt.value === value ? 'selected' : ''}>${opt.label}</option>`).join('')}
        </select>
      `;
      //console.log('Generated dropdown for', key, 'with value', value);
    } else if (key.includes('DESCRIPTION') || key.includes('COMMENTS') || key.includes('NOTES')) {
      //console.log('Textarea detected for key:', key);
      fieldHTML += `
        <textarea id="${fieldId}" name="${key}" class="form-control" rows="4">${value}</textarea>
      `;
    } else {
      //console.log('Default text input for key:', key);
      // Default text input with event handlers and options
      const inputClass = className ? `form-control ${className}` : 'form-control';
      const inputPlaceholder = placeholder || '';
      const eventHandlers = [];
      if (onchange) eventHandlers.push(`onchange="${onchange}"`);
      if (oninput) eventHandlers.push(`oninput="${oninput}"`);
      if (onblur) eventHandlers.push(`onblur="${onblur}"`);
      const eventAttrs = eventHandlers.length > 0 ? ` ${eventHandlers.join(' ')}` : '';
      
      fieldHTML += `
        <input type="text" id="${fieldId}" name="${key}" value="${value}" class="${inputClass}" placeholder="${inputPlaceholder}"${eventAttrs}>
      `;
    }
    
    fieldHTML += `
      </div>
    `;
    
    return fieldHTML;
  }

  // Create master toggle for section enabling/disabling
  static createMasterToggle(sectionId, masterKey, isEnabled, title, description) {
    return `
      <div class="master-toggle">
        <div class="field-group">
          <label class="checkbox-label">
            <input type="checkbox" id="config-${masterKey}" name="${masterKey}" value="true" ${isEnabled ? 'checked' : ''} onchange="ConfigShared.toggleSection('${sectionId}', this.checked)">
            <span class="checkbox-custom"></span>
            <span class="checkbox-text">
              ${title}
              ${description ? `<span class="tooltip" title="${description}">ℹ️</span>` : ''}
            </span>
          </label>
        </div>
      </div>
    `;
  }

  // Create section content wrapper
  static createSectionContent(sectionId, isEnabled) {
    return `
      <div id="section-content-${sectionId}" class="section-content ${isEnabled ? '' : 'disabled'}">
    `;
  }

  // Toggle section fields (modular function)
  static toggleSection(sectionId, isEnabled) {
    const sectionContent = document.getElementById(`section-content-${sectionId}`);
    
    if (!sectionContent) {
      console.warn(`Section content not found: ${sectionId}`);
      return;
    }

    const fields = sectionContent.querySelectorAll('input, select, textarea');
    
    if (isEnabled) {
      // Enable section
      sectionContent.classList.remove('disabled');
      fields.forEach(field => {
        field.disabled = false;
        const fieldGroup = field.closest('.field-group');
        if (fieldGroup) {
          fieldGroup.style.opacity = '1';
          fieldGroup.style.pointerEvents = 'auto';
        }
      });
      //console.log(`Section ${sectionId} enabled`);
    } else {
      // Disable section
      sectionContent.classList.add('disabled');
      fields.forEach(field => {
        field.disabled = true;
        const fieldGroup = field.closest('.field-group');
        if (fieldGroup) {
          fieldGroup.style.opacity = '0.6';
          fieldGroup.style.pointerEvents = 'none';
        }
      });
      //console.log(`Section ${sectionId} disabled`);
    }
  }

  // Toggle section visibility (hide/show entire section)
  static toggleSectionVisibility(sectionId, isEnabled) {
    const sectionContent = document.getElementById(sectionId);
    
    if (!sectionContent) {
      console.warn(`Section content not found: ${sectionId}`);
      return;
    }

    if (isEnabled) {
      // Show section
      sectionContent.classList.remove('hidden');
      //console.log(`Section ${sectionId} shown`);
    } else {
      // Hide section
      sectionContent.classList.add('hidden');
      //console.log(`Section ${sectionId} hidden`);
    }
  }

  // Initialize section toggles on page load
  static initializeSectionToggles() {
    // Find all master toggles and initialize their sections
    document.querySelectorAll('[id^="config-CFG_"][onchange*="toggleSection"]').forEach(toggle => {
      // Extract section ID from the onchange attribute
      const onchangeAttr = toggle.getAttribute('onchange');
      const match = onchangeAttr.match(/toggleSection\('([^']+)'/);
      if (match) {
        const sectionId = match[1];
        const isEnabled = toggle.checked;
        this.toggleSection(sectionId, isEnabled);
      }
    });
  }

  // Git section toggle function (moved from global scope)
  static toggleGitSectionFields(isEnabled) {
    // If no parameter provided, get the state from the checkbox
    if (typeof isEnabled === 'undefined') {
      const gitLoginCheckbox = document.getElementById('git-login-toggle');
      isEnabled = gitLoginCheckbox ? gitLoginCheckbox.checked : false;
    }
    
    const gitSectionContent = document.getElementById('git-section-content');
    const gitFields = gitSectionContent?.querySelectorAll('.config-fields input, .config-fields select, .config-fields textarea');
    
    if (gitSectionContent && gitFields) {
      if (isEnabled) {
        gitSectionContent.classList.remove('hidden');
        gitFields.forEach(field => {
          field.disabled = false;
          const fieldGroup = field?.closest('.field-group');
          if (fieldGroup) {
            fieldGroup.style.opacity = '1';
            fieldGroup.style.pointerEvents = 'auto';
          }
        });
      } else {
        gitSectionContent.classList.add('hidden');
        gitFields.forEach(field => {
          field.disabled = true;
          const fieldGroup = field?.closest('.field-group');
          if (fieldGroup) {
            fieldGroup.style.opacity = '0.5';
            fieldGroup.style.pointerEvents = 'none';
          }
        });
      }
    }
    
    // Force re-initialization of form to ensure proper state
    setTimeout(() => {
      const form = document.getElementById('config-form');
      if (form) {
        // Trigger a change event to update any dependent fields
        const event = new Event('change', { bubbles: true });
        gitSectionContent?.dispatchEvent(event);
      }
    }, 100);
  }

  // Universal toggle function for all _ENABLED options
  static toggleSection(sectionId, isEnabled) {
    //console.log('=== UNIVERSAL TOGGLE DEBUG ===');
    //console.log('sectionId:', sectionId);
    //console.log('isEnabled:', isEnabled);
    
    const sectionContent = document.getElementById(sectionId);
    const fields = sectionContent?.querySelectorAll('.config-fields input, .config-fields select, .config-fields textarea');
    
    //console.log('sectionContent found:', !!sectionContent);
    //console.log('fields found:', fields ? fields.length : 0);
    
    if (sectionContent && fields) {
      if (isEnabled) {
        //console.log('Enabling section...');
        sectionContent.classList.remove('hidden');
        fields.forEach((field, index) => {
          //console.log(`Enabling field ${index}:`, field);
          field.disabled = false;
          const fieldGroup = field?.closest('.field-group');
          if (fieldGroup) {
            fieldGroup.style.opacity = '1';
            fieldGroup.style.pointerEvents = 'auto';
          }
        });
      } else {
        //console.log('Disabling section...');
        sectionContent.classList.add('hidden');
        fields.forEach((field, index) => {
          //console.log(`Disabling field ${index}:`, field);
          field.disabled = true;
          const fieldGroup = field?.closest('.field-group');
          if (fieldGroup) {
            fieldGroup.style.opacity = '0.5';
            fieldGroup.style.pointerEvents = 'none';
          }
        });
      }
    }
    
    //console.log('=== UNIVERSAL TOGGLE DEBUG END ===');
  }

  // Remote backup section toggle function
  static toggleMailSection(sectionId, isEnabled) {
    //console.log('=== TOGGLE MAIL SECTION DEBUG ===');
    //console.log('sectionId:', sectionId);
    //console.log('isEnabled:', isEnabled);
    
    alert('toggleMailSection called: ' + sectionId + ', enabled: ' + isEnabled);
    
    //console.log('Looking for sectionContent...');
    const sectionContent = document.getElementById(sectionId);
    //console.log('sectionContent found:', !!sectionContent);
    
    //console.log('Looking for mailFields...');
    const mailFields = sectionContent?.querySelectorAll('.config-fields input, .config-fields select, .config-fields textarea');
    //console.log('mailFields found:', mailFields ? mailFields.length : 0);
    
    if (sectionContent && mailFields) {
      //console.log('Enabling mail section...');
      if (isEnabled) {
        //console.log('Removing hidden class...');
        sectionContent.classList.remove('hidden');
        //console.log('Enabling fields...');
        mailFields.forEach((field, index) => {
          //console.log(`Disabling field ${index}:`, field);
          field.disabled = false;
          const fieldGroup = field?.closest('.field-group');
          if (fieldGroup) {
            //console.log('Enabling field group...');
            fieldGroup.style.opacity = '1';
            fieldGroup.style.pointerEvents = 'auto';
          }
        });
      } else {
        //console.log('Disabling mail section...');
        sectionContent.classList.add('hidden');
        //console.log('Disabling fields...');
        mailFields.forEach((field, index) => {
          //console.log(`Enabling field ${index}:`, field);
          field.disabled = true;
          const fieldGroup = field?.closest('.field-group');
          if (fieldGroup) {
            //console.log('Disabling field group...');
            fieldGroup.style.opacity = '0.5';
            fieldGroup.style.pointerEvents = 'none';
          }
        });
      }
    }
    
    //console.log('=== TOGGLE MAIL SECTION DEBUG END ===');
  }

  static toggleRemoteBackupSection(sectionId, isEnabled) {
    const sectionContent = document.getElementById(sectionId);
    const backupFields = sectionContent?.querySelectorAll('.config-fields input, .config-fields select, .config-fields textarea');
    
    if (sectionContent && backupFields) {
      if (isEnabled) {
        sectionContent.classList.remove('hidden');
        backupFields.forEach(field => {
          field.disabled = false;
          const fieldGroup = field?.closest('.field-group');
          if (fieldGroup) {
            fieldGroup.style.opacity = '1';
            fieldGroup.style.pointerEvents = 'auto';
          }
        });
      } else {
        sectionContent.classList.add('hidden');
        backupFields.forEach(field => {
          field.disabled = true;
          const fieldGroup = field?.closest('.field-group');
          if (fieldGroup) {
            fieldGroup.style.opacity = '0.5';
            fieldGroup.style.pointerEvents = 'none';
          }
        });
      }
    }
    
    // Force re-initialization of form to ensure proper state
    setTimeout(() => {
      const form = document.getElementById('config-form');
      if (form) {
        // Trigger a change event to update any dependent fields
        const event = new Event('change', { bubbles: true });
        sectionContent?.dispatchEvent(event);
      }
    }, 100);
  }

  // Git section toggle function
  static toggleGitSection(sectionId, isEnabled) {
    const sectionContent = document.getElementById(sectionId);
    const gitFields = sectionContent?.querySelectorAll('.config-fields input, .config-fields select, .config-fields textarea');
    
    if (sectionContent && gitFields) {
      if (isEnabled) {
        sectionContent.classList.remove('hidden');
        gitFields.forEach(field => {
          field.disabled = false;
          const fieldGroup = field?.closest('.field-group');
          if (fieldGroup) {
            fieldGroup.style.opacity = '1';
            fieldGroup.style.pointerEvents = 'auto';
          }
        });
      } else {
        sectionContent.classList.add('hidden');
        gitFields.forEach(field => {
          field.disabled = true;
          const fieldGroup = field?.closest('.field-group');
          if (fieldGroup) {
            fieldGroup.style.opacity = '0.5';
            fieldGroup.style.pointerEvents = 'none';
          }
        });
      }
    }
    
    // Force re-initialization of form to ensure proper state
    setTimeout(() => {
      const form = document.getElementById('config-form');
      if (form) {
        // Trigger a change event to update any dependent fields
        const event = new Event('change', { bubbles: true });
        sectionContent?.dispatchEvent(event);
      }
    }, 100);
  }

  // Parse options string into array of {value, label} objects
  static parseOptions(options) {
    if (!options || typeof options !== 'string') {
      return [];
    }
    
    return options.split('|').map(opt => {
      const parts = opt.split('=');
      if (parts.length === 2) {
        return { value: parts[0].trim(), label: parts[1].trim() };
      }
      return { value: opt.trim(), label: opt.trim() };
    });
  }

  // Generate fields for category with 3-per-line layout and smart field detection
  static generateFieldsForCategory(keys, category, config, generateFieldCallback = null) {
    let formHTML = '<div class="domains-divider"></div><div class="config-fields">';
    
    keys.forEach((key, index) => {
      const configItem = config[key] || {};
      const value = configItem.value || '';
      const title = configItem.title || this.formatConfigLabel(key);
      const description = configItem.description || '';
      const options = configItem.options || '';
      const fieldId = `config-${key}`;
      
      // Add line break every 3 items
      if (index > 0 && index % 3 === 0) {
        formHTML += `</div><div class="config-fields">`;
      }
      
      // Use smart field creation if no callback provided, otherwise use callback
      if (generateFieldCallback) {
        formHTML += generateFieldCallback(fieldId, key, value, title, description, options, config);
      } else {
        formHTML += this.createSmartField(fieldId, key, value, title, description, {
          selectOptions: options,
          category: category,
          layout: 'inline',
          config: config
        });
      }
    });
    
    formHTML += `</div>`;
    return formHTML;
  }

  // Generate fields for category WITHOUT the leading divider (for master toggle sections)
  static generateFieldsForCategoryNoDivider(keys, category, config, generateFieldCallback = null) {
    let formHTML = '';
    
    keys.forEach((key, index) => {
      const configItem = config[key] || {};
      const value = configItem.value || '';
      const title = configItem.title || this.formatConfigLabel(key);
      const description = configItem.description || '';
      const options = configItem.options || '';
      const fieldId = `config-${key}`;
      
      let fieldHTML;
      if (generateFieldCallback) {
        fieldHTML = generateFieldCallback(fieldId, key, value, title, description, options, config);
      } else {
        fieldHTML = this.generateField(fieldId, key, value, title, description, options, config);
      }
      
      formHTML += fieldHTML;
    });
    
    return formHTML;
  }

  // Separate categories into regular, advanced, and unused
  static categorizeConfigs(config) {
    const groupedConfigs = this.groupConfigKeys(config);
    const categoryOrder = this.extractCategoryOrder(config);
    
    const regularCategories = [];
    const advancedCategories = [];
    const unusedCategories = [];
    
    for (const category of categoryOrder) {
      const keys = groupedConfigs[category];
      
      if (keys && keys.length > 0 && category !== 'Hidden/Unused Options') {
        // Check if category has advanced items
        const hasAdvanced = keys.some(key => {
          const configItem = config[key] || {};
          return configItem.advanced === true;
        });
        
        // Check if category has unused items
        const hasUnused = keys.some(key => {
          const configItem = config[key] || {};
          return configItem.unused === true;
        });
        
        // Categorize based on the presence of advanced/unused flags
        if (hasUnused) {
          unusedCategories.push(category);
        } else if (hasAdvanced) {
          advancedCategories.push(category);
        } else {
          regularCategories.push(category);
        }
      }
    }
    
    return {
      groupedConfigs,
      categoryOrder,
      regularCategories,
      advancedCategories,
      unusedCategories
    };
  }

  // Generate warning notice for requirements page
  static generateRequirementsWarning() {
    return `
      <div class="requirements-warning-section">
        <div class="requirements-warning-header">
          <h3>⚠️ System Requirements Warning</h3>
          <p>Disabling any of the following system requirements may break LibrePortal functionality. Always create a backup before making changes.</p>
        </div>
      </div>
    `;
  }

  // Generate toggle controls HTML for advanced/unused sections
  static generateToggleControls(hasAdvanced = false, hasUnused = false) {
    if (!hasAdvanced && !hasUnused) {
      return ''; // Don't show danger zone if no content
    }
    
    let formHTML = `
      <div class="danger-zone-section">
        <div class="danger-zone-header">
          <h3>⚠️ Danger Zone</h3>
          <p>These options are for advanced users and may affect system stability</p>
        </div>
        
        <div class="config-toggles">
    `;
    
    if (hasAdvanced) {
      formHTML += `
          <div class="toggle-section">
            <label class="checkbox-label">
              <input type="checkbox" id="show-advanced" onchange="ConfigShared.toggleAdvancedSections()">
              <span class="checkbox-custom"></span>
              <div class="toggle-content">
                <span class="checkbox-text">Show Advanced Options</span>
                <span class="checkbox-description">Display advanced configuration settings for experienced users</span>
              </div>
            </label>
          </div>
      `;
    }
    
    if (hasUnused) {
      formHTML += `
          <div class="toggle-section">
            <label class="checkbox-label">
              <input type="checkbox" id="show-unused" onchange="ConfigShared.toggleUnusedSections()">
              <span class="checkbox-custom"></span>
              <div class="toggle-content">
                <span class="checkbox-text">Show Unused Options</span>
                <span class="checkbox-description">Display deprecated or unused configuration options</span>
              </div>
            </label>
          </div>
      `;
    }
    
    formHTML += `
        </div>
      </div>
    `;
    
    return formHTML;
  }

  // Generate advanced sections HTML
  static async generateAdvancedSections(advancedCategories, groupedConfigs, config, getCategoryDescriptionCallback) {
    if (advancedCategories.length === 0) {
      return '';
    }
    
    let formHTML = `
      <div id="advanced-sections" class="advanced-sections" style="display: none;">
        <div class="section-divider">
          <h3>🛠️ Advanced Configuration</h3>
          <p>Advanced settings for experienced users</p>
        </div>
    `;
    
    for (const category of advancedCategories) {
      const keys = groupedConfigs[category];
      
      if (keys && keys.length > 0) {
        const displayCategory = this.formatCategoryName(category);
        const categoryDescription = getCategoryDescriptionCallback ? await getCategoryDescriptionCallback(category) : '';
        
        // Check if this category has a master toggle (any key with master: true)
        const masterKey = keys.find(key => {
          const configItem = config[key] || {};
          return configItem.master === true;
        });
        
        if (masterKey) {
          // Dynamic master toggle handling for advanced sections
          const masterValue = config[masterKey]?.value || 'false';
          const isMasterEnabled = masterValue === 'true';
          const masterTitle = config[masterKey]?.title || this.formatConfigLabel(masterKey);
          const masterDescription = config[masterKey]?.description || '';
          const sectionId = `${category.toLowerCase().replace(/[^a-z0-9]/g, '-')}`;
          const toggleId = `${masterKey.toLowerCase()}-toggle`;
          
          formHTML += `
            <div class="config-section advanced-section">
              <h3>${displayCategory}</h3>
              <p class="category-description">${categoryDescription}</p>
              <div class="domains-divider"></div>
              <div class="git-master-toggle">
                <div class="field-group">
                  <label class="checkbox-label master-toggle">
                    <input type="checkbox" id="${toggleId}" name="${masterKey}" value="true" ${isMasterEnabled ? 'checked' : ''} onchange="ConfigShared.toggleSectionVisibility('section-content-${sectionId}', this.checked)">
                    <span class="checkbox-custom"></span>
                    <span class="checkbox-text">
                      ${masterTitle}
                      <span class="tooltip" title="${masterDescription}">ℹ️</span>
                    </span>
                  </label>
                </div>
              </div>
              <div id="section-content-${sectionId}" class="git-section-content ${isMasterEnabled ? '' : 'hidden'}">
                <div class="config-fields">
                  ${this.generateFieldsForCategoryNoDivider(keys.filter(key => key !== masterKey), category, config)}
                </div>
              </div>
            </div>
          `;
        } else {
          // Regular advanced section handling (no master toggle)
          formHTML += `
            <div class="config-section advanced-section">
              <h3>${displayCategory}</h3>
              <p class="category-description">${categoryDescription}</p>
              <div class="config-group">
                ${this.generateFieldsForCategory(keys, category, config)}
              </div>
            </div>
          `;
        }
      }
    }
    
    formHTML += `</div>`;
    return formHTML;
  }

  // Generate unused sections HTML
  static async generateUnusedSections(unusedCategories, groupedConfigs, config, getCategoryDescriptionCallback) {
    if (unusedCategories.length === 0) {
      return '';
    }
    
    let formHTML = `
      <div id="unused-sections" class="unused-sections" style="display: none;">
        <div class="section-divider">
          <h3>🗑️ Unused Configuration</h3>
          <p>Deprecated or unused configuration options</p>
        </div>
    `;
    
    for (const category of unusedCategories) {
      const keys = groupedConfigs[category];
      
      if (keys && keys.length > 0) {
        const displayCategory = this.formatCategoryName(category);
        const categoryDescription = getCategoryDescriptionCallback ? await getCategoryDescriptionCallback(category) : '';
        
        // Check if this category has a master toggle (any key with master: true)
        const masterKey = keys.find(key => {
          const configItem = config[key] || {};
          return configItem.master === true;
        });
        
        if (masterKey) {
          // Dynamic master toggle handling for unused sections
          const masterValue = config[masterKey]?.value || 'false';
          const isMasterEnabled = masterValue === 'true';
          const masterTitle = config[masterKey]?.title || this.formatConfigLabel(masterKey);
          const masterDescription = config[masterKey]?.description || '';
          const sectionId = `${category.toLowerCase().replace(/[^a-z0-9]/g, '-')}`;
          const toggleId = `${masterKey.toLowerCase()}-toggle`;
          
          formHTML += `
            <div class="config-section unused-section">
              <h3>${displayCategory}</h3>
              <p class="category-description">${categoryDescription}</p>
              <div class="domains-divider"></div>
              <div class="git-master-toggle">
                <div class="field-group">
                  <label class="checkbox-label master-toggle">
                    <input type="checkbox" id="${toggleId}" name="${masterKey}" value="true" ${isMasterEnabled ? 'checked' : ''} onchange="ConfigShared.toggleSectionVisibility('section-content-${sectionId}', this.checked)">
                    <span class="checkbox-custom"></span>
                    <span class="checkbox-text">
                      ${masterTitle}
                      <span class="tooltip" title="${masterDescription}">ℹ️</span>
                    </span>
                  </label>
                </div>
              </div>
              <div id="section-content-${sectionId}" class="git-section-content ${isMasterEnabled ? '' : 'hidden'}">
                <div class="config-fields">
                  ${this.generateFieldsForCategoryNoDivider(keys.filter(key => key !== masterKey), category, config)}
                </div>
              </div>
            </div>
          `;
        } else {
          // Regular unused section handling (no master toggle)
          formHTML += `
            <div class="config-section unused-section">
              <h3>${displayCategory}</h3>
              <p class="category-description">${categoryDescription}</p>
              <div class="config-group">
                ${this.generateFieldsForCategory(keys, category, config)}
              </div>
            </div>
          `;
        }
      }
    }
    
    formHTML += `</div>`;
    return formHTML;
  }

  // Toggle advanced sections visibility
  static toggleAdvancedSections() {
    const checkbox = document.getElementById('show-advanced');
    const advancedSections = document.getElementById('advanced-sections');
    
    if (advancedSections) {
      advancedSections.style.display = checkbox.checked ? 'block' : 'none';
    }
  }

  // Toggle unused sections visibility
  static toggleUnusedSections() {
    const checkbox = document.getElementById('show-unused');
    const unusedSections = document.getElementById('unused-sections');
    
    if (unusedSections) {
      unusedSections.style.display = checkbox.checked ? 'block' : 'none';
    }
  }
}

// Export for global access
window.ConfigShared = ConfigShared;

// Global toggle change function for checkbox handling
window.handleToggleChange = function(checkbox, key) {
  //console.log(`Toggle changed: ${key} = ${checkbox.checked}`);
  // This function can be extended to handle specific toggle logic
  // For now, it just logs change
};

// Global flag to prevent multiple config reloads
window.isReloadingConfig = false;

// Global function to handle CFG_INSTALL_MODE change
window.handleInstallModeChange = function(selectElement) {
  // Prevent multiple simultaneous reloads
  if (window.isReloadingConfig) {
    //console.log('Config reload already in progress, ignoring...');
    return;
  }
  
  const installMode = selectElement.value;
  //console.log(`Install mode changed to: ${installMode}`);
  
  // Set flag to prevent multiple reloads
  window.isReloadingConfig = true;
  
  // Use a longer delay and onchange instead of onblur to avoid the loop
  setTimeout(() => {
    if (window.configManager) {
      // Clear cache to ensure we get fresh data with updated CFG_INSTALL_MODE
      window.configManager.cache.clear();
      //console.log('Cache cleared for fresh config data');
      
      // Get the current category from the URL or default to 'general'
      const currentCategory = window.configCategory || 'general';
      //console.log(`Reloading config category: ${currentCategory}`);
      window.configManager.renderConfig(currentCategory).finally(() => {
        // Clear the flag after reload is complete
        setTimeout(() => {
          window.isReloadingConfig = false;
        }, 500); // Extra delay to ensure DOM is fully settled
      });
    } else if (window.configRouter) {
      // Fallback to configRouter if configManager is not available
      const currentCategory = window.configCategory || 'general';
      //console.log(`Using configRouter to reload: ${currentCategory}`);
      window.configRouter.loadConfigComponentManual(currentCategory).finally(() => {
        // Clear the flag after reload is complete
        setTimeout(() => {
          window.isReloadingConfig = false;
        }, 500); // Extra delay to ensure DOM is fully settled
      });
    } else {
      console.warn('Neither configManager nor configRouter available for install mode change');
      window.isReloadingConfig = false;
    }
  }, 500); // Longer delay to avoid conflicts
};

// Global function to initialize git field visibility based on current CFG_INSTALL_MODE
window.initializeGitFieldVisibility = function() {
  const installModeSelect = document.querySelector('select[name="CFG_INSTALL_MODE"]');
  if (installModeSelect) {
    // Trigger the change handler to set initial visibility
    handleInstallModeChange(installModeSelect);
  }
};

// Global password toggle function for onclick handlers
window.togglePasswordVisibility = function(fieldId) {
  ConfigShared.togglePasswordVisibility(fieldId);
};
