// Config Manager - Main orchestrator for modular config system
if (typeof window.ConfigManager === 'undefined') {
  //console.log('ConfigManager: Defining new ConfigManager class...');
  
  class ConfigManager {
    constructor() {
      this.core = new ConfigCore();
      this.domainManager = new DomainManager();
      this.whitelistManager = new IPWhitelistManager();
      this.renderer = new ConfigRenderer();
      this.sidebar = new ConfigSidebar();
      this.form = new ConfigForm();
      this.utils = new ConfigUtils();
      
      // Expose IPWhitelistManager globally for wrapper functions
      window.IPWhitelistManager = this.whitelistManager;
    }

    async renderConfig(category) {
      //console.log('ConfigManager: Rendering ' + category + ' config...');
      
      const configSection = document.getElementById('config-section');
      if (!configSection) {
        console.error('ConfigManager: config-section element not found');
        return;
      }

      // The sidebar and page headers read window.configData. Load it up front so
      // populateSidebar() has categories on a cold admin visit (e.g. straight
      // from the dashboard); otherwise the overview/tools branches below render
      // an empty sidebar until something else populates configData. Cached after
      // the first call, so the config-category path below is a cache hit.
      try { await this.core.loadConfig(category); } catch (e) {}

      // Overview is the Admin landing — an ops/health board, not a config form.
      if (category === 'overview') {
        try { this.sidebar.populateSidebar(); } catch (e) {}
        if (typeof AdminOverview !== 'undefined') {
          window.adminOverview = new AdminOverview('config-section');
          await window.adminOverview.init();
        } else {
          configSection.innerHTML = '<div class="error">Admin overview failed to load.</div>';
        }
        return;
      }

      // SSH Access is an admin tool page that lives in this sidebar rather than
      // a config category — render its own controller into the main pane.
      if (category === 'ssh-access') {
        try { this.sidebar.populateSidebar(); } catch (e) {}
        if (typeof SshPage !== 'undefined') {
          window.sshPage = new SshPage('config-section');
          await window.sshPage.init();
        } else {
          configSection.innerHTML = '<div class="error">SSH Access page failed to load.</div>';
        }
        return;
      }

      // System is an admin tool page (live host + per-app statistics) with its
      // own controller, like SSH Access above.
      if (category === 'system') {
        try { this.sidebar.populateSidebar(); } catch (e) {}
        if (typeof AdminSystem !== 'undefined') {
          window.adminSystem = new AdminSystem('config-section');
          await window.adminSystem.init();
        } else {
          configSection.innerHTML = '<div class="error">System page failed to load.</div>';
        }
        return;
      }

      try {
        // Show loading state with enhanced box styling
        configSection.innerHTML = `
          <div class="loading-content" style="
            text-align: center; 
            padding: 60px 20px;
            background: var(--input-bg);
            border: 2px solid var(--border-color);
            border-radius: 12px;
            box-shadow: 0 4px 8px rgba(0,0,0,0.15);
            width: calc(100% - 40px);
            height: calc(100% - 40px);
            box-sizing: border-box;
            margin: 20px;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            min-height: 400px;
          ">
            <div class="loading-spinner" style="
              width: 24px; 
              height: 24px; 
              border: 3px solid rgba(52, 152, 219, 0.3); 
              border-top: 3px solid #3498db; 
              border-radius: 50%; 
              animation: spin 1s linear infinite; 
              margin: 0 auto 16px auto;
              display: inline-block;
            "></div>
            <div class="loading-message" style="
              font-size: 16px; 
              color: #ffffff; 
              font-weight: 500;
              margin-bottom: 8px;
            ">
              Loading configuration...
            </div>
            <div class="loading-subtitle" style="
              font-size: 14px; 
              color: rgba(255, 255, 255, 0.8); 
              font-style: italic;
            ">
              ${this.core.getRandomLoadingMessage()}
            </div>
          </div>
          <style>
            @keyframes spin {
              0% { transform: rotate(0deg); }
              100% { transform: rotate(360deg); }
            }
          </style>
        `;

        // Load configuration data
        const configData = await this.core.loadConfig(category);
        
        // Populate sidebar with categories
        this.sidebar.populateSidebar();
        
        if (Object.keys(configData).length === 0) {
          configSection.innerHTML = '<div class="no-config"><h3>No Configuration Available</h3><p>No configuration items found for this category.</p></div>';
          return;
        }

        // Render configuration sections
        var formHTML = '';
        var self = this; // Preserve 'this' context

        // Features page is system-level — add a Danger Zone header at the
        // top so it's visually obvious before the user touches anything.
        // Reuses the same `.danger-zone-section` / `.danger-zone-header`
        // styling used elsewhere, but without the advanced/unused toggle
        // tickboxes that live inside the normal danger zone — this is just
        // the heading.
        if (category === 'features') {
          formHTML += '<div class="danger-zone-section danger-zone-section--header-only"><div class="danger-zone-header"><h3>⚠️ Danger Zone</h3><p>These options are for advanced users and may affect system stability</p></div></div>';
          // Divider below the features Danger Zone banner, separating it from
          // the feature fields — same rule used elsewhere in the config form.
          formHTML += '<div class="config-divider"></div>';
        }
        
        //console.log('ConfigManager: About to process configData entries:', Object.keys(configData));
        
        // Filter subcategories by type
        const subcategoryTypes = this.utils.filterSubcategoriesByType(configData, category);
        
        // Render regular subcategories
        for (const subcategoryName of subcategoryTypes.regular) {
          const subcategoryData = configData[subcategoryName];
          //console.log('ConfigManager: Processing regular subcategory:', subcategoryName, 'data:', subcategoryData);
          
          if (typeof subcategoryData === 'object' && subcategoryData !== null) {
            //console.log('ConfigManager: Calling renderSubcategory for:', subcategoryName);
            formHTML += await self.renderSubcategory.call(self, category, subcategoryName, subcategoryData);
          }
        }
        
        // Render advanced and unused sections
        formHTML = await this.utils.renderSectionedContent(formHTML, subcategoryTypes.advanced, subcategoryTypes.unused, self, category, configData);

        //console.log('ConfigManager: Final formHTML length:', formHTML.length);

        if (formHTML) {
          // Page-level header for the config section. Mirrors the
          // .backup-page-header used on /backup so /config gets the same
          // prominent H1 + description above the form fields. Looked up from
          // window.configData.categories[category] so titles/descriptions
          // come straight from the .category metadata file.
          var catMeta = (window.configData && window.configData.categories && window.configData.categories[category]) || {};
          var catTitle = catMeta.title || (typeof ConfigShared !== 'undefined' && ConfigShared.formatCategoryName ? ConfigShared.formatCategoryName(category) : category);
          var catDesc = catMeta.description || '';
          var catIcon = catMeta.icon || category;
          var headerHTML =
            '<div class="page-header config-page-header">' +
              '<img class="page-header-icon" src="/icons/config/' + catIcon + '.svg" alt="" onerror="this.style.display=\'none\'">' +
              '<div class="page-header-title">' +
                '<div class="admin-breadcrumb">Config</div>' +
                '<h1>' + catTitle + '</h1>' +
                (catDesc ? '<p>' + catDesc + '</p>' : '') +
              '</div>' +
            '</div>';

          configSection.innerHTML = headerHTML + '<form id="config-form" class="config-form">' + formHTML + '<div class="config-divider"></div><div class="config-actions">' +
            '<button type="submit" class="btn btn-primary">' +
              '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
                '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>' +
                '<polyline points="7 10 12 15 17 10"></polyline>' +
                '<line x1="12" y1="15" x2="12" y2="3"></line>' +
              '</svg>' +
              'Save Configuration' +
            '</button>' +
            '<button type="button" class="btn btn-secondary" onclick="window.configManager.resetForm()">' +
              '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">' +
                '<polyline points="23 4 23 10 17 10"></polyline>' +
                '<path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path>' +
              '</svg>' +
              'Reset' +
            '</button>' +
          '</div></form>';
          // Wire the submit event so it dispatches the config-update task
          // instead of letting the browser fall back to a GET that dumps every
          // CFG value (including passwords) into the URL.
          if (this.form && typeof this.form.attachSubmitHandler === 'function') {
            this.form.attachSubmitHandler();
          }
        }

        //console.log('ConfigManager: Successfully rendered ' + category + ' config');
        
        // Force rediscover toggles to handle timing issues
        if (window.toggleManager && window.toggleManager.forceRediscover) {
          setTimeout(() => {
            window.toggleManager.forceRediscover();
          }, 200);
        }
        
      } catch (error) {
        console.error('ConfigManager: Error rendering ' + category + ' config: ', error);
        configSection.innerHTML = '<div class="error-container"><h3>Error Loading Configuration</h3><p>Failed to load configuration: ' + error.message + '</p><button type="button" class="btn btn-primary" onclick="window.configManager.renderConfig(\'' + category + '\')">Retry</button></div>';
      }
    }

    async renderSubcategory(category, subcategoryName, subcategoryData) {
      //console.log('ConfigManager: renderSubcategory() called - category: ' + category + ', subcategory: ' + subcategoryName);
      
      var displaySubcategory = this.utils.formatSubcategoryName(subcategoryName);
      // Strip the parent-category prefix from the display title so the user
      // sees "Basic" instead of "General Basic" while on the General page.
      if (typeof ConfigShared !== 'undefined' && ConfigShared.stripCategoryPrefix) {
        displaySubcategory = ConfigShared.stripCategoryPrefix(displaySubcategory, category);
      }
      var subcategoryDescription = this.utils.cleanDescription(subcategoryData.description || '');
      
      // The subcategoryData IS the config items, not a container for them
      var configItems = [];
      
      // Look for actual config items in the main config object
      if (window.configData && window.configData.config) {
        Object.entries(window.configData.config).forEach(function([configKey, configValue]) {
          if (configValue.subcategory === subcategoryName) {
            configItems.push({
              key: configKey,
              title: configValue.title,
              description: configValue.description,
              value: configValue.value,
              options: configValue.options,
              master: configValue.master,
              subcategory: configValue.subcategory
            });
          }
        });
      }
      
      //console.log('ConfigManager: Processing subcategory:', subcategoryName, 'data:', subcategoryData);
      //console.log('ConfigManager: configItems count: ' + configItems.length);
      //console.log('ConfigManager: All config items keys:', configItems.map(item => item.key));
      
      if (configItems.length === 0) {
        //console.log('ConfigManager: No config items, returning empty string');
        return '';
      }

      //console.log('ConfigManager: renderSubcategory called with:', {
        //category, 
        //subcategoryName, 
        //displaySubcategory, 
        //hasData: !!subcategoryData
      //});
      
      // Check for master toggle in this subcategory
      var masterKey = configItems.find(function(item) { return item.master === true; });
      //console.log('ConfigManager: masterKey found: ' + !!masterKey, masterKey ? masterKey.key : null);
      
      // Look for any ENABLED options and use universal toggle renderer
      var enabledKey = configItems.find(function(item) { 
        //console.log('Checking item for ENABLED:', item.key, item.key.includes('ENABLED'));
        return item.key.includes('ENABLED') || item.key === 'CFG_INSTALL_MODE'; 
      });
      //console.log('ConfigManager: enabledKey found: ' + !!enabledKey, enabledKey ? enabledKey.key : null);
      
      // Special handling for domains section
      var isDomains = subcategoryName.includes('domains') || subcategoryName.includes('network_domains');
      //console.log('ConfigManager: isDomains:', isDomains);
      
      // Special handling for IP whitelist section
      var isWhitelist = subcategoryName === 'network_whitelist' || subcategoryName.includes('whitelist');
      //console.log('ConfigManager: subcategoryName:', subcategoryName, 'isWhitelist:', isWhitelist);
      
      var resultHTML = '';
      
      if (isDomains) {
        //console.log('ConfigManager: Using domains renderer');
        // Render domains section with special handling
        resultHTML = await this.domainManager.renderDomainsSection(configItems, displaySubcategory, subcategoryDescription);
      } else if (isWhitelist) {
        //console.log('ConfigManager: Using whitelist renderer');
        resultHTML = await this.whitelistManager.renderWhitelistSection(configItems, displaySubcategory, subcategoryDescription);
      } else if (enabledKey) {
        //console.log('ConfigManager: Using universal toggle renderer');
        // Use universal toggle renderer for any ENABLED option or CFG_INSTALL_MODE
        resultHTML = window.toggleManager ? window.toggleManager.renderToggleSection(enabledKey, configItems, displaySubcategory, subcategoryDescription) : '';
      } else if (masterKey) {
        //console.log('ConfigManager: Using master toggle renderer');
        // Render with master toggle
        resultHTML = this.renderer.renderSubcategoryWithMaster(masterKey, configItems, displaySubcategory, subcategoryDescription);
      } else {
        //console.log('ConfigManager: Using regular renderer');
        // Render regular subcategory
        resultHTML = this.renderer.renderSubcategorySection(configItems, displaySubcategory, subcategoryDescription);
      }
      
      //console.log('ConfigManager: resultHTML length:', resultHTML.length);
      return resultHTML;
    }

    // Delegate form operations to ConfigForm
    resetForm() {
      return this.form.resetForm();
    }

    // Domain management methods
    addDomain() {
      return window.domainManager.addDomain();
    }

    deleteDomain(domainKey, buttonElement) {
      return window.domainManager.deleteDomain(domainKey, buttonElement);
    }

    async saveConfig() {
      return await this.form.saveConfig();
    }

    showNotification(message, type) {
      return this.form.showNotification(message, type);
    }
  }

  // Export to global scope
  window.ConfigManager = ConfigManager;
} else {
  //console.log('ConfigManager: Already exists, using existing instance');
}
