I created a floating browser extension that uses chat models from huggingface to provide a chat companion on a browser. But if I run the server, it only says Starting SocketIO server on 127.0.0.1:8765 but it doesn't actually run, so when I try to use the extension it says Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist. What is the problem? Please analyze my code below and make necessary changes to make the extension work smoothly.
When making changes to resolve above issues please also modify it so that the floating window remains active until I click on the extension icon. Let the floating window not disappear when I click on any other place in the site. Also, include a close icon at the top right which I can use to exit apart from clicking on the icon. Also, make the floating window movable. I should be able to hold it and drag it around on the page. And also add a button for send on the input textbox (After writing the message I should click send to send the message to the models for them to respond.) You can also add any other features that would make it user friendly and amazing to improve user experience.
There are features in contentScript.js which are on other script files, please remove such features from contentscript.js to avoid duplication and errors that certain features have already been defined.

app.py
import os
import json
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
import langdetect
from .translator import translate_text
import json

with open(os.path.join(os.path.dirname(__file__), 'models.json')) as f:
    models_config = json.load(f)

def detect_language(text):
    try:
        return langdetect.detect(text)
    except langdetect.lang_detect_exception.LangDetectException:
        return 'en'  # Default to English on detection failure

def generate_response(prompt, model_name):
    model = AutoModelForSeq2SeqLM.from_pretrained(model_name)
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    
    inputs = tokenizer(prompt, return_tensors="pt")
    outputs = model.generate(**inputs)
    response = tokenizer.decode(outputs[0], skip_special_tokens=True)
    
    return response

def get_responses(prompt, lang):
    responses = []
    for model in models_config[lang]:
        responses.append(generate_response(prompt, model))
    return responses

ws_server.py
import os
import json
import logging
from logging.handlers import RotatingFileHandler

from flask import Flask, jsonify
from flask_socketio import SocketIO, emit
from .app import detect_language, get_responses
from .translator import translate_text
import gevent

# --- Create Flask App ---
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'  # Change this for production!

# --- Configure Flask's Logger ---
file_handler = RotatingFileHandler('flask_app.log', maxBytes=1024 * 1024 * 100, backupCount=20)
file_handler.setLevel(logging.INFO) 
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)

# --- Load Models Configuration ---
with open(os.path.join(os.path.dirname(__file__), 'models.json')) as f:
    models_config = json.load(f)

# --- Create SocketIO Instance ---
socketio = SocketIO(app, cors_allowed_origins='*', async_mode='gevent')

# --- Event Handlers ---
@socketio.on('connect')
def handle_connect():
    app.logger.info('Client connected')

@socketio.on('disconnect')
def handle_disconnect():
    app.logger.info('Client disconnected')

@socketio.on('processText')
def handle_process_text(data):
    app.logger.info('processText event received with data: %s', data)
    text = data['text']
    app.logger.info('Text received: %s', text)

    lang = detect_language(text)
    app.logger.info('Detected language: %s', lang)

    responses = get_responses(text, lang)
    app.logger.info('Generated responses: %s', responses)

    emit('responses', {
        'responses': responses,
        'detectedLanguage': lang
    })
    app.logger.info('Responses emitted back to client.')

@socketio.on('translateToEnglish')
def handle_translate_to_english(data):
    app.logger.info('translateToEnglish event received with data: %s', data)
    text = data['text']
    app.logger.info('Text received for translation: %s', text)

    translation = translate_text(text, dest='en')
    app.logger.info('Translated text: %s', translation)

    emit('translation', {'translation': translation})
    app.logger.info('Translation emitted back to client.')

# --- Run the Server ---
if __name__ == '__main__':
    app.logger.info('Starting SocketIO server on 127.0.0.1:8765')
    socketio.run(app, host='127.0.0.1', port=8765, debug=True) 

background.js
// background.js
class BackgroundService {
    constructor() {
        this.connections = new Map();
        this.modelCache = new Map();
        this.processingQueue = [];
        this.isProcessing = false;
        
        this.initializeListeners();
        this.initializeModelCache();
    }

    initializeListeners() {
        // Listen for connection from content scripts
        chrome.runtime.onConnect.addListener(this.handleConnection.bind(this));
        
        // Listen for messages from popup or content scripts
        chrome.runtime.onMessage.addListener(this.handleMessage.bind(this));
        
        // Handle tab updates
        chrome.tabs.onUpdated.addListener(this.handleTabUpdate.bind(this));
        
        // Handle tab removal
        chrome.tabs.onRemoved.addListener(this.handleTabRemoval.bind(this));
    }

    async initializeModelCache() {
        try {
            // Load cached models from storage
            const data = await chrome.storage.local.get('modelCache');
            if (data.modelCache) {
                this.modelCache = new Map(JSON.parse(data.modelCache));
            }
        } catch (error) {
            console.error('Error initializing model cache:', error);
        }
    }

    handleConnection(port) {
        const tabId = port.sender.tab.id;
        this.connections.set(tabId, port);

        port.onDisconnect.addListener(() => {
            this.connections.delete(tabId);
            this.cleanupTab(tabId);
        });

        port.onMessage.addListener((message) => {
            this.handlePortMessage(tabId, message);
        });
    }

    async handleMessage(message, sender, sendResponse) {
        try {
            switch (message.action) {
                case 'processText':
                    await this.queueProcessing(message, sender);
                    sendResponse({ success: true });
                    break;

                case 'getModelStatus':
                    const status = await this.getModelStatus();
                    sendResponse({ status });
                    break;

                case 'clearCache':
                    await this.clearModelCache();
                    sendResponse({ success: true });
                    break;

                default:
                    console.warn('Unknown message action:', message.action);
                    sendResponse({ error: 'Unknown action' });
            }
        } catch (error) {
            console.error('Error handling message:', error);
            sendResponse({ error: error.message });
        }
        
        return true; // Keep the message channel open for async response
    }

    async handlePortMessage(tabId, message) {
        const port = this.connections.get(tabId);
        if (!port) return;

        try {
            switch (message.action) {
                case 'startProcessing':
                    await this.startTextProcessing(tabId, message.data);
                    break;

                case 'updateStatus':
                    await this.updateProcessingStatus(tabId, message.status);
                    break;

                case 'error':
                    this.handleError(tabId, message.error);
                    break;
            }
        } catch (error) {
            console.error('Error handling port message:', error);
            port.postMessage({ action: 'error', error: error.message });
        }
    }

    async handleTabUpdate(tabId, changeInfo, tab) {
        if (changeInfo.status === 'complete') {
            try {
                await this.injectContentScript(tab);
            } catch (error) {
                console.error('Error injecting content script:', error);
            }
        }
    }

    handleTabRemoval(tabId) {
        this.connections.delete(tabId);
        this.cleanupTab(tabId);
    }

    async queueProcessing(message, sender) {
        this.processingQueue.push({
            message,
            sender,
            timestamp: Date.now()
        });

        if (!this.isProcessing) {
            await this.processQueue();
        }
    }

    async processQueue() {
        if (this.processingQueue.length === 0) {
            this.isProcessing = false;
            return;
        }

        this.isProcessing = true;
        const item = this.processingQueue.shift();

        try {
            await this.processText(item.message, item.sender);
        } catch (error) {
            console.error('Error processing queue item:', error);
        }

        // Process next item
        await this.processQueue();
    }

    async processText(message, sender) {
        const tabId = sender.tab?.id;
        if (!tabId) return;

        const port = this.connections.get(tabId);
        if (!port) return;

        try {
            // Connect to WebSocket server
            const ws = new WebSocket('ws://localhost:8765');
            
            ws.onopen = () => {
                ws.send(JSON.stringify({
                    action: 'processText',
                    text: message.text,
                    options: message.options || {}
                }));
            };

            ws.onmessage = (event) => {
                const response = JSON.parse(event.data);
                port.postMessage(response);
            };

            ws.onerror = (error) => {
                console.error('WebSocket error:', error);
                port.postMessage({ action: 'error', error: 'WebSocket error occurred' });
            };

            // Clean up WebSocket after response or timeout
            setTimeout(() => {
                if (ws.readyState === WebSocket.OPEN) {
                    ws.close();
                }
            }, 30000); // 30 second timeout

        } catch (error) {
            console.error('Error in processText:', error);
            port.postMessage({ action: 'error', error: error.message });
        }
    }

    async injectContentScript(tab) {
        if (!tab.url?.startsWith('http')) return;

        try {
            await chrome.scripting.executeScript({
                target: { tabId: tab.id },
                files: ['contentScript.js']
            });

            await chrome.scripting.insertCSS({
                target: { tabId: tab.id },
                files: ['styles/content.css']
            });
        } catch (error) {
            console.error('Error injecting scripts/styles:', error);
        }
    }

    async clearModelCache() {
        try {
            this.modelCache.clear();
            await chrome.storage.local.remove('modelCache');
        } catch (error) {
            console.error('Error clearing model cache:', error);
        }
    }

    async getModelStatus() {
        return {
            cacheSize: this.modelCache.size,
            processingQueue: this.processingQueue.length,
            isProcessing: this.isProcessing,
            activeConnections: this.connections.size
        };
    }

    cleanupTab(tabId) {
        // Remove any pending processing requests for this tab
        this.processingQueue = this.processingQueue.filter(
            item => item.sender.tab?.id !== tabId
        );
    }

    async updateProcessingStatus(tabId, status) {
        try {
            await chrome.storage.local.set({
                [`processingStatus_${tabId}`]: status
            });
        } catch (error) {
            console.error('Error updating processing status:', error);
        }
    }

    handleError(tabId, error) {
        console.error(`Error in tab ${tabId}:`, error);
        // Implement error reporting/logging logic here
    }
}

// Initialize the background service
const backgroundService = new BackgroundService();

contentscript.js
// Configuration and constants
//const CONFIG = {
    //MESSAGE_SCAN_INTERVAL: 1000,
    //MAX_QUEUE_SIZE: 100,
    //DEBOUNCE_DELAY: 500,
    //RESPONSE_TIMEOUT: 5000
//};

// Message queue to handle concurrent processing
class MessageQueue {
    constructor() {
        this.queue = [];
        this.processing = false;
    }

    async add(message) {
        if (this.queue.length >= CONFIG.MAX_QUEUE_SIZE) {
            this.queue.shift(); // Remove oldest message if queue is full
        }
        this.queue.push(message);
        if (!this.processing) {
            await this.processQueue();
        }
    }

    async processQueue() {
        if (this.queue.length === 0) {
            this.processing = false;
            return;
        }

        this.processing = true;
        const message = this.queue.shift();
        await this.processMessage(message);
        await this.processQueue();
    }

    async processMessage(message) {
        try {
            // Send message to background script for processing
            const response = await chrome.runtime.sendMessage({
                action: 'processMessage',
                message: message.text,
                metadata: {
                    timestamp: message.timestamp,
                    url: window.location.href,
                    elementId: message.elementId
                }
            });

            if (response && response.success) {
                await this.handleResponse(message, response);
            }
        } catch (error) {
            console.error('Error processing message:', error);
        }
    }

    async handleResponse(originalMessage, response) {
        const responseElement = document.getElementById(originalMessage.elementId);
        if (responseElement) {
            // Apply response based on the platform's UI structure
            await this.injectResponse(responseElement, response.data);
        }
    }

    async injectResponse(element, responseData) {
        // Platform-specific response injection logic
        const platformHandlers = {
            'chat.openai.com': injectOpenAIResponse,
            'messenger.com': injectMessengerResponse,
            'web.whatsapp.com': injectWhatsAppResponse,
            // Add more platform handlers as needed
        };

        const domain = window.location.hostname;
        const handler = platformHandlers[domain] || injectDefaultResponse;
        await handler(element, responseData);
    }
}

// Platform-specific injection handlers
async function injectOpenAIResponse(element, responseData) {
    const responseContainer = document.createElement('div');
    responseContainer.className = 'chat-response-container';
    responseContainer.innerHTML = `
        <div class="response-header">
            <span class="ai-tag">AI Response</span>
            <span class="confidence">${responseData.confidence}%</span>
        </div>
        <div class="response-content">${responseData.text}</div>
    `;
    element.parentNode.insertBefore(responseContainer, element.nextSibling);
}

async function injectMessengerResponse(element, responseData) {
    // Messenger-specific injection logic
    const messageContainer = element.closest('.message-container');
    if (messageContainer) {
        const responseElement = document.createElement('div');
        responseElement.className = 'ai-response-bubble';
        responseElement.textContent = responseData.text;
        messageContainer.appendChild(responseElement);
    }
}

async function injectWhatsAppResponse(element, responseData) {
    // WhatsApp-specific injection logic
    const chatContainer = element.closest('.message-in');
    if (chatContainer) {
        const responseElement = document.createElement('div');
        responseElement.className = 'message-out ai-response';
        responseElement.innerHTML = responseData.text;
        chatContainer.parentNode.insertBefore(responseElement, chatContainer.nextSibling);
    }
}

async function injectDefaultResponse(element, responseData) {
    const responseElement = document.createElement('div');
    responseElement.className = 'extension-response';
    responseElement.textContent = responseData.text;
    element.parentNode.insertBefore(responseElement, element.nextSibling);
}

// Message observer to detect new messages
class MessageObserver {
    constructor(messageQueue) {
        this.messageQueue = messageQueue;
        this.observer = null;
        this.processedMessages = new Set();
    }

    start() {
        const config = { childList: true, subtree: true };
        this.observer = new MutationObserver(this.handleMutations.bind(this));
        this.observer.observe(document.body, config);
    }

    stop() {
        if (this.observer) {
            this.observer.disconnect();
        }
    }

    handleMutations(mutations) {
        for (const mutation of mutations) {
            this.processNewMessages(mutation.target);
        }
    }

    processNewMessages(node) {
        const messageElements = this.findMessageElements(node);
        for (const element of messageElements) {
            if (!this.processedMessages.has(element.id)) {
                const messageText = this.extractMessageText(element);
                if (messageText) {
                    this.messageQueue.add({
                        text: messageText,
                        timestamp: Date.now(),
                        elementId: element.id || this.generateMessageId()
                    });
                    this.processedMessages.add(element.id);
                }
            }
        }
    }

    findMessageElements(node) {
        // Platform-specific message element selectors
        const selectors = {
            'chat.openai.com': '.message-content',
            'messenger.com': '.message-bubble',
            'web.whatsapp.com': '.message-in'
        };

        const domain = window.location.hostname;
        const selector = selectors[domain] || '.message';
        return Array.from(node.querySelectorAll(selector));
    }

    extractMessageText(element) {
        // Remove any UI elements or metadata, return only the message content
        const textContent = element.textContent.trim();
        return textContent.length > 0 ? textContent : null;
    }

    generateMessageId() {
        return `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    }
}

// Style injector for custom UI elements
class StyleInjector {
    static inject() {
        const styles = `
            .chat-response-container {
                margin: 10px 0;
                padding: 12px;
                border-radius: 8px;
                background-color: #f8f9fa;
                border: 1px solid #e9ecef;
            }

            .response-header {
                display: flex;
                justify-content: space-between;
                margin-bottom: 8px;
            }

            .ai-tag {
                background-color: #007bff;
                color: white;
                padding: 2px 6px;
                border-radius: 4px;
                font-size: 12px;
            }

            .confidence {
                color: #6c757d;
                font-size: 12px;
            }

            .response-content {
                line-height: 1.5;
                color: #212529;
            }

            .ai-response-bubble {
                margin: 8px;
                padding: 10px;
                background-color: #e3f2fd;
                border-radius: 8px;
                max-width: 80%;
                word-wrap: break-word;
            }

            .extension-response {
                margin: 8px 0;
                padding: 10px;
                background-color: #f1f3f4;
                border-left: 4px solid #1a73e8;
                border-radius: 4px;
            }
        `;

        const styleElement = document.createElement('style');
        styleElement.textContent = styles;
        document.head.appendChild(styleElement);
    }
}

// Extension initialization
function initializeExtension() {
    // Inject custom styles
    StyleInjector.inject();

    // Initialize message handling
    const messageQueue = new MessageQueue();
    const messageObserver = new MessageObserver(messageQueue);
    messageObserver.start();

    // Listen for messages from popup
    chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
        if (request.action === 'getPageMessages') {
            const messages = Array.from(messageObserver.processedMessages);
            sendResponse({ messages });
        }
        return true;
    });

    // Cleanup on window unload
    window.addEventListener('unload', () => {
        messageObserver.stop();
    });
}

// Start the extension
initializeExtension();

manifest.json
{
  "manifest_version": 3,
  "name": "Advanced Chat Responder",
  "version": "1.2",
  "description": "An advanced browser extension for auto-responding to chats with AI capabilities.",
  "permissions": [
    "activeTab",
    "storage",
    "tabs",
    "webNavigation",
    "scripting",
    "notifications"
  ],
  "host_permissions": [
    "ws://localhost:8765/*",
    "https://*.huggingface.co/*",
    "<all_urls>"
  ],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  },
  "background": {
    "service_worker": "background.js",
    "type": "module"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["contentScript.js"],
      "css": ["styles/content.css"]
    }
  ],
  "web_accessible_resources": [
    {
      "resources": [
        "assets/*",
        "styles/*"
      ],
      "matches": ["<all_urls>"]
    }
  ],
  "icons": {
    "16": "icons/icon16.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  },
  "options_page": "options.html",
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self'",
    "sandbox": "sandbox allow-scripts allow-forms allow-popups allow-modals; script-src 'self' 'unsafe-inline' 'unsafe-eval'; child-src 'self';"
  },
  "minimum_chrome_version": "88"
}

options.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Advanced Chat Responder Settings</title>
    <style>
        :root {
            --primary-color: #007bff;
            --secondary-color: #6c757d;
            --success-color: #28a745;
            --danger-color: #dc3545;
            --light-bg: #f8f9fa;
            --dark-bg: #343a40;
            --border-color: #dee2e6;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, sans-serif;
            line-height: 1.6;
            margin: 0;
            padding: 20px;
            background-color: var(--light-bg);
        }

        .container {
            max-width: 800px;
            margin: 0 auto;
            background-color: white;
            padding: 24px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }

        h1 {
            color: var(--primary-color);
            margin-bottom: 24px;
            padding-bottom: 12px;
            border-bottom: 2px solid var(--border-color);
        }

        .section {
            margin-bottom: 24px;
            padding: 16px;
            background-color: var(--light-bg);
            border-bottom: 2px solid var(--border-color);
        }

popup.html
<!DOCTYPE html>
<html>
<head>
  <title>Advanced Chat Responder</title>
  <style>
    /* Advanced styling for a better UI */
    body { font-family: Arial, sans-serif; width: 500px; height: 400px; }
    #inputText { width: 100%; height: 100px; padding: 10px; }
    #outputText { width: 100%; height: 150px; padding: 10px; }
    .buttons { margin-top: 10px; }
    button { margin: 5px; padding: 10px; }
  </style>
</head>
<body>
  <h1>Advanced Chat Responder</h1>
  <textarea id="inputText" placeholder="Enter or paste your message here..."></textarea>
  <textarea id="outputText" readonly></textarea>
  <div class="buttons">
    <button id="nextButton">Next Response</button>
    <button id="generateNewButton">Generate New Responses</button>
    <button id="translateButton">Translate to English</button>
    <span id="language Detected"></span>
  </div>

  <script src="popup.js"></script>
</body>
</html>

popup.js
// popup.js
class PopupManager {
  constructor() {
      this.socket = null;
      this.currentResponseIndex = 0;
      this.responses = [];
      this.detectedLanguage = null;
      this.isProcessing = false;
      this.messageHistory = [];
      
      // UI Elements
      this.elements = {
          inputText: document.getElementById('inputText'),
          outputText: document.getElementById('outputText'),
          nextButton: document.getElementById('nextButton'),
          generateNewButton: document.getElementById('generateNewButton'),
          translateButton: document.getElementById('translateButton'),
          languageDetected: document.getElementById('languageDetected'),
      };

      this.initializeWebSocket();
      this.setupEventListeners();
      this.loadSettings();
  }

  initializeWebSocket() {
      this.socket = new WebSocket('ws://127.0.0.1:8765');
      
      this.socket.onopen = () => {
          console.log('WebSocket Connected');
          this.updateConnectionStatus(true);
      };

      this.socket.onclose = () => {
          console.log('WebSocket Disconnected');
          this.updateConnectionStatus(false);
          // Attempt to reconnect after 5 seconds
          setTimeout(() => this.initializeWebSocket(), 5000);
      };

      this.socket.onerror = (error) => {
          console.error('WebSocket Error:', error);
          this.showError('Connection error occurred');
      };

      this.socket.onmessage = (event) => this.handleWebSocketMessage(event);
  }

  async setupEventListeners() {
      // Button click handlers
      this.elements.nextButton.addEventListener('click', () => this.showNextResponse());
      this.elements.generateNewButton.addEventListener('click', () => this.generateNewResponses());
      this.elements.translateButton.addEventListener('click', () => this.translateToEnglish());
      
      // Input text handlers
      this.elements.inputText.addEventListener('input', this.debounce(() => {
          this.saveInputText();
          this.checkLanguage();
      }, 500));

      // Initialize communication with content script
      this.initializeContentScriptConnection();
  }

  async initializeContentScriptConnection() {
      try {
          const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
          if (tab?.id) {
              chrome.tabs.sendMessage(tab.id, { action: 'getPageMessages' }, 
                  (response) => {
                      if (response?.messages) {
                          this.messageHistory = response.messages;
                          this.updateMessageHistory();
                      }
                  }
              );
          }
      } catch (error) {
          console.error('Error connecting to content script:', error);
      }
  }

  handleWebSocketMessage(event) {
      try {
          const data = JSON.parse(event.data);
          switch (data.action) {
              case 'responses':
                  this.handleResponses(data);
                  break;
              case 'translation':
                  this.handleTranslation(data);
                  break;
              case 'error':
                  this.showError(data.message);
                  break;
              case 'languageDetected':
                  this.updateLanguageDisplay(data.language);
                  break;
              default:
                  console.warn('Unknown message type:', data.action);
          }
      } catch (error) {
          console.error('Error handling WebSocket message:', error);
          this.showError('Error processing server response');
      }
  }

  handleResponses(data) {
      this.responses = data.responses;
      this.detectedLanguage = data.detectedLanguage;
      this.currentResponseIndex = 0;
      this.updateLanguageDisplay(this.detectedLanguage);
      this.showResponse();
      this.saveToHistory(data);
  }

  handleTranslation(data) {
      this.elements.outputText.value = data.translation;
      this.elements.translateButton.disabled = false;
  }

  showNextResponse() {
      if (this.responses.length > 0) {
          this.currentResponseIndex = (this.currentResponseIndex + 1) % this.responses.length;
          this.showResponse();
      }
  }

  async checkLanguage() {
    const inputText = this.elements.inputText.value.trim();
    if (inputText) {
      try {
        this.socket.send(JSON.stringify({
          action: 'detectLanguage',
          text: inputText,
        }));
      } catch (error) {
        console.error('Error detecting language:', error);
        this.showError('Language detection failed');
      }
    }
  }

  async generateNewResponses() {
      if (this.isProcessing) return;
      
      const inputText = this.elements.inputText.value.trim();
      if (!inputText) {
          this.showError('Please enter some text');
          return;
      }

      this.isProcessing = true;
      this.elements.generateNewButton.disabled = true;
      
      try {
          this.socket.send(JSON.stringify({
              action: 'processText',
              text: inputText,
              options: await this.getProcessingOptions()
          }));
      } catch (error) {
          console.error('Error generating responses:', error);
          this.showError('Failed to generate responses');
      } finally {
          this.isProcessing = false;
          this.elements.generateNewButton.disabled = false;
      }
  }

  async translateToEnglish() {
      const outputText = this.elements.outputText.value.trim();
      if (!outputText) return;

      this.elements.translateButton.disabled = true;
      
      try {
          this.socket.send(JSON.stringify({
              action: 'translateToEnglish',
              text: outputText
          }));
      } catch (error) {
          console.error('Translation error:', error);
          this.showError('Translation failed');
          this.elements.translateButton.disabled = false;
      }
  }

  // Utility Methods
  debounce(func, wait) {
      let timeout;
      return function executedFunction(...args) {
          const later = () => {
              clearTimeout(timeout);
              func(...args);
          };
          clearTimeout(timeout);
          timeout = setTimeout(later, wait);
      };
  }

  showError(message) {
      // Implement error display logic
      console.error(message);
      // You could add a UI element for errors
  }

  async getProcessingOptions() {
      const settings = await chrome.storage.sync.get('processingOptions');
      return settings.processingOptions || {};
  }

  updateConnectionStatus(connected) {
      document.body.classList.toggle('connected', connected);
      document.body.classList.toggle('disconnected', !connected);
  }

  updateLanguageDisplay(language) {
      this.elements.languageDetected.textContent = `Language Detected: ${language}`;
  }

  showResponse() {
      if (this.responses.length > 0) {
          const response = this.responses[this.currentResponseIndex];
          this.elements.outputText.value = response;
          this.updateResponseCounter();
      }
  }

  updateResponseCounter() {
      const counter = document.getElementById('responseCounter');
      if (counter) {
          counter.textContent = `Response ${this.currentResponseIndex + 1}/${this.responses.length}`;
      }
  }

  async saveInputText() {
      try {
          await chrome.storage.local.set({
              lastInput: this.elements.inputText.value
          });
      } catch (error) {
          console.error('Error saving input:', error);
      }
  }

  async loadSettings() {
      try {
          const settings = await chrome.storage.sync.get(['lastInput', 'processingOptions']);
          if (settings.lastInput) {
              this.elements.inputText.value = settings.lastInput;
          }
      } catch (error) {
          console.error('Error loading settings:', error);
      }
  }

  async saveToHistory(data) {
      try {
          const history = await chrome.storage.local.get('messageHistory');
          const messageHistory = history.messageHistory || [];
          messageHistory.unshift({
              input: this.elements.inputText.value,
              responses: data.responses,
              language: data.detectedLanguage,
              timestamp: new Date().toISOString()
          });
          
          // Keep only last 50 entries
          if (messageHistory.length > 50) {
              messageHistory.pop();
          }
          
          await chrome.storage.local.set({ messageHistory });
      } catch (error) {
          console.error('Error saving to history:', error);
      }
  }
}

// Initialize popup
document.addEventListener('DOMContentLoaded', () => {
  new PopupManager();
});