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

console = Console()


class PluginInstaller:
    DEFAULT_PLUGIN_SERVER = 'https://b980a83b-350b-4565-9b87-cd4e21ce0df5-00-ubpnkgnd7kvn.spock.replit.dev'
    
    def __init__(self, server_url=None):
        # Try to get server URL from parameter, database settings, environment, then default
        self.server_url = server_url or 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 default"""
        # Try to query the default server's config API
        try:
            config_url = f'{self.DEFAULT_PLUGIN_SERVER}/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 environment variable
        env_url = os.environ.get('PLUGIN_SERVER_URL')
        if env_url:
            return self._normalize_url(env_url)
        
        # 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 default server
        return self._normalize_url(self.DEFAULT_PLUGIN_SERVER)
    
    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"
        
        try:
            response = requests.get(download_url, timeout=30)
            
            if response.status_code == 404:
                console.print(f"[red]✗ Plugin '{plugin_name}' not found[/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"[red]✗ Could not connect to plugin server[/red]")
            console.print(f"[yellow]Please check your internet connection and try again[/yellow]")
            return False
        except requests.exceptions.Timeout:
            console.print(f"[red]✗ Connection timed out[/red]")
            return False
        except Exception as e:
            console.print(f"[red]✗ Error installing plugin: {e}[/red]")
            return False
    
    def list_installed(self):
        """List all installed plugins"""
        if not self.plugins_dir.exists():
            console.print("[yellow]No plugins installed yet[/yellow]")
            return
        
        plugins = [d for d in self.plugins_dir.iterdir() if d.is_dir()]
        
        if not plugins:
            console.print("[yellow]No plugins installed yet[/yellow]")
            return
        
        console.print("[cyan]Installed plugins:[/cyan]")
        for plugin in sorted(plugins):
            console.print(f"  • {plugin.name}")
        
        console.print(f"\n[dim]Total: {len(plugins)} plugin(s)[/dim]")
