// Popup script for DCS Credit Application Extension

class PopupController {
  constructor() {
    this.init();
    this.checkStatus();
  }

  init() {
    // Get DOM elements
    this.elements = {
      pageStatus: document.getElementById('pageStatus'),
      pageStatusText: document.getElementById('pageStatusText'),
      serverStatus: document.getElementById('serverStatus'),
      serverStatusText: document.getElementById('serverStatusText'),
      odooStatus: document.getElementById('odooStatus'),
      odooStatusText: document.getElementById('odooStatusText'),
      processBtn: document.getElementById('processBtn'),
      manualSyncBtn: document.getElementById('manualSyncBtn'),
      fieldCounter: document.getElementById('fieldCounter'),
      errorMessage: document.getElementById('errorMessage'),
      successMessage: document.getElementById('successMessage'),
      printToggle: document.getElementById('printToggle'),
      openToggle: document.getElementById('openToggle'),
      odooSyncToggle: document.getElementById('odooSyncToggle'),
      advancedSettings: document.getElementById('advancedSettings')
    };

    // Add event listeners
    this.elements.processBtn.addEventListener('click', () => this.processApplication());
    this.elements.manualSyncBtn.addEventListener('click', () => this.syncToOdoo());
    this.elements.printToggle.addEventListener('click', () => this.togglePrint());
    this.elements.openToggle.addEventListener('click', () => this.toggleOpen());
    this.elements.odooSyncToggle.addEventListener('click', () => this.toggleOdooSync());
    this.elements.advancedSettings.addEventListener('click', (e) => {
      e.preventDefault();
      chrome.tabs.create({ url: chrome.runtime.getURL('settings.html') });
    });
    
    // Load settings
    this.loadSettings();
    
    // Check status every few seconds
    setInterval(() => this.checkStatus(), 3000);
  }

  async checkStatus() {
    try {
      // Check if current tab is a DCS page
      const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
      
      if (!tab) {
        this.updatePageStatus(false, 'No active tab');
        return;
      }

      // Send message to content script to check page status
      chrome.tabs.sendMessage(tab.id, { action: 'checkPageStatus' }, (response) => {
        if (chrome.runtime.lastError) {
          this.updatePageStatus(false, 'Page not loaded');
          return;
        }
        
        // Check if URL is invalid
        if (response && response.invalidURL) {
          this.updatePageStatus(false, 'Invalid URL - Use print page only');
          this.elements.processBtn.disabled = true;
          this.showError('Please navigate to a credit application print page (not edit page)');
        } else if (response && response.isDCSPage) {
          this.updatePageStatus(true, 'DCS page detected');
          this.elements.processBtn.disabled = false;
          this.hideError(); // Clear any previous error
        } else {
          this.updatePageStatus(false, 'Not a DCS page');
          this.elements.processBtn.disabled = true;
        }
      });

      // Check Python server status
      this.checkServerStatus();
      
    } catch (error) {
      console.error('Error checking status:', error);
      this.updatePageStatus(false, 'Error checking page');
    }
  }

  async checkServerStatus() {
    try {
      // Get API URL from settings
      const settings = await chrome.storage.local.get(['apiUrl']);
      const apiUrl = settings.apiUrl || 'http://localhost:8000';
      
      const response = await fetch(`${apiUrl}/health`, {
        method: 'GET',
        timeout: 2000
      });
      
      if (response.ok) {
        this.updateServerStatus(true, 'Python server connected');
        // Check Odoo status when server is connected
        this.checkOdooStatus();
      } else {
        this.updateServerStatus(false, 'Server error');
        this.updateOdooStatus(false, 'Odoo disconnected', '');
      }
    } catch (error) {
      this.updateServerStatus(false, 'Server disconnected');
      this.updateOdooStatus(false, 'Odoo disconnected', '');
    }
  }

  updatePageStatus(isActive, text) {
    this.elements.pageStatus.className = `status-dot ${isActive ? 'active' : 'inactive'}`;
    this.elements.pageStatusText.textContent = text;
  }

  updateServerStatus(isActive, text) {
    this.elements.serverStatus.className = `status-dot ${isActive ? 'active' : 'inactive'}`;
    this.elements.serverStatusText.textContent = text;
  }

  updateOdooStatus(isActive, text, indicatorText = '') {
    this.elements.odooStatus.className = `status-dot ${isActive ? 'active' : 'inactive'}`;
    this.elements.odooStatusText.textContent = text;
  }


  extractCustomerName(data) {
    // Parse customer name from extracted data
    const firstName = data.first_name || '';
    const lastName = data.last_name || '';
    
    if (firstName && lastName) {
      return `${firstName} ${lastName}`;
    } else if (firstName) {
      return firstName;
    } else if (lastName) {
      return lastName;
    }
    
    return null;
  }

  async extractDataWithRetry(tabId, maxRetries = 3) {
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        console.log(`Data extraction attempt ${attempt}/${maxRetries}`);
        
        const result = await new Promise((resolve, reject) => {
          // Set up timeout for individual attempt
          const timeout = setTimeout(() => {
            reject(new Error(`Extraction timeout on attempt ${attempt} (45s)`));
          }, 45000); // 45 second timeout per attempt
          
          chrome.tabs.sendMessage(tabId, { action: 'extractData' }, (response) => {
            clearTimeout(timeout);
            
            if (chrome.runtime.lastError) {
              const error = chrome.runtime.lastError.message;
              console.error(`Chrome runtime error on attempt ${attempt}:`, error);
              
              // Check for specific message port errors
              if (error.includes('message port closed') || 
                  error.includes('receiving end does not exist') ||
                  error.includes('context invalidated')) {
                reject(new Error(`Message port error: ${error}`));
              } else {
                reject(new Error(error));
              }
              return;
            }
            
            if (!response) {
              reject(new Error('No response from content script'));
              return;
            }
            
            resolve(response);
          });
        });
        
        // If successful, return result
        if (result.success) {
          console.log(`Data extraction successful on attempt ${attempt}`);
          return result;
        } else {
          console.warn(`Extraction failed on attempt ${attempt}:`, result.error);
          if (attempt === maxRetries) {
            return result; // Return the last error
          }
        }
        
      } catch (error) {
        console.error(`Extraction attempt ${attempt} failed:`, error.message);
        
        if (attempt === maxRetries) {
          return {
            success: false,
            error: `All ${maxRetries} extraction attempts failed. Last error: ${error.message}`,
            data: {},
            fieldCount: 0
          };
        }
        
        // Wait before retrying (exponential backoff)
        const delay = Math.min(1000 * Math.pow(2, attempt - 1), 5000);
        console.log(`Waiting ${delay}ms before retry...`);
        await new Promise(resolve => setTimeout(resolve, delay));
        
        // For message port errors, try multiple recovery methods
        if (error.message.includes('message port') || 
            error.message.includes('receiving end does not exist')) {
          console.log('Attempting recovery methods...');
          
          // Try 1: Reinject content script
          await this.reinjectContentScript(tabId);
          
          // Try 2: Use background script forwarding as fallback
          if (attempt === maxRetries - 1) { // On second-to-last attempt
            console.log('Trying background script forwarding...');
            try {
              const fallbackResult = await this.tryBackgroundForwarding(tabId);
              if (fallbackResult.success) {
                return fallbackResult;
              }
            } catch (fallbackError) {
              console.error('Background forwarding failed:', fallbackError);
            }
          }
        }
      }
    }
    
    return {
      success: false,
      error: `Failed after ${maxRetries} attempts`,
      data: {},
      fieldCount: 0
    };
  }

  async reinjectContentScript(tabId) {
    try {
      // Try to reinject the content script
      await chrome.scripting.executeScript({
        target: { tabId: tabId },
        files: ['content.js']
      });
      console.log('Content script reinjected successfully');
      
      // Wait a moment for the script to initialize
      await new Promise(resolve => setTimeout(resolve, 2000));
      
    } catch (error) {
      console.error('Failed to reinject content script:', error);
      // This will fail if we don't have scripting permission, which is expected
      // The content script should already be injected via manifest
    }
  }

  async tryBackgroundForwarding(tabId) {
    try {
      console.log('Attempting background script forwarding...');
      
      return new Promise((resolve, reject) => {
        const timeout = setTimeout(() => {
          reject(new Error('Background forwarding timeout (30s)'));
        }, 30000);
        
        chrome.runtime.sendMessage({
          action: 'forwardToContentScript',
          targetTabId: tabId,
          originalAction: 'extractData',
          originalData: {}
        }, (response) => {
          clearTimeout(timeout);
          
          if (chrome.runtime.lastError) {
            reject(new Error(`Background forwarding failed: ${chrome.runtime.lastError.message}`));
            return;
          }
          
          if (!response || !response.success) {
            reject(new Error(`Background forwarding failed: ${response?.error || 'Unknown error'}`));
            return;
          }
          
          resolve(response.data || { success: false, error: 'No data from background forwarding' });
        });
      });
      
    } catch (error) {
      console.error('Background forwarding error:', error);
      throw error;
    }
  }

  async processApplication() {
    try {
      // Step 1: Extract data from page
      this.showMessage('Extracting data from page...', 'info');
      this.elements.processBtn.disabled = true;
      this.elements.processBtn.textContent = 'Extracting...';
      this.elements.fieldCounter.textContent = 'Extracting data...';

      // Get current tab
      const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
      
      // Extract data using improved promise wrapper with timeout and retry
      const extractionResult = await this.extractDataWithRetry(tab.id, 3);

      if (!extractionResult.success) {
        this.showMessage(`Failed to extract data: ${extractionResult.error}`, 'error');
        return;
      }

      const fieldCount = extractionResult.fieldCount || 0;
      const customerName = this.extractCustomerName(extractionResult.data);
      
      this.elements.fieldCounter.textContent = `Extracted ${fieldCount} fields`;
      this.showMessage(`Extracted ${fieldCount} fields, processing...`, 'info');

      // Step 2: Process the application
      this.elements.processBtn.textContent = 'Processing...';

      // Get settings
      const settings = await chrome.storage.local.get(['apiUrl', 'autoPrint', 'autoOpen', 'customerDocsPath']);
      const apiUrl = settings.apiUrl || 'http://localhost:8000';
      const autoPrint = settings.autoPrint !== undefined ? settings.autoPrint : true;
      const autoOpen = settings.autoOpen !== undefined ? settings.autoOpen : true;
      const customerDocsPath = settings.customerDocsPath || 'D:\\Customer Docs';
      
      // Get Odoo sync setting
      const odooSync = await this.getOdooSyncSetting();

      // Send data to Python backend
      const response = await fetch(`${apiUrl}/process-application`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          data: extractionResult.data,
          pageHtml: extractionResult.pageHtml,
          timestamp: new Date().toISOString(),
          pdf_filename: null,
          source_url: window.location.href,
          auto_print: autoPrint,
          auto_open: autoOpen,
          customer_docs_path: customerDocsPath,
          odoo_sync: odooSync
        })
      });

      if (response.ok) {
        const result = await response.json();
        this.showMessage('Credit application processed successfully!', 'success');
        
        // Display clean status with customer name and field count
        const displayName = customerName || result.customer_name || 'Customer';
        const processedFields = result.fields_processed || fieldCount;
        this.elements.fieldCounter.textContent = `${displayName} Credit App Processed - ${processedFields} Fields`;
        
        // Store result for potential Odoo sync
        this.lastProcessResult = {
          customer_name: displayName,
          pdf_path: result.customer_folder ? `${result.customer_folder}/${displayName} Credit App.pdf` : null,
          dcs_pdf_path: result.customer_folder ? `${result.customer_folder}/DCS ${displayName} Credit App.pdf` : null,
          json_path: result.customer_folder ? `${result.customer_folder}/${displayName} Credit App.json` : null,
          extracted_data: extractionResult.data,
          odoo_lead_id: result.odoo_lead_id || null
        };
        
        // Check if Odoo sync was already done by API
        if (result.odoo_lead_id) {
          this.showMessage(`✅ Created/Updated Odoo Lead #${result.odoo_lead_id}`, 'success');
          console.log(`Odoo sync already completed by API: Lead #${result.odoo_lead_id}`);
          // Hide manual sync button since it's already synced
          this.elements.manualSyncBtn.style.display = 'none';
        } else {
          // Check if auto-sync is enabled and Odoo is connected (old flow for backward compatibility)
          const autoSyncEnabled = await this.getOdooSyncSetting();
          const odooStatusText = this.elements.odooStatusText.textContent;
          const odooConnected = odooStatusText.includes('connected');
          
          console.log(`Auto-sync debug: autoSyncEnabled=${autoSyncEnabled}, odooStatusText="${odooStatusText}", odooConnected=${odooConnected}`);
          
          if (odooConnected && autoSyncEnabled) {
            console.log('Triggering auto-sync to Odoo...');
            // Auto-sync to Odoo
            setTimeout(() => this.syncToOdoo(), 1500);
          } else if (odooConnected) {
            console.log('Showing manual sync button...');
            // Show manual sync button
            this.elements.manualSyncBtn.style.display = 'block';
            this.elements.manualSyncBtn.disabled = false;
          } else {
            console.log(`Sync not triggered: odooConnected=${odooConnected}, autoSyncEnabled=${autoSyncEnabled}`);
          }
        }
      } else {
        const error = await response.text();
        this.showMessage(`Processing failed: ${error}`, 'error');
      }

    } catch (error) {
      console.error('Error processing application:', error);
      this.showMessage('Failed to connect to processing server', 'error');
    } finally {
      this.elements.processBtn.disabled = false;
      this.elements.processBtn.textContent = 'Process DCS Application';
    }
  }


  showMessage(text, type) {
    // Hide all messages first
    this.elements.errorMessage.style.display = 'none';
    this.elements.successMessage.style.display = 'none';

    // Show appropriate message
    if (type === 'error') {
      this.elements.errorMessage.textContent = text;
      this.elements.errorMessage.style.display = 'block';
    } else if (type === 'success') {
      this.elements.successMessage.textContent = text;
      this.elements.successMessage.style.display = 'block';
    }

    // Auto-hide after 5 seconds
    setTimeout(() => {
      this.elements.errorMessage.style.display = 'none';
      this.elements.successMessage.style.display = 'none';
    }, 5000);
  }

  showError(text) {
    this.showMessage(text, 'error');
  }
  
  hideError() {
    if (this.elements.errorMessage) {
      this.elements.errorMessage.style.display = 'none';
    }
  }

  showSuccess(text) {
    this.showMessage(text, 'success');
  }

  async loadSettings() {
    try {
      const result = await chrome.storage.local.get(['autoPrint', 'autoOpen', 'odooAutoSync']);
      const autoPrint = result.autoPrint !== undefined ? result.autoPrint : true;
      const autoOpen = result.autoOpen !== undefined ? result.autoOpen : true;
      const odooAutoSync = result.odooAutoSync || false;
      
      // Update toggle UI
      if (autoPrint) {
        this.elements.printToggle.classList.add('active');
      } else {
        this.elements.printToggle.classList.remove('active');
      }
      
      if (autoOpen) {
        this.elements.openToggle.classList.add('active');
      } else {
        this.elements.openToggle.classList.remove('active');
      }
      
      if (odooAutoSync) {
        this.elements.odooSyncToggle.classList.add('active');
      } else {
        this.elements.odooSyncToggle.classList.remove('active');
      }
      
    } catch (error) {
      console.error('Error loading settings:', error);
      // Default to enabled if error
      this.elements.printToggle.classList.add('active');
      this.elements.openToggle.classList.add('active');
    }
  }

  async togglePrint() {
    try {
      // Toggle the visual state
      const isActive = this.elements.printToggle.classList.contains('active');
      const newState = !isActive;
      
      if (newState) {
        this.elements.printToggle.classList.add('active');
      } else {
        this.elements.printToggle.classList.remove('active');
      }
      
      // Save to storage
      await chrome.storage.local.set({ autoPrint: newState });
      
      console.log(`Auto-print ${newState ? 'enabled' : 'disabled'}`);
      
    } catch (error) {
      console.error('Error toggling print setting:', error);
    }
  }

  async toggleOpen() {
    try {
      // Toggle the visual state
      const isActive = this.elements.openToggle.classList.contains('active');
      const newState = !isActive;
      
      if (newState) {
        this.elements.openToggle.classList.add('active');
      } else {
        this.elements.openToggle.classList.remove('active');
      }
      
      // Save to storage
      await chrome.storage.local.set({ autoOpen: newState });
      
      console.log(`Auto-open ${newState ? 'enabled' : 'disabled'}`);
      
    } catch (error) {
      console.error('Error toggling open setting:', error);
    }
  }

  async getPrintSetting() {
    try {
      const result = await chrome.storage.local.get(['autoPrint']);
      return result.autoPrint !== undefined ? result.autoPrint : true; // Default to true
    } catch (error) {
      console.error('Error getting print setting:', error);
      return true; // Default to enabled
    }
  }

  async toggleOdooSync() {
    const isActive = this.elements.odooSyncToggle.classList.contains('active');
    const newState = !isActive;
    
    try {
      await chrome.storage.local.set({ odooAutoSync: newState });
      
      if (newState) {
        this.elements.odooSyncToggle.classList.add('active');
      } else {
        this.elements.odooSyncToggle.classList.remove('active');
      }
    } catch (error) {
      console.error('Error toggling Odoo sync setting:', error);
    }
  }

  async getOdooSyncSetting() {
    try {
      const result = await chrome.storage.local.get(['odooAutoSync']);
      return result.odooAutoSync || false; // Default to false
    } catch (error) {
      console.error('Error getting Odoo sync setting:', error);
      return false;
    }
  }

  // Odoo sync methods
  async checkOdooStatus() {
    try {
      const response = await fetch('http://127.0.0.1:8000/odoo/config');
      if (response.ok) {
        const config = await response.json();
        const configured = config.url && config.database && config.username;
        
        if (configured && config.enable_sync) {
          // Test connection
          const testResponse = await fetch('http://127.0.0.1:8000/odoo/test', { method: 'POST' });
          const testResult = await testResponse.json();
          
          if (testResult.success) {
            this.updateOdooStatus(true, 'Odoo connected', '✅ Odoo connected');
            return true;
          } else {
            this.updateOdooStatus(false, 'Odoo config issue', '⚠️ Odoo config issue');
            return false;
          }
        } else {
          this.updateOdooStatus(false, 'Odoo not configured', 'Odoo not configured');
          return false;
        }
      }
    } catch (error) {
      this.updateOdooStatus(false, 'Odoo offline', 'Odoo offline');
      return false;
    }
  }

  async syncToOdoo() {
    if (!this.lastProcessResult) {
      this.showError('No recent processing result found. Process application first.');
      return;
    }

    try {
      // Update button to show progress
      if (this.elements.manualSyncBtn) {
        this.elements.manualSyncBtn.disabled = true;
        this.elements.manualSyncBtn.textContent = '🔄 Searching leads...';
      }

      // Extract customer info for search
      const customerName = this.lastProcessResult.customer_name;
      const customerData = this.lastProcessResult.extracted_data || {};
      const phone = customerData.mobile_phone || customerData.home_phone || '';

      if (!customerName) {
        this.showError('No customer name found for lead search');
        return;
      }

      // Search for leads
      const searchResponse = await fetch('http://127.0.0.1:8000/odoo/search-leads', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: customerName,
          phone: phone
        })
      });

      const searchResult = await searchResponse.json();
      console.log('Search result:', searchResult);

      if (!searchResult.success) {
        this.showError(`Lead search failed: ${searchResult.message}`);
        return;
      }

      if (searchResult.leads.length === 0) {
        this.showError(`No leads found for "${customerName}". Create lead in Odoo first.`);
        return;
      }

      // If multiple leads, use the first one (most recent)
      const selectedLead = searchResult.leads[0];
      console.log('Selected lead for sync:', selectedLead);
      
      if (this.elements.manualSyncBtn) {
        this.elements.manualSyncBtn.textContent = '🔄 Syncing files...';
      }

      // Sync to selected lead
      console.log('Starting sync with data:', {
        lead_id: selectedLead.id,
        customer_name: customerName,
        pdf_path: this.lastProcessResult.pdf_path,
        dcs_pdf_path: this.lastProcessResult.dcs_pdf_path,
        json_path: this.lastProcessResult.json_path
      });
      
      const syncResponse = await fetch('http://127.0.0.1:8000/odoo/sync', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          lead_id: selectedLead.id,
          customer_name: customerName,
          pdf_path: this.lastProcessResult.pdf_path,
          dcs_pdf_path: this.lastProcessResult.dcs_pdf_path,
          json_path: this.lastProcessResult.json_path,
          extracted_data: this.lastProcessResult.extracted_data
        })
      });

      console.log('Sync response status:', syncResponse.status);
      const syncResult = await syncResponse.json();
      console.log('Sync result:', syncResult);

      if (syncResult.success) {
        this.showSuccess(`✅ Successfully synced to lead "${selectedLead.name}" (ID: ${selectedLead.id})`);
        if (this.elements.manualSyncBtn) {
          this.elements.manualSyncBtn.textContent = '✅ Synced';
          this.elements.manualSyncBtn.style.backgroundColor = '#4CAF50';
          
          // Hide button after successful sync
          setTimeout(() => {
            this.elements.manualSyncBtn.style.display = 'none';
            this.elements.manualSyncBtn.textContent = '🔗 Sync Last Result to Odoo';
            this.elements.manualSyncBtn.style.backgroundColor = '';
          }, 3000);
        }
      } else {
        this.showError(`Sync failed: ${syncResult.message}`);
      }

    } catch (error) {
      this.showError(`Network error: ${error.message}`);
    } finally {
      // Re-enable manual sync button
      if (this.elements.manualSyncBtn) {
        this.elements.manualSyncBtn.disabled = false;
        if (this.elements.manualSyncBtn.textContent.includes('🔄')) {
          this.elements.manualSyncBtn.textContent = '🔗 Sync Last Result to Odoo';
        }
      }
    }
  }
}

// Initialize popup when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
  new PopupController();
});