// Domain Management - Handles domain-related functionality
class DomainManager {
  constructor() {
    this.domains = [];
  }

  async checkTraefikInstallation() {
    try {
      const response = await fetch('/api/traefik/status');
      if (response.ok) {
        const data = await response.json();
        return data.installed || false;
      }
      return false;
    } catch (error) {
      //console.log('DomainManager: Traefik status check failed, assuming not installed:', error.message);
      return false;
    }
  }

  async renderDomainsSection(configItems, displaySubcategory, subcategoryDescription) {
    const traefikStatus = await this.checkTraefikInstallation();
    
    let html = `
      <div class="config-category">
        <div class="domains-wrapper">
          <div class="domains-header">
            <div>
              <h3>${displaySubcategory}</h3>
              <p class="category-description">${subcategoryDescription}</p>
            </div>
          </div>
          <div class="domains-divider"></div>
    `;
    
    if (!traefikStatus.installed) {
      html += `
        <div class="traefik-warning-banner">
          <div class="traefik-warning-content">
            <span class="traefik-warning-icon">⚠️</span>
            <div class="traefik-warning-text">
              <strong>Traefik Not Installed</strong> - Domain settings won't be applied until Traefik is installed. You can configure domains now and install Traefik later.
            </div>
          </div>
        </div>
      `;
    }
    
    html += `<div class="domain-building-blocks">`;
    
    // Only show domains that have content (non-empty values)
    const allDomainKeys = configItems.map(item => item.key).filter(key => key.startsWith('CFG_DOMAIN_'));
    const domainKeysWithContent = allDomainKeys.filter(key => {
      const configItem = configItems.find(item => item.key === key) || {};
      const value = configItem.value || '';
      return value.trim() !== '';
    });
    
    // Check if we've reached the maximum of 9 domains (count only existing domains, not empty slots)
    const isMaxDomains = domainKeysWithContent.length >= 9;
    
    domainKeysWithContent.forEach(key => {
      const configItem = configItems.find(item => item.key === key) || {};
      const value = configItem.value || '';
      const title = configItem.title || this.formatConfigLabel(key);
      const fieldId = `config-${key}`;
      
      // Extract domain number
      const domainNum = parseInt(key.match(/CFG_DOMAIN_(\d+)/)[1]);
      const isHighestDomain = domainNum === Math.max(...domainKeysWithContent.map(k => 
        parseInt(k.match(/CFG_DOMAIN_(\d+)/)[1])
      ));
      
      // Domain 1 can never be deleted, and only highest numbered domain WITH CONTENT can be deleted
      const canDelete = isHighestDomain && domainNum !== 1;
      
      html += `
        <div class="domain-building-block">
          <div class="domain-header">
            ${this.generateField(fieldId, key, value, title, '', {
              placeholder: 'example.com',
              className: 'domain-input'
            })}
            <button type="button" class="delete-domain-btn ${!canDelete ? 'disabled' : ''}"
                    onclick="window.deleteDomain('${key}', this)"
                    title="${canDelete ? 'Delete domain' : domainNum === 1 ? 'Domain 1 cannot be deleted' : 'Can only delete highest numbered domain'}"
                    ${!canDelete ? 'disabled' : ''}>
              <span class="delete-icon">×</span>
            </button>
          </div>
          <div class="setup-dns-status" data-dns-for="${fieldId}"></div>
        </div>
      `;
    });

    setTimeout(() => this.attachDnsChecks(), 0);
    
    html += `
      </div>
      <div class="domain-actions">
        <button type="button" id="add-domain-btn" class="btn ${isMaxDomains ? 'btn-secondary' : 'btn-primary'}" 
                onclick="window.addDomain()" 
                ${isMaxDomains ? 'disabled' : ''}>
          <span class="add-icon">${isMaxDomains ? '✓' : '+'}</span>
          ${isMaxDomains ? 'Maximum Domains Reached' : 'Add Domain'}
        </button>
      </div>
    </div>
    <div class="spacer spacer-lg"></div>
  </div>
    `;
    
    return html;
  }

  attachDnsChecks() {
    const inputs = document.querySelectorAll('input[id^="config-CFG_DOMAIN_"]');
    inputs.forEach((input) => {
      if (input.dataset.dnsBound === '1') return;
      input.dataset.dnsBound = '1';
      const status = document.querySelector(`[data-dns-for="${input.id}"]`);
      if (!status) return;
      let timer = null;
      let ctrl = null;
      const run = () => {
        if (timer) clearTimeout(timer);
        if (ctrl) ctrl.abort();
        const domain = input.value.trim().toLowerCase();
        if (!domain) { status.textContent = ''; status.className = 'setup-dns-status'; return; }
        if (!/^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(domain)) {
          status.textContent = ''; status.className = 'setup-dns-status';
          return;
        }
        status.textContent = 'Checking DNS…';
        status.className = 'setup-dns-status checking';
        timer = setTimeout(async () => {
          ctrl = new AbortController();
          try {
            const res = await fetch(`/api/setup/dns-check?domain=${encodeURIComponent(domain)}`, { signal: ctrl.signal });
            const data = await res.json();
            if (data.matches) {
              status.textContent = `✓ ${domain} → ${data.server_ip} (this server)`;
              status.className = 'setup-dns-status ok';
            } else {
              const detail = data.domain_ip
                ? `points to ${data.domain_ip}, this server is ${data.server_ip}`
                : `does not resolve (server: ${data.server_ip || 'unknown'})`;
              status.textContent = `⚠ ${domain} ${detail}. Traefik may not route this yet.`;
              status.className = 'setup-dns-status warn';
            }
          } catch (err) {
            if (err.name !== 'AbortError') {
              status.textContent = 'DNS check failed.';
              status.className = 'setup-dns-status warn';
            }
          }
        }, 500);
      };
      input.addEventListener('input', run);
      input.addEventListener('blur', run);
      if (input.value) run();
    });
  }

  generateField(fieldId, key, value, title, description, options = {}) {
    // Use the same field generation as ConfigShared
    if (typeof ConfigShared !== 'undefined') {
      return ConfigShared.generateField(fieldId, key, value, title, description, options);
    }
    
    // Fallback field generation
    const placeholder = key.startsWith('CFG_DOMAIN_') ? 'example.com' : 'https://example.com';
    return `
      <input type="url" id="${fieldId}" name="${key}" value="${value}" class="form-control" placeholder="${placeholder}">
    `;
  }

  formatConfigLabel(key) {
    // Special handling for domain configuration
    if (key.startsWith('CFG_DOMAIN_')) {
      const domainNum = key.replace('CFG_DOMAIN_', '');
      return `Domain ${domainNum}`;
    }
    
    // Use ConfigShared if available
    if (typeof ConfigShared !== 'undefined') {
      return ConfigShared.formatConfigLabel(key);
    }
    
    // Fallback formatting
    return key.replace(/^CFG_/, '').replace(/_/g, ' ').toLowerCase().replace(/\b\w/g, l => l.toUpperCase());
  }

  addNewDomain() {
    //console.log('Add Domain button clicked!');
    
    try {
      // Find the highest existing domain number
      const domainInputs = document.querySelectorAll('input[name^="CFG_DOMAIN_"]');
      const domainNumbers = [];
      
      domainInputs.forEach(input => {
        const match = input.name.match(/CFG_DOMAIN_(\d+)/);
        if (match) {
          domainNumbers.push(parseInt(match[1]));
        }
      });
      
      // Check if we've reached the maximum of 9 domains (count only existing domains, not empty slots)
      if (domainNumbers.length >= 9) {
        //console.log('Maximum of 9 domains reached');
        return;
      }
      
      const nextDomainNumber = domainNumbers.length > 0 ? Math.max(...domainNumbers) + 1 : 1;
      const newDomainKey = `CFG_DOMAIN_${nextDomainNumber}`;
      const newFieldId = `config-${newDomainKey}`;
      
      // Create new domain building block HTML
      const newDomainHTML = `
        <div class="domain-building-block">
          <div class="domain-header">
            ${this.generateField(newFieldId, newDomainKey, '', `Domain ${nextDomainNumber}`, '', { placeholder: 'example.com' })}
            <button type="button" class="delete-domain-btn"
                    onclick="window.configManager.deleteDomain('${newDomainKey}', this)">
              <span class="delete-icon">×</span>
            </button>
          </div>
          <div class="setup-dns-status" data-dns-for="${newFieldId}"></div>
        </div>
      `;
      
      // Find the domain-building-blocks container and add the new block
      const domainContainer = document.querySelector('.domain-building-blocks');
      if (domainContainer) {
        const tempDiv = document.createElement('div');
        tempDiv.innerHTML = newDomainHTML;
        const newBlock = tempDiv.firstElementChild;
        domainContainer.appendChild(newBlock);
        
        // Focus on the new input field
        const newInput = newBlock.querySelector('input');
        if (newInput) {
          newInput.focus();
        }
        
        // Update add domain button state
        this.updateDomainDeleteButtons();
        this.attachDnsChecks();
      }
    } catch (error) {
      console.error('Error adding new domain:', error);
    }
  }

  deleteDomain(domainKey, buttonElement) {
    if (typeof window.DomainManager === 'undefined' || !window.DomainManager.deleteDomain) {
      console.error('DomainManager not available for deleteDomain');
      return;
    }
    //console.log(`Delete domain button clicked for: ${domainKey}`);
    
    try {
      // Find the domain-building-block and remove it
      const domainBlock = buttonElement.closest('.domain-building-block');
      if (domainBlock) {
        // Clear the input value first
        const input = domainBlock.querySelector('input');
        if (input) {
          input.value = '';
        }
        // Remove the entire building block
        domainBlock.remove();
        
        // Update delete button states
        this.updateDomainDeleteButtons();
      }
    } catch (error) {
      console.error('Error deleting domain:', error);
    }
  }

  updateDomainDeleteButtons() {
    // Find all domain building blocks
    const allDomainBlocks = document.querySelectorAll('.domain-building-block');
    
    // Find all domain numbers from existing blocks
    const allDomainNumbers = [];
    allDomainBlocks.forEach(block => {
      const input = block.querySelector('input');
      if (input) {
        const inputName = input.name;
        const match = inputName.match(/CFG_DOMAIN_(\d+)/);
        if (match) {
          allDomainNumbers.push(parseInt(match[1]));
        }
      }
    });
    
    // Update delete button states (only highest numbered domain can be deleted, but NEVER Domain 1)
    allDomainBlocks.forEach((block, index) => {
      const deleteBtn = block.querySelector('.delete-domain-btn');
      if (deleteBtn) {
        const input = block.querySelector('input');
        if (input) {
          const inputName = input.name;
          const domainNum = inputName.match(/CFG_DOMAIN_(\d+)/);
          const domainNumber = domainNum ? parseInt(domainNum[1]) : 0;
          
          // Find the highest domain number among all visible blocks
          const highestDomainNumber = Math.max(...allDomainNumbers);
          
          // Only highest numbered domain can be deleted, but NEVER Domain 1
          const canDelete = domainNumber === highestDomainNumber && domainNumber !== 1;
          
          deleteBtn.disabled = !canDelete;
          deleteBtn.className = `delete-domain-btn ${!canDelete ? 'disabled' : ''}`;
          deleteBtn.title = canDelete ? 'Delete domain' : domainNumber === 1 ? 'Domain 1 cannot be deleted' : 'Can only delete highest numbered domain';
        }
      }
    });
  }
}

// Standalone domain management functions - immediately available
window.addDomain = function() {
  //console.log('Add Domain button clicked!');
  
  try {
    // Before adding new domain, validate that all existing domains have valid format
    if (!canAddNewDomain()) {
      // Find the first invalid domain and focus it with flash
      const allDomainInputs = document.querySelectorAll('input[id^="config-CFG_DOMAIN_"]');
      for (const input of allDomainInputs) {
        if (!validateDomainFormat(input, false)) { // Don't show notification here
          input.style.animation = 'flash 0.5s ease-in-out 2';
          input.focus();
          setTimeout(() => {
            input.style.animation = '';
          }, 1000);
          return;
        }
      }
      return;
    }
    
    // Find the highest existing domain number
    const domainInputs = document.querySelectorAll('input[name^="CFG_DOMAIN_"]');
    const domainNumbers = [];
    
    domainInputs.forEach(input => {
      const match = input.name.match(/CFG_DOMAIN_(\d+)/);
      if (match) {
        domainNumbers.push(parseInt(match[1]));
      }
    });
    
    // Check if we've reached the maximum of 9 domains
    if (domainNumbers.length >= 9) {
      //console.log('Maximum of 9 domains reached');
      return;
    }
    
    const nextDomainNumber = domainNumbers.length > 0 ? Math.max(...domainNumbers) + 1 : 1;
    const newDomainKey = `CFG_DOMAIN_${nextDomainNumber}`;
    const newFieldId = `config-${newDomainKey}`;
    
    // Create new domain building block HTML
    const newDomainHTML = `
      <div class="domain-building-block">
        <div class="domain-header">
          ${typeof ConfigShared !== 'undefined' ? ConfigShared.generateField(newFieldId, newDomainKey, '', `Domain ${nextDomainNumber}`, '', { 
            placeholder: 'example.com',
            className: 'domain-input',
            onchange: 'validateDomainFormat(this, true)',
            oninput: 'validateDomainFormat(this, true)',
            onblur: 'validateDomainFormat(this, true)'
          }) : `<input type="url" id="${newFieldId}" name="${newDomainKey}" value="" class="form-control domain-input" placeholder="example.com" onchange="validateDomainFormat(this, true)" oninput="validateDomainFormat(this, true)" onblur="validateDomainFormat(this, true)">`}
          <button type="button" class="delete-domain-btn" 
                  onclick="window.deleteDomain('${newDomainKey}', this)">
            <span class="delete-icon">×</span>
          </button>
        </div>
      </div>
    `;
    
    // Find the domain-building-blocks container and add the new block
    const domainContainer = document.querySelector('.domain-building-blocks');
    if (domainContainer) {
      const tempDiv = document.createElement('div');
      tempDiv.innerHTML = newDomainHTML;
      const newBlock = tempDiv.firstElementChild;
      domainContainer.appendChild(newBlock);
      
      // Focus on the new input field
      const newInput = newBlock.querySelector('input');
      if (newInput) {
        newInput.focus();
      }
      
      // Update add domain button state
      updateDomainDeleteButtons();
      updateAddDomainButton();
    }
  } catch (error) {
    console.error('Error adding new domain:', error);
  }
};

window.deleteDomain = function(domainKey, buttonElement) {
  //console.log(`Delete domain button clicked for: ${domainKey}`);
  
  try {
    // Find the domain-building-block and remove it
    const domainBlock = buttonElement.closest('.domain-building-block');
    if (domainBlock) {
      // Clear the input value first
      const input = domainBlock.querySelector('input');
      if (input) {
        input.value = '';
      }
      // Remove the entire building block
      domainBlock.remove();
      
      // Update add domain button state (re-enable if we're below 9 domains)
      updateDomainDeleteButtons();
      updateAddDomainButton();
    }
  } catch (error) {
    console.error('Error deleting domain:', error);
  }
};

// Helper function to update delete button states
function updateDomainDeleteButtons() {
  // Find all domain building blocks
  const allDomainBlocks = document.querySelectorAll('.domain-building-block');
  
  // Find all domain numbers from existing blocks
  const allDomainNumbers = [];
  allDomainBlocks.forEach(block => {
    const input = block.querySelector('input');
    if (input) {
      const inputName = input.name;
      const match = inputName.match(/CFG_DOMAIN_(\d+)/);
      if (match) {
        allDomainNumbers.push(parseInt(match[1]));
      }
    }
  });
  
  // Update delete button states (only highest numbered domain can be deleted, but NEVER Domain 1)
  allDomainBlocks.forEach((block, index) => {
    const deleteBtn = block.querySelector('.delete-domain-btn');
    if (deleteBtn) {
      const input = block.querySelector('input');
      if (input) {
        const inputName = input.name;
        const domainNum = inputName.match(/CFG_DOMAIN_(\d+)/);
        const domainNumber = domainNum ? parseInt(domainNum[1]) : 0;
        
        // Find the highest domain number among all visible blocks
        const highestDomainNumber = Math.max(...allDomainNumbers);
        
        // Only highest numbered domain can be deleted, but NEVER Domain 1
        const canDelete = domainNumber === highestDomainNumber && domainNumber !== 1;
        
        deleteBtn.disabled = !canDelete;
        deleteBtn.className = `delete-domain-btn ${!canDelete ? 'disabled' : ''}`;
        deleteBtn.title = canDelete ? 'Delete domain' : domainNumber === 1 ? 'Domain 1 cannot be deleted' : 'Can only delete highest numbered domain';
      }
    }
  });
}

// Helper function to update add domain button state
function updateAddDomainButton() {
  const addDomainBtn = document.getElementById('add-domain-btn');
  if (addDomainBtn) {
    // Find all domain building blocks
    const allDomainBlocks = document.querySelectorAll('.domain-building-block');
    
    // Find all domain numbers from existing blocks
    const allDomainNumbers = [];
    allDomainBlocks.forEach(block => {
      const input = block.querySelector('input');
      if (input) {
        const inputName = input.name;
        const match = inputName.match(/CFG_DOMAIN_(\d+)/);
        if (match) {
          allDomainNumbers.push(parseInt(match[1]));
        }
      }
    });
    
    // Check if we've reached the maximum of 9 domains
    const isMaxDomains = allDomainNumbers.length >= 9;
    
    // Update button state
    addDomainBtn.disabled = isMaxDomains;
    addDomainBtn.className = `btn ${isMaxDomains ? 'btn-secondary' : 'btn-primary'}`;
    addDomainBtn.innerHTML = `<span class="add-icon">${isMaxDomains ? '✓' : '+'}</span>${isMaxDomains ? 'Maximum Domains Reached' : 'Add Domain'}`;
  }
}

// Validate domain format when user tries to add a new domain
function validateDomainFormat(input, showNotifications = true) {
  const value = input.value.trim();
  //console.log('validateDomainFormat called with:', value, 'showNotifications:', showNotifications);
  //console.log('window.notificationSystem available:', !!window.notificationSystem);
  
  if (!value) {
    // Clear styling for empty fields
    input.style.borderColor = '#dc3545';
    input.title = 'Domain cannot be empty';
    if (showNotifications && window.notificationSystem) {
      //console.log('Attempting to show empty domain notification');
      window.notificationSystem.error('Domain cannot be empty');
    } else {
      console.error('Domain cannot be empty - notification system not available');
    }
    return false; // Empty fields are not valid for adding new domains
  }
  
  // Basic domain validation regex - supports subdomains and multiple TLD levels
  const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]?(?:\.[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]?)*\.[a-zA-Z]{2,}$/;
  const isValidFormat = domainRegex.test(value);
  
  // Check for duplicates
  const allDomainInputs = document.querySelectorAll('input[id^="config-CFG_DOMAIN_"]');
  const duplicates = Array.from(allDomainInputs).filter(otherInput => 
    otherInput !== input && otherInput.value.trim() === value
  );
  const hasDuplicate = duplicates.length > 0;
  
  if (!isValidFormat) {
    input.style.borderColor = '#dc3545';
    input.title = 'Invalid domain format (e.g., example.com)';
    if (showNotifications && window.notificationSystem) {
      //console.log('Attempting to show invalid format notification');
      window.notificationSystem.error('Invalid domain format: "' + value + '". Please use a valid domain like example.com');
    } else {
      console.error('Invalid domain format - notification system not available');
    }
    return false;
  } else if (hasDuplicate) {
    input.style.borderColor = '#dc3545';
    input.title = 'Domain already exists';
    if (showNotifications && window.notificationSystem) {
      //console.log('Attempting to show duplicate notification');
      window.notificationSystem.error('Domain "' + value + '" already exists');
    } else {
      console.error('Domain already exists - notification system not available');
    }
    return false;
  } else {
    input.style.borderColor = '';
    input.title = '';
    return true;
  }
}

// Check if all domains are valid before allowing new domain addition
function canAddNewDomain() {
  const allDomainInputs = document.querySelectorAll('input[id^="config-CFG_DOMAIN_"]');
  for (const input of allDomainInputs) {
    const domainValue = input.value.trim();
    
    // Check if domain is empty
    if (!domainValue) {
      // Flash the empty input field
      input.style.animation = 'flash 0.5s ease-in-out 2';
      input.focus();
      setTimeout(() => {
        input.style.animation = '';
      }, 1000);
      
      // Show notification with safety check
      if (window.notificationSystem) {
        window.notificationSystem.error('Domain cannot be empty');
      } else {
        console.error('Domain cannot be empty');
      }
      return false; // Empty domain - don't allow adding new domain
    }
    
    // Check for duplicates with notification (always show)
    if (checkForDuplicateDomain(input, domainValue)) {
      return false;
    }
    
    // Check domain format with notification (always show)
    if (checkForInvalidDomainFormat(input, domainValue)) {
      return false;
    }
  }
  return true; // All domains are valid and non-empty
}

// Separate function to check for invalid format that always shows notifications
function checkForInvalidDomainFormat(input, domainValue) {
  if (!domainValue) return false;
  
  // Basic domain validation regex - supports subdomains and multiple TLD levels
  const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]?(?:\.[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]?)*\.[a-zA-Z]{2,}$/;
  const isValidFormat = domainRegex.test(domainValue);
  
  if (!isValidFormat) {
    input.style.borderColor = '#dc3545';
    input.title = 'Invalid domain format (e.g., example.com)';
    if (window.notificationSystem) {
      //console.log('Showing invalid domain format notification');
      window.notificationSystem.error('Invalid domain format: "' + domainValue + '". Please use a valid domain like example.com');
    } else {
      console.error('Invalid domain format - notification system not available');
    }
    return true;
  }
  
  return false;
}

// Separate function to check for duplicates that always shows notifications
function checkForDuplicateDomain(input, domainValue) {
  if (!domainValue) return false;
  
  const allDomainInputs = document.querySelectorAll('input[id^="config-CFG_DOMAIN_"]');
  const duplicates = Array.from(allDomainInputs).filter(otherInput => 
    otherInput !== input && otherInput.value.trim() === domainValue
  );
  const hasDuplicate = duplicates.length > 0;
  
  if (hasDuplicate) {
    input.style.borderColor = '#dc3545';
    input.title = 'Domain already exists';
    if (window.notificationSystem) {
      //console.log('Showing duplicate domain notification');
      window.notificationSystem.error('Domain "' + domainValue + '" already exists');
    } else {
      console.error('Domain already exists - notification system not available');
    }
    return true;
  }
  
  return false;
}
