import os
import requests
import zipfile
from pathlib import Path
from rich.console import Console
from rich.progress import Progress

console = Console()


class PluginInstaller:
    def __init__(self):
        # Try to get server URL from database settings first, then environment, then default
        self.server_url = self._get_server_url()
        self.plugins_dir = Path.home() / '.feather' / 'plugins'
        self.plugins_dir.mkdir(parents=True, exist_ok=True)
    
    def _normalize_url(self, url: str) -> str:
        """Normalize a URL to ensure it has protocol and no trailing slash"""
        if not url:
            return ''
        
        url = url.rstrip('/')
        
        # Add protocol if missing
        if not url.startswith(('http://', 'https://')):
            url = f'https://{url}'
        
        return url
    
    def _get_server_url(self):
        """Get plugin server URL from API config endpoint, environment, or database"""
        # First, try to get the base server URL
        base_url = os.environ.get('PLUGIN_SERVER_URL')
        
        if not base_url:
            # Check if we're on Replit
            replit_domain = os.environ.get('REPLIT_DOMAINS')
            if replit_domain:
                base_url = f'https://{replit_domain}'
        
        # If we have a base URL, try to fetch config from the API
        if base_url:
            try:
                # Get base domain without any API paths
                base_domain = base_url.split('/api')[0].rstrip('/')
                config_url = f'{base_domain}/api/config'
                response = requests.get(config_url, timeout=5)
                if response.status_code == 200:
                    config = response.json()
                    server_url = config.get('plugin_server_url')
                    if server_url:
                        return self._normalize_url(server_url)
            except Exception:
                pass
        
        # Try to get from local database (if running on same machine as server)
        try:
            from admin.models import admin_db
            db_url = admin_db.get_setting('plugin_server_url')
            if db_url:
                return self._normalize_url(db_url)
        except Exception:
            pass
        
        # Fall back to environment variable or default
        fallback = os.environ.get('PLUGIN_SERVER_URL', 'http://localhost:5000')
        return self._normalize_url(fallback)
    
    def install(self, plugin_name: str):
        """Download and install a plugin from the server"""
        console.print(f"[cyan]Installing plugin: {plugin_name}[/cyan]")
        
        # Construct the download URL
        # Check if server_url already has /api/plugins path
        if '/api/plugins' in self.server_url:
            download_url = f"{self.server_url}/{plugin_name}/download"
        else:
            download_url = f"{self.server_url}/api/plugins/{plugin_name}/download"
        
        console.print(f"[dim]Downloading from: {download_url}[/dim]")
        
        try:
            response = requests.get(download_url)
            
            if response.status_code == 404:
                console.print(f"[red]Plugin '{plugin_name}' not found on server[/red]")
                return False
            
            if response.status_code != 200:
                console.print(f"[red]Failed to download plugin: HTTP {response.status_code}[/red]")
                return False
            
            plugin_path = self.plugins_dir / plugin_name
            plugin_path.mkdir(parents=True, exist_ok=True)
            
            zip_path = plugin_path / f"{plugin_name}.zip"
            with open(zip_path, 'wb') as f:
                f.write(response.content)
            
            with zipfile.ZipFile(zip_path, 'r') as zip_ref:
                zip_ref.extractall(plugin_path)
            
            zip_path.unlink()
            
            console.print(f"[green]✓ Plugin '{plugin_name}' installed successfully[/green]")
            return True
            
        except requests.exceptions.ConnectionError:
            console.print(f"[yellow]Warning: Could not connect to plugin server at {self.server_url}[/yellow]")
            console.print(f"[yellow]Plugin '{plugin_name}' will be loaded from local plugins/ directory if available[/yellow]")
            return False
        except Exception as e:
            console.print(f"[red]Error installing plugin: {e}[/red]")
            return False
