# app.py
from flask import Flask, request, jsonify, abort
from flask_cors import CORS
from googletrans import Translator
import requests
import os
import json
from datetime import datetime
import sqlite3
from functools import wraps
import logging
from typing import Dict, List, Optional
import time

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('chat_app.log'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

app = Flask(__name__)
CORS(app)

# Configuration
class Config:
    HUGGINGFACE_API_KEY = os.getenv('HUGGINGFACE_API_KEY')
    DATABASE_PATH = 'chat_history.db'
    CACHE_TIMEOUT = 3600  # 1 hour
    MAX_RETRIES = 3
    RETRY_DELAY = 1  # seconds

# Initialize translator
translator = Translator()

# Cache for API responses
response_cache: Dict[str, Dict] = {}

def init_db():
    """Initialize SQLite database for chat history and user settings"""
    with sqlite3.connect(Config.DATABASE_PATH) as conn:
        conn.execute('''
        CREATE TABLE IF NOT EXISTS chat_history (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            session_id TEXT,
            timestamp DATETIME,
            user_message TEXT,
            bot_response TEXT,
            model_name TEXT,
            language TEXT
        )
        ''')
        
        conn.execute('''
        CREATE TABLE IF NOT EXISTS user_settings (
            session_id TEXT PRIMARY KEY,
            preferred_language TEXT,
            theme TEXT,
            custom_models TEXT
        )
        ''')
        conn.commit()

def require_api_key(f):
    """Decorator to check for valid API key"""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not Config.HUGGINGFACE_API_KEY:
            return jsonify({'error': 'Huggingface API key not configured'}), 401
        return f(*args, **kwargs)
    return decorated_function

def cache_response(key: str, response: Dict):
    """Cache API response with timestamp"""
    response_cache[key] = {
        'data': response,
        'timestamp': time.time()
    }

def get_cached_response(key: str) -> Optional[Dict]:
    """Get cached response if still valid"""
    if key in response_cache:
        cache_entry = response_cache[key]
        if time.time() - cache_entry['timestamp'] < Config.CACHE_TIMEOUT:
            return cache_entry['data']
        del response_cache[key]
    return None

def query_huggingface_api(model_name: str, input_text: str) -> Dict:
    """Query Huggingface Inference API with retry logic"""
    headers = {
        "Authorization": f"Bearer {Config.HUGGINGFACE_API_KEY}",
        "Content-Type": "application/json"
    }
    
    data = {
        "inputs": input_text,
        "parameters": {
            "max_length": 100,
            "temperature": 0.7,
            "top_p": 0.9
        }
    }
    
    for attempt in range(Config.MAX_RETRIES):
        try:
            response = requests.post(
                f"https://api-inference.huggingface.co/models/{model_name}",
                headers=headers,
                json=data
            )
            response.raise_for_status()
            return response.json()
        except requests.exceptions.RequestException as e:
            if attempt == Config.MAX_RETRIES - 1:
                raise Exception(f"Failed to query Huggingface API: {str(e)}")
            time.sleep(Config.RETRY_DELAY)

def save_chat_history(session_id: str, user_message: str, bot_response: str, 
                     model_name: str, language: str):
    """Save chat interaction to database"""
    try:
        with sqlite3.connect(Config.DATABASE_PATH) as conn:
            conn.execute('''
            INSERT INTO chat_history 
            (session_id, timestamp, user_message, bot_response, model_name, language)
            VALUES (?, ?, ?, ?, ?, ?)
            ''', (session_id, datetime.now(), user_message, bot_response, 
                 model_name, language))
            conn.commit()
    except sqlite3.Error as e:
        logger.error(f"Database error: {e}")

@app.route('/chat', methods=['POST'])
@require_api_key
def chat():
    try:
        data = request.json
        text = data.get('text')
        model_name = data.get('model')
        session_id = data.get('session_id')
        
        if not all([text, model_name, session_id]):
            return jsonify({'error': 'Missing required parameters'}), 400
        
        # Check cache
        cache_key = f"{model_name}:{text}"
        cached_response = get_cached_response(cache_key)
        if cached_response:
            return jsonify({'response': cached_response})
        
        # Query Huggingface API
        api_response = query_huggingface_api(model_name, text)
        
        if isinstance(api_response, list):
            response_text = api_response[0].get('generated_text', '')
        else:
            response_text = api_response.get('generated_text', '')
        
        # Cache the response
        cache_response(cache_key, response_text)
        
        # Save to chat history
        save_chat_history(session_id, text, response_text, model_name, 
                         data.get('language', 'en'))
        
        return jsonify({'response': response_text})
    
    except Exception as e:
        logger.error(f"Error in chat endpoint: {str(e)}")
        return jsonify({'error': str(e)}), 500

@app.route('/translate', methods=['POST'])
def translate():
    try:
        data = request.json
        text = data.get('text')
        target_lang = data.get('target_lang')
        
        if not all([text, target_lang]):
            return jsonify({'error': 'Missing required parameters'}), 400
        
        translated = translator.translate(text, dest=target_lang)
        return jsonify({'translated_text': translated.text})
    
    except Exception as e:
        logger.error(f"Error in translate endpoint: {str(e)}")
        return jsonify({'error': str(e)}), 500

@app.route('/settings', methods=['GET', 'POST'])
def user_settings():
    try:
        if request.method == 'POST':
            data = request.json
            session_id = data.get('session_id')
            
            if not session_id:
                return jsonify({'error': 'Missing session_id'}), 400
            
            with sqlite3.connect(Config.DATABASE_PATH) as conn:
                conn.execute('''
                INSERT OR REPLACE INTO user_settings 
                (session_id, preferred_language, theme, custom_models)
                VALUES (?, ?, ?, ?)
                ''', (session_id, data.get('preferred_language'), 
                      data.get('theme'), json.dumps(data.get('custom_models', []))))
                conn.commit()
            
            return jsonify({'status': 'success'})
        
        else:  # GET
            session_id = request.args.get('session_id')
            
            if not session_id:
                return jsonify({'error': 'Missing session_id'}), 400
            
            with sqlite3.connect(Config.DATABASE_PATH) as conn:
                cursor = conn.execute('''
                SELECT preferred_language, theme, custom_models 
                FROM user_settings WHERE session_id = ?
                ''', (session_id,))
                row = cursor.fetchone()
                
                if row:
                    return jsonify({
                        'preferred_language': row[0],
                        'theme': row[1],
                        'custom_models': json.loads(row[2]) if row[2] else []
                    })
                return jsonify({
                    'preferred_language': 'en',
                    'theme': 'light',
                    'custom_models': []
                })
    
    except Exception as e:
        logger.error(f"Error in settings endpoint: {str(e)}")
        return jsonify({'error': str(e)}), 500

@app.route('/chat_history', methods=['GET'])
def get_chat_history():
    try:
        session_id = request.args.get('session_id')
        limit = request.args.get('limit', 50)
        
        if not session_id:
            return jsonify({'error': 'Missing session_id'}), 400
        
        with sqlite3.connect(Config.DATABASE_PATH) as conn:
            cursor = conn.execute('''
            SELECT timestamp, user_message, bot_response, model_name, language
            FROM chat_history 
            WHERE session_id = ?
            ORDER BY timestamp DESC
            LIMIT ?
            ''', (session_id, limit))
            
            history = [{
                'timestamp': row[0],
                'user_message': row[1],
                'bot_response': row[2],
                'model_name': row[3],
                'language': row[4]
            } for row in cursor.fetchall()]
            
            return jsonify({'history': history})
    
    except Exception as e:
        logger.error(f"Error in chat_history endpoint: {str(e)}")
        return jsonify({'error': str(e)}), 500

@app.before_first_request
def setup():
    init_db()

if __name__ == '__main__':
    app.run(debug=True)

// manifest.json
{
  "manifest_version": 3,
  "name": "Enhanced AI Chat Assistant",
  "version": "1.0",
  "description": "Multilingual AI chat assistant with Huggingface models",
  "permissions": [
    "activeTab",
    "storage",
    "unlimitedStorage"
  ],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "images/icon16.png",
      "48": "images/icon48.png",
      "128": "images/icon128.png"
    }
  },
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [{
    "matches": ["<all_urls>"],
    "js": ["content.js"],
    "css": ["styles.css"]
  }],
  "icons": {
    "16": "images/icon16.png",
    "48": "images/icon48.png",
    "128": "images/icon128.png"
  }
}

// styles.css
:root {
  --primary-color: #2563eb;
  --secondary-color: #3b82f6;
  --background-color: #ffffff;
  --text-color: #1f2937;
  --border-color: #e5e7eb;
  --hover-color: #dbeafe;
  --shadow-color: rgba(0, 0, 0, 0.1);
}

[data-theme="dark"] {
  --primary-color: #3b82f6;
  --secondary-color: #60a5fa;
  --background-color: #1f2937;
  --text-color: #f3f4f6;
  --border-color: #374151;
  --hover-color: #2563eb;
  --shadow-color: rgba(0, 0, 0, 0.3);
}

#floating-chat {
  position: fixed;
  bottom: 20px;
  right: 20px;
  width: 400px;
  height: 600px;
  background: var(--background-color);
  border-radius: 12px;
  box-shadow: 0 4px 12px var(--shadow-color);
  z-index: 10000;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: all 0.3s ease;
  font-family: 'Inter', sans-serif;
}

#chat-header {
  padding: 12px 16px;
  background: var(--primary-color);
  color: white;
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: move;
  user-select: none;
}

.header-buttons {
  display: flex;
  gap: 8px;
}

.header-button {
  background: transparent;
  border: none;
  color: white;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.header-button:hover {
  background: rgba(255, 255, 255, 0.2);
}

#chat-container {
  flex-grow: 1;
  overflow-y: auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  scroll-behavior: smooth;
}

.message {
  max-width: 85%;
  padding: 10px 14px;
  border-radius: 12px;
  animation: messageAppear 0.3s ease;
}

@keyframes messageAppear {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.user-message {
  background: var(--primary-color);
  color: white;
  align-self: flex-end;
  border-bottom-right-radius: 4px;
}

.bot-message {
  background: var(--border-color);
  color: var(--text-color);
  align-self: flex-start;
  border-bottom-left-radius: 4px;
}

#input-container {
  padding: 16px;
  border-top: 1px solid var(--border-color);
  background: var(--background-color);
}

.input-wrapper {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
}

#message-input {
  flex-grow: 1;
  padding: 10px;
  border: 1px solid var(--border-color);
  border-radius: 8px;
  outline: none;
  transition: border-color 0.2s;
  background: var(--background-color);
  color: var(--text-color);
}

#message-input:focus {
  border-color: var(--primary-color);
}

.control-button {
  padding: 8px 16px;
  background: var(--primary-color);
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.control-button:hover {
  background: var(--secondary-color);
}

.control-button:disabled {
  background: var(--border-color);
  cursor: not-allowed;
}

.controls {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

#model-info {
  padding: 8px 16px;
  background: var(--border-color);
  color: var(--text-color);
  font-size: 12px;
  text-align: center;
}

.settings-panel {
  position: absolute;
  top: 0;
  right: -300px;
  width: 300px;
  height: 100%;
  background: var(--background-color);
  border-left: 1px solid var(--border-color);
  transition: right 0.3s ease;
  padding: 16px;
  overflow-y: auto;
}

.settings-panel.open {
  right: 0;
}

.settings-section {
  margin-bottom: 20px;
}

.settings-section h3 {
  margin-bottom: 12px;
  color: var(--text-color);
}

.setting-item {
  margin-bottom: 12px;
}

.setting-item label {
  display: block;
  margin-bottom: 4px;
  color: var(--text-color);
}

.setting-item select,
.setting-item input {
  width: 100%;
  padding: 8px;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  background: var(--background-color);
  color: var(--text-color);
}

.chat-history-panel {
  display: none;
  position: absolute;
  top: 0;
  left: -300px;
  width: 300px;
  height: 100%;
  background: var(--background-color);
  border-right: 1px solid var(--border-color);
  transition: left 0.3s ease;
  padding: 16px;
  overflow-y: auto;
}

.chat-history-panel.open {
  left: 0;
  display: block;
}

.history-item {
  padding: 8px;
  border-bottom: 1px solid var(--border-color);
  cursor: pointer;
  transition: background-color 0.2s;
}

.history-item:hover {
  background: var(--hover-color);
}

.loading-spinner {
  display: inline-block;
  width: 20px;
  height: 20px;
  border: 2px solid var(--border-color);
  border-radius: 50%;
  border-top-color: var(--primary-color);
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.tooltip {
  position: relative;
  display: inline-block;
}

.tooltip .tooltip-text {
  visibility: hidden;
  background-color: var(--text-color);
  color: var(--background-color);
  text-align: center;
  padding: 4px 8px;
  border-radius: 4px;
  position: absolute;
  z-index: 1;
  bottom: 125%;
  left: 50%;
  transform: translateX(-50%);
  opacity: 0;
  transition: opacity 0.2s;
  font-size: 12px;
  white-space: nowrap;
}

.tooltip:hover .tooltip-text {
  visibility: visible;
  opacity: 1;
}

/* Responsive design */
@media (max-width: 768px) {
  #floating-chat {
    width: 100%;
    height: 100%;
    bottom: 0;
    right: 0;
    border-radius: 0;
  }
  
  .settings-panel,
  .chat-history-panel {
    width: 100%;
  }
}

// popup.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>AI Chat Assistant Settings</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="settings-container">
    <h2>Chat Assistant Settings</h2>
    <div class="settings-section">
      <h3>General Settings</h3>
      <div class="setting-item">
        <label for="defaultLanguage">Default Language</label>
        <select id="defaultLanguage">
          <option value="en">English</option>
          <option value="de">German</option>
          <option value="es">Spanish</option>
        </select>
      </div>
      <div class="setting-item">
        <label for="theme">Theme</label>
        <select id="theme">
          <option value="light">Light</option>
          <option value="dark">Dark</option>
          <option value="system">System Default</option>
        </select>
      </div>
    </div>
    
    <div class="settings-section">
      <h3>Model Settings</h3>
      <div class="setting-item">
        <label for="customModels">Custom Models</label>
        <div id="customModelsList"></div>
        <button id="addCustomModel" class="control-button">Add Model</button>
      </div>
    </div>
    
    <div class="settings-section">
      <h3>Chat History</h3>
      <div class="setting-item">
        <label>
          <input type="checkbox" id="saveHistory">
          Save chat history
        </label>
      </div>
      <button id="clearHistory" class="control-button">Clear History</button>
    </div>
    
    <div class="settings-section">
      <h3>Advanced Settings</h3>
      <div class="setting-item">
        <label for="apiKey">Huggingface API Key</label>
        <input type="password" id="apiKey" placeholder="Enter your API key">
      </div>
    </div>
  </div>
  <script src="popup.js"></script>
</body>
</html>

// popup.js
document.addEventListener('DOMContentLoaded', function() {
  // Load saved settings
  chrome.storage.local.get([
    'defaultLanguage',
    'theme',
    'customModels',
    'saveHistory',
    'apiKey'
  ], function(result) {
    // Set default language
    if (result.defaultLanguage) {
      document.getElementById('defaultLanguage').value = result.defaultLanguage;
    }
    
    // Set theme
    if (result.theme) {
      document.getElementById('theme').value = result.theme;
    }
    
    // Set custom models
    if (result.customModels) {
      updateCustomModelsList(result.customModels);
    }
    
    // Set save history checkbox
    if (result.saveHistory !== undefined) {
      document.getElementById('saveHistory').checked = result.saveHistory;
    }
    
    // Set API key
    if (result.apiKey) {
      document.getElementById('apiKey').value = result.apiKey;
    }
  });
  
  // Save settings when changed
  document.getElementById('defaultLanguage').addEventListener('change', function(e) {
    chrome.storage.local.set({ defaultLanguage: e.target.value });
  });
  
  document.getElementById('theme').addEventListener('change', function(e) {
    chrome.storage.local.set({ theme: e.target.value });
    applyTheme(e.target.value);
  });
  
  document.getElementById('saveHistory').addEventListener('change', function(e) {
    chrome.storage.local.set({ saveHistory: e.target.checked });
  });
  
  document.getElementById('apiKey').addEventListener('change', function(e) {
    chrome.storage.local.set({ apiKey: e.target.value });
  });
  
  document.getElementById('clearHistory').addEventListener('click', function() {
    if (confirm('Are you sure you want to clear all chat history?')) {
      chrome.storage.local.remove('chatHistory', function() {
        alert('Chat history cleared');
      });
    }
  });
  
  document.getElementById('addCustomModel').addEventListener('click', addCustomModel);
});

function updateCustomModelsList(models) {
  const container = document.getElementById('customModelsList');
  container.innerHTML = '';
  
  models.forEach((model, index) => {
    const div = document.createElement('div');
    div.className = 'custom-model-item';
    div.innerHTML = `
      <input type="text" value="${model}" data-index="${index}">
      <button class="remove-model" data-index="${index}">Remove</button>
    `;
    container.appendChild(div);
  });
  
  // Add event listeners for remove buttons
  document.querySelectorAll('.remove-model').forEach(button => {
    button.addEventListener('click', function() {
      removeCustomModel(parseInt(this.dataset.index));
    });
  });
}

function addCustomModel() {
  chrome.storage.local.get('customModels', function(result) {
    const models = result.customModels || [];
    models.push('');
    chrome.storage.local.set({ customModels: models }, function() {
      updateCustomModelsList(models);
    });
  });
}

function removeCustomModel(index) {
  chrome.storage.local.get('customModels', function(result) {
    const models = result.customModels || [];
    models.splice(index, 1);
    chrome.storage.local.set({ customModels: models }, function() {
      updateCustomModelsList(models);
    });
  });
}

function applyTheme(theme) {
  if (theme === 'system') {
    theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
  }
  document.documentElement.setAttribute('data-theme', theme);
}
// content.js
let chatInterface = null;

class ChatInterface {
  constructor() {
    this.isMinimized = false;
    this.isDragging = false;
    this.dragOffset = { x: 0, y: 0 };
    this.settings = {
      theme: 'light',
      language: 'en',
      customModels: []
    };
    this.currentModel = 'gpt2';
    this.isProcessing = false;
    this.initialize();
  }

  async initialize() {
    // Create the chat interface container
    const container = document.createElement('div');
    container.innerHTML = `
      <div id="floating-chat" class="shadow-lg">
        <div id="chat-header">
          <span>AI Chat Assistant</span>
          <div class="header-buttons">
            <button class="header-button" id="history-btn" title="Chat History">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
              </svg>
            </button>
            <button class="header-button" id="settings-btn" title="Settings">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"/>
              </svg>
            </button>
            <button class="header-button" id="minimize-btn" title="Minimize">−</button>
            <button class="header-button" id="close-btn" title="Close">×</button>
          </div>
        </div>
        
        <div id="chat-container"></div>
        
        <div id="input-container">
          <div class="input-wrapper">
            <textarea id="message-input" placeholder="Type your message..." rows="1"></textarea>
            <button id="send-btn" class="control-button">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z"/>
              </svg>
            </button>
          </div>
          
          <div class="controls">
            <select id="model-select" class="control-button">
              <option value="gpt2">GPT-2</option>
              <option value="bart-large">BART Large</option>
              <option value="t5-base">T5 Base</option>
            </select>
            
            <select id="language-select" class="control-button">
              <option value="en">English</option>
              <option value="es">Spanish</option>
              <option value="fr">French</option>
              <option value="de">German</option>
            </select>
          </div>
        </div>

        <div class="settings-panel">
          <h3>Settings</h3>
          <div class="settings-section">
            <label>Theme</label>
            <select id="theme-select">
              <option value="light">Light</option>
              <option value="dark">Dark</option>
            </select>
          </div>
        </div>

        <div class="chat-history-panel">
          <h3>Chat History</h3>
          <div id="history-container"></div>
        </div>
      </div>
    `;

    document.body.appendChild(container.firstElementChild);
    this.initializeEventListeners();
    await this.loadSettings();
  }

  initializeEventListeners() {
    // Header buttons
    document.getElementById('minimize-btn').addEventListener('click', () => this.toggleMinimize());
    document.getElementById('close-btn').addEventListener('click', () => this.close());
    document.getElementById('settings-btn').addEventListener('click', () => this.toggleSettings());
    document.getElementById('history-btn').addEventListener('click', () => this.toggleHistory());

    // Chat functionality
    document.getElementById('send-btn').addEventListener('click', () => this.sendMessage());
    document.getElementById('message-input').addEventListener('keypress', (e) => {
      if (e.key === 'Enter' && !e.shiftKey) {
        e.preventDefault();
        this.sendMessage();
      }
    });

    // Settings changes
    document.getElementById('theme-select').addEventListener('change', (e) => {
      this.updateTheme(e.target.value);
    });

    document.getElementById('model-select').addEventListener('change', (e) => {
      this.currentModel = e.target.value;
    });

    document.getElementById('language-select').addEventListener('change', (e) => {
      this.settings.language = e.target.value;
      this.saveSettings();
    });

    // Dragging functionality
    this.initializeDragging();
  }

  initializeDragging() {
    const header = document.getElementById('chat-header');
    const chatWindow = document.getElementById('floating-chat');

    header.addEventListener('mousedown', (e) => {
      if (e.target.closest('.header-button')) return;
      
      this.isDragging = true;
      const rect = chatWindow.getBoundingClientRect();
      this.dragOffset = {
        x: e.clientX - rect.left,
        y: e.clientY - rect.top
      };
      
      header.style.cursor = 'grabbing';
    });

    document.addEventListener('mousemove', (e) => {
      if (!this.isDragging) return;
      
      const x = e.clientX - this.dragOffset.x;
      const y = e.clientY - this.dragOffset.y;
      
      chatWindow.style.left = `${x}px`;
      chatWindow.style.top = `${y}px`;
    });

    document.addEventListener('mouseup', () => {
      if (this.isDragging) {
        this.isDragging = false;
        header.style.cursor = 'grab';
      }
    });
  }

  async sendMessage() {
    const input = document.getElementById('message-input');
    const message = input.value.trim();
    
    if (!message || this.isProcessing) return;
    
    this.isProcessing = true;
    input.value = '';
    
    try {
      this.addMessage(message, 'user');
      
      const response = await this.sendToBackground({
        type: 'sendMessage',
        message,
        model: this.currentModel,
        language: this.settings.language
      });
      
      this.addMessage(response.response, 'bot');
      
    } catch (error) {
      this.showError('Failed to send message: ' + error.message);
    } finally {
      this.isProcessing = false;
    }
  }

  addMessage(text, type) {
    const container = document.getElementById('chat-container');
    const messageDiv = document.createElement('div');
    messageDiv.className = `message ${type}-message`;
    messageDiv.textContent = text;
    container.appendChild(messageDiv);
    container.scrollTop = container.scrollHeight;
  }

  showError(message) {
    const errorDiv = document.createElement('div');
    errorDiv.className = 'message error-message';
    errorDiv.textContent = message;
    document.getElementById('chat-container').appendChild(errorDiv);
    setTimeout(() => errorDiv.remove(), 5000);
  }

  toggleMinimize() {
    const chatWindow = document.getElementById('floating-chat');
    this.isMinimized = !this.isMinimized;
    chatWindow.classList.toggle('minimized', this.isMinimized);
  }

  toggleSettings() {
    const settingsPanel = document.querySelector('.settings-panel');
    const isOpen = settingsPanel.classList.toggle('open');
    
    if (isOpen) {
      document.querySelector('.chat-history-panel').classList.remove('open');
    }
  }

  toggleHistory() {
    const historyPanel = document.querySelector('.chat-history-panel');
    const isOpen = historyPanel.classList.toggle('open');
    
    if (isOpen) {
      document.querySelector('.settings-panel').classList.remove('open');
    }
  }

  close() {
    const chatWindow = document.getElementById('floating-chat');
    chatWindow.remove();
    chatInterface = null;
  }

  async loadSettings() {
    try {
      const settings = await this.sendToBackground({ type: 'getSettings' });
      this.settings = { ...this.settings, ...settings };
      this.updateTheme(this.settings.theme);
      document.getElementById('language-select').value = this.settings.language;
    } catch (error) {
      console.error('Failed to load settings:', error);
    }
  }

  updateTheme(theme) {
    document.documentElement.setAttribute('data-theme', theme);
    this.settings.theme = theme;
    this.saveSettings();
  }

  async saveSettings() {
    try {
      await this.sendToBackground({
        type: 'saveSettings',
        settings: this.settings
      });
    } catch (error) {
      console.error('Failed to save settings:', error);
    }
  }

  async sendToBackground(message) {
    return new Promise((resolve, reject) => {
      chrome.runtime.sendMessage(message, response => {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
        } else {
          resolve(response);
        }
      });
    });
  }
}

// Initialize chat interface when clicking the extension icon
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === 'toggleChat') {
    if (!chatInterface) {
      chatInterface = new ChatInterface();
    } else {
      chatInterface.close();
    }
  }
  sendResponse({ success: true });
});

// background.js
class BackgroundService {
  constructor() {
    this.API_ENDPOINT = 'http://localhost:5000';
    this.initializeListeners();
  }

  initializeListeners() {
    // Handle extension icon click
    chrome.action.onClicked.addListener((tab) => {
      chrome.tabs.sendMessage(tab.id, { action: 'toggleChat' });
    });

    // Handle messages from content script
    chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
      switch (request.type) {
        case 'sendMessage':
          this.handleChatMessage(request).then(sendResponse).catch(sendResponse);
          return true;
        
        case 'getSettings':
          this.getSettings().then(sendResponse);
          return true;
        
        case 'saveSettings':
          this.saveSettings(request.settings).then(sendResponse);
          return true;
      }
    });
  }

  async handleChatMessage(request) {
    try {
      const response = await fetch(`${this.API_ENDPOINT}/chat`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          text: request.message,
          model: request.model,
          language: request.language,
          session_id: await this.getSessionId()
        })
      });

      if (!response.ok) {
        throw new Error(`API error: ${response.status}`);
      }

      const data = await response.json();
      return { success: true, response: data.response };

    } catch (error) {
      console.error('API request failed:', error);
      return { success: false, error: error.message };
    }
  }

  async getSettings() {
    return new Promise((resolve) => {
      chrome.storage.local.get({
        theme: 'light',
        language: 'en',
        customModels: []
      }, resolve);
    });
  }

  async saveSettings(settings) {
    return new Promise((resolve) => {
      chrome.storage.local.set(settings, () => resolve({ success: true }));
    });
  }

  async getSessionId() {
    return new Promise((resolve) => {
      chrome.storage.local.get('sessionId', (result) => {
        const sessionId = result.sessionId || this.generateSessionId();
        if (!result.sessionId) {
          chrome.storage.local.set({ sessionId });
        }
        resolve(sessionId);
      });
    });
  }

  generateSessionId() {
    return 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
  }
}

// Initialize background service
new BackgroundService();

Describe features of the extension above