"""Simple HTTP API server for Device Doctor dashboard."""

import sys
import json
import os
import logging
from pathlib import Path
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse

# Add parent directory to path for imports
sys.path.insert(0, str(Path(__file__).parent))

from doctor.diagnostics.analyzer import analyze_system
from doctor.ai.explainer import AIExplainer
from doctor.report.health_score import calculate_health_score
from doctor.report.formatter import format_json_report
from doctor.core.telemetry import get_top_resource_contributors
from doctor.ai.chat_explainer import ChatExplainer


logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


class APIHandler(BaseHTTPRequestHandler):
    """HTTP request handler for Device Doctor API."""
    
    def do_GET(self):
        """Handle GET requests."""
        parsed_path = urlparse(self.path)
        
        if parsed_path.path == '/api/health':
            self.handle_health()
        elif parsed_path.path == '/api/config':
            self.handle_config()
        elif parsed_path.path == '/' or parsed_path.path == '/index.html':
            self.serve_file('dashboard/index.html', 'text/html')
        elif parsed_path.path == '/favicon.ico':
            # Return 204 No Content for favicon requests
            self.send_response(204)
            self.end_headers()
        elif parsed_path.path.startswith('/dashboard/'):
            # Serve static files
            file_path = parsed_path.path[1:]  # Remove leading /
            self.serve_file(file_path)
        else:
            self.send_error(404, "Not Found")
    
    def do_OPTIONS(self):
        """Handle CORS preflight requests."""
        self.send_response(200)
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
        self.end_headers()
    
    def do_POST(self):
        """Handle POST requests."""
        parsed_path = urlparse(self.path)
        
        if parsed_path.path == '/api/chat/explain':
            self.handle_chat_explain()
        elif parsed_path.path == '/api/config':
            self.handle_config()
        else:
            self.send_error(404, "Not Found")
    
    def handle_health(self):
        """Handle /api/health endpoint."""
        try:
            logger.info("Processing health check request...")
            
            # Run diagnostics
            diagnostic_result = analyze_system()
            
            # Generate AI explanations
            explainer = AIExplainer(use_ai=True)
            report = explainer.explain(
                diagnostic_result.symptoms,
                diagnostic_result.matching_rules,
                diagnostic_result.telemetry
            )
            
            # Calculate health score
            health_score = calculate_health_score(diagnostic_result.symptoms)
            
            # Get top resource contributors
            top_contributors = get_top_resource_contributors(diagnostic_result.telemetry)
            
            # Prepare response data
            response_data = {
                "health_score": health_score,
                "summary": report.summary,
                "issues": [issue.model_dump() for issue in report.issues],
                "symptoms": [symptom.to_dict() for symptom in diagnostic_result.symptoms],
                "telemetry": diagnostic_result.telemetry,
                "top_contributors": top_contributors,
                "not_checked": report.not_checked,
                "timestamp": diagnostic_result.telemetry.get("timestamp", 0)
            }
            
            # Send JSON response
            self.send_response(200)
            self.send_header('Content-Type', 'application/json')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(json.dumps(response_data, indent=2).encode('utf-8'))
            
            logger.info("Health check completed successfully")
            
        except Exception as e:
            logger.error(f"Error processing health check: {e}", exc_info=True)
            self.send_error(500, f"Internal Server Error: {str(e)}")
    
    def handle_chat_explain(self):
        """Handle /api/chat/explain endpoint."""
        try:
            content_length = int(self.headers.get('Content-Length', 0))
            post_data = self.rfile.read(content_length)
            
            try:
                request_data = json.loads(post_data.decode('utf-8'))
            except json.JSONDecodeError:
                self.send_error(400, "Invalid JSON")
                return
            
            question = request_data.get('question', '')
            selected_issue = request_data.get('selected_issue')
            dashboard_state = request_data.get('dashboard_state', {})
            
            # Get provider and API key from request or environment
            provider = request_data.get('provider') or os.getenv("AI_PROVIDER", "ollama")
            api_key = request_data.get('api_key') or None
            model = request_data.get('model') or None
            
            if not question:
                self.send_error(400, "Question is required")
                return
            
            try:
                chat_explainer = ChatExplainer(
                    provider=provider,
                    api_key=api_key,
                    model=model
                )
                explanation = chat_explainer.explain(
                    question=question,
                    selected_issue=selected_issue,
                    dashboard_state=dashboard_state
                )
                
                # Send response
                response_data = {
                    "answer": explanation,
                    "confidence": "medium"
                }
                
                self.send_response(200)
                self.send_header('Content-Type', 'application/json')
                self.send_header('Access-Control-Allow-Origin', '*')
                self.end_headers()
                self.wfile.write(json.dumps(response_data).encode('utf-8'))
                
                logger.info("Chat explanation generated successfully")
                
            except Exception as explain_error:
                logger.error(f"Error generating explanation: {explain_error}", exc_info=True)
                # Return error message to user instead of 500
                error_response = {
                    "answer": f"I encountered an error: {str(explain_error)[:200]}. Please check server logs for details.",
                    "confidence": "low"
                }
                self.send_response(200)  # Still return 200 so frontend can display the error
                self.send_header('Content-Type', 'application/json')
                self.send_header('Access-Control-Allow-Origin', '*')
                self.end_headers()
                self.wfile.write(json.dumps(error_response).encode('utf-8'))
            
        except Exception as e:
            logger.error(f"Error processing chat request: {e}", exc_info=True)
            # Try to send a JSON error response
            try:
                error_response = {
                    "answer": f"Server error: {str(e)[:200]}. Please check server logs.",
                    "confidence": "low"
                }
                self.send_response(200)
                self.send_header('Content-Type', 'application/json')
                self.send_header('Access-Control-Allow-Origin', '*')
                self.end_headers()
                self.wfile.write(json.dumps(error_response).encode('utf-8'))
            except:
                self.send_error(500, f"Internal Server Error: {str(e)}")
    
    def handle_config(self):
        """Handle /api/config endpoint for getting/setting AI provider configuration."""
        try:
            if self.command == 'GET':
                # Return current configuration (without sensitive keys)
                config = {
                    "providers": ["ollama", "openai", "gemini", "claude"],
                    "default_provider": os.getenv("AI_PROVIDER", "ollama"),
                    "default_models": {
                        "ollama": "llama3.2",
                        "openai": "gpt-4o-mini",
                        "gemini": "gemini-pro",
                        "claude": "claude-3-haiku-20240307"
                    },
                    "has_openai_key": bool(os.getenv("OPENAI_API_KEY")),
                    "has_gemini_key": bool(os.getenv("GEMINI_API_KEY")),
                    "has_claude_key": bool(os.getenv("ANTHROPIC_API_KEY")),
                    "ollama_url": os.getenv("OLLAMA_URL", "http://localhost:11434")
                }
                
                self.send_response(200)
                self.send_header('Content-Type', 'application/json')
                self.send_header('Access-Control-Allow-Origin', '*')
                self.end_headers()
                self.wfile.write(json.dumps(config).encode('utf-8'))
                
            elif self.command == 'POST':
                # Store configuration (in memory for this session)
                content_length = int(self.headers.get('Content-Length', 0))
                post_data = self.rfile.read(content_length)
                
                try:
                    config_data = json.loads(post_data.decode('utf-8'))
                    provider = config_data.get('provider', 'ollama')
                    api_key = config_data.get('api_key')
                    model = config_data.get('model')
                    
                    # Store in environment for this process (not persistent)
                    if provider:
                        os.environ['AI_PROVIDER'] = provider
                    if api_key:
                        if provider == 'openai':
                            os.environ['OPENAI_API_KEY'] = api_key
                        elif provider == 'gemini':
                            os.environ['GEMINI_API_KEY'] = api_key
                        elif provider == 'claude':
                            os.environ['ANTHROPIC_API_KEY'] = api_key
                    if model:
                        os.environ['AI_MODEL'] = model
                    
                    response = {"status": "success", "message": "Configuration updated"}
                    self.send_response(200)
                    self.send_header('Content-Type', 'application/json')
                    self.send_header('Access-Control-Allow-Origin', '*')
                    self.end_headers()
                    self.wfile.write(json.dumps(response).encode('utf-8'))
                    
                except json.JSONDecodeError:
                    self.send_error(400, "Invalid JSON")
        except Exception as e:
            logger.error(f"Error handling config: {e}", exc_info=True)
            self.send_error(500, f"Internal Server Error: {str(e)}")
    
    def serve_file(self, file_path, content_type=None):
        """Serve static files."""
        try:
            full_path = Path(__file__).parent / file_path
            
            if not full_path.exists():
                self.send_error(404, "File Not Found")
                return
            
            # Determine content type
            if content_type is None:
                if file_path.endswith('.css'):
                    content_type = 'text/css'
                elif file_path.endswith('.js'):
                    content_type = 'application/javascript'
                elif file_path.endswith('.html'):
                    content_type = 'text/html'
                else:
                    content_type = 'application/octet-stream'
            
            with open(full_path, 'rb') as f:
                content = f.read()
            
            self.send_response(200)
            self.send_header('Content-Type', content_type)
            self.end_headers()
            self.wfile.write(content)
            
        except Exception as e:
            logger.error(f"Error serving file {file_path}: {e}")
            self.send_error(500, "Internal Server Error")
    
    def log_message(self, format, *args):
        """Override to use our logger."""
        logger.info("%s - - [%s] %s" % (self.address_string(), self.log_date_time_string(), format % args))


def run_server(port=8000):
    """Run the API server."""
    server_address = ('', port)
    httpd = HTTPServer(server_address, APIHandler)
    logger.info(f"Device Doctor API server starting on http://localhost:{port}")
    logger.info("Press Ctrl+C to stop")
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        logger.info("Server stopped")
        httpd.shutdown()


if __name__ == '__main__':
    import argparse
    parser = argparse.ArgumentParser(description='Device Doctor API Server')
    parser.add_argument('--port', type=int, default=8000, help='Port to run server on')
    args = parser.parse_args()
    run_server(args.port)
