import os
from fastapi import FastAPI, UploadFile, File, Form, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from typing import Optional
import uvicorn
from core import AppConfig, StudentNationality
from repositories import StorageRepository, MinIOStorageRepository
from handlers import AudioMessageHandler, TextMessageHandler
from services import (
    AudioService, ChatService, HealthService, ResponseService, 
    ResponseManager, OpenAIService, AgentService
)

class DIContainer:
    def __init__(self):
        self.config = AppConfig.from_env()
        self.storage_repo = MinIOStorageRepository(self.config)
        self.response_manager = ResponseManager()
        
        # Initialize OpenAI and Agent services
        self.openai_service = OpenAIService()
        self.agent_service = AgentService()
        
        # Initialize services
        self.audio_service = AudioService(self.storage_repo, self.config.minio_bucket)
        self.chat_service = ChatService(
            self.storage_repo, 
            self.response_manager, 
            self.config,
            self.openai_service,
            self.agent_service
        )
        self.response_service = ResponseService(self.response_manager, self.audio_service)
        self.health_service = HealthService(self.storage_repo, self.config)

def create_app() -> FastAPI:
    app = FastAPI(title="Unified Chat API with Local Agent")
    
    # Add CORS middleware
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
        expose_headers=["X-Response-Text"],
    )
    
    # Initialize dependencies
    container = DIContainer()
    
    # Print configuration
    print("MinIO Endpoint:", container.config.minio_endpoint)
    print("MinIO Bucket:", container.config.minio_bucket)
    print("OpenAI Service Available:", container.openai_service.is_available())
    print("Agent Service Available:", container.agent_service.is_available())

    from fastapi.responses import FileResponse

    @app.get("/chat-interface")
    async def serve_audio_recorder():
        return FileResponse("static/audio-recorder.html")

    @app.post("/chat")
    async def chat_handler(
        file: Optional[UploadFile] = File(None), 
        text: Optional[str] = Form(None),
        student_id: str = Form("student_001")  # Default student_id, but can be overridden
    ):
        """
        Handles incoming chat messages (either text or audio).
        Generates responses locally using the agent service.
        """
        if not student_id.strip():
            raise HTTPException(status_code=400, detail="Student ID is required")
        
        return container.chat_service.process_message(student_id=student_id, file=file, text=text)

    @app.get("/get-audio-response")
    async def get_audio_response():
        """Fetches the agent's text and audio response."""
        return container.response_service.get_agent_response()

    @app.get("/health")
    async def health_check():
        """Health check endpoint with agent service status"""
        health_status = container.health_service.get_health_status()
        # Add agent service status
        health_status.update({
            "openai_service_status": "available" if container.openai_service.is_available() else "unavailable",
            "agent_service_status": "available" if container.agent_service.is_available() else "unavailable"
        })
        return health_status

    # Agent management endpoints
    @app.get("/conversation/stats")
    async def get_conversation_stats(student_id: str = "student_001"):
        """Get conversation statistics"""
        return container.chat_service.get_agent_stats(student_id)

    @app.post("/conversation/clear")
    async def clear_conversation(student_id: str = Form("student_001")):
        """Clear conversation history"""
        return container.chat_service.clear_conversation(student_id)

    @app.post("/agent/system-prompt")
    async def set_system_prompt(request: dict):
        """Update the agent's system prompt"""
        prompt = request.get("prompt", "")
        if not prompt:
            raise HTTPException(status_code=400, detail="System prompt cannot be empty")
        return container.chat_service.set_system_prompt(prompt)

    @app.get("/agent/system-prompt")
    async def get_system_prompt():
        """Get the current system prompt"""
        return {
            "system_prompt": container.agent_service.system_prompt,
            "status": "success"
        }

    @app.get("/conversation/export")
    async def export_conversation(student_id: str = "student_001"):
        """Export conversation history"""
        history = container.agent_service.export_conversation(student_id)
        return {
            "student_id": student_id,
            "messages": history,
            "total_messages": len(history)
        }

    @app.post("/conversation/import")
    async def import_conversation(request: dict):
        """Import conversation history"""
        student_id = request.get("student_id", "student_001")
        messages = request.get("messages", [])
        
        if not messages:
            raise HTTPException(status_code=400, detail="Messages list cannot be empty")
        
        container.agent_service.import_conversation(messages, student_id)
        return {
            "status": "success",
            "message": f"Imported {len(messages)} messages to conversation {student_id}"
        }

    @app.get("/")
    async def root():
        """Root endpoint with API info"""
        return {
            "service": "Unified Chat API with Local Agent",
            "version": "2.1.0",
            "description": "Unified backend for audio/text chat with a local AI agent.",
            "features": [
                "Local AI agent responses using OpenAI GPT",
                "Audio transcription using OpenAI Whisper",
                "Text-to-speech using OpenAI TTS",
                "Conversation history management",
                "Student-specific conversations"
            ],
            "endpoints": {
                "chat": "/chat (accepts audio or text with student_id, generates local agent response)",
                "get_audio_response": "/get-audio-response (fetches agent's audio and text response)",
                "conversation_stats": "/conversation/stats (get conversation statistics)",
                "clear_conversation": "/conversation/clear (clear conversation history)",
                "set_system_prompt": "/agent/system-prompt (update agent system prompt)",
                "export_conversation": "/conversation/export (export conversation history)",
                "health": "/health (service health check)"
            }
        }
    
    return app

# Application entry point
app = create_app()

if __name__ == "__main__":
    try:
        uvicorn.run(app, host="0.0.0.0", port=8000)
    except Exception as e:
        print(f"Application failed to start: {e}", flush=True)
        import sys
        sys.exit(1)
