"""
Voice Service - PersonaPlex + TaskOrchestrator Integration
Voice-First Interface fuer Breakpilot

DSGVO-konform:
- Keine Audio-Persistenz (nur RAM)
- Namespace-Verschluesselung (Key nur auf Lehrergeraet)
- TTL-basierte Auto-Loeschung

Main FastAPI Application
"""
import structlog
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
import time
from typing import Dict

from config import settings

# Configure structured logging
structlog.configure(
    processors=[
        structlog.stdlib.filter_by_level,
        structlog.stdlib.add_logger_name,
        structlog.stdlib.add_log_level,
        structlog.stdlib.PositionalArgumentsFormatter(),
        structlog.processors.TimeStamper(fmt="iso"),
        structlog.processors.StackInfoRenderer(),
        structlog.processors.format_exc_info,
        structlog.processors.UnicodeDecoder(),
        structlog.processors.JSONRenderer() if not settings.is_development else structlog.dev.ConsoleRenderer(),
    ],
    wrapper_class=structlog.stdlib.BoundLogger,
    context_class=dict,
    logger_factory=structlog.stdlib.LoggerFactory(),
    cache_logger_on_first_use=True,
)

logger = structlog.get_logger(__name__)

# Active WebSocket connections (transient, not persisted)
active_connections: Dict[str, WebSocket] = {}


@asynccontextmanager
async def lifespan(app: FastAPI):
    """Application lifespan manager."""
    # Startup
    logger.info(
        "Starting Voice Service",
        environment=settings.environment,
        port=settings.port,
        personaplex_enabled=settings.personaplex_enabled,
        orchestrator_enabled=settings.orchestrator_enabled,
        audio_persistence=settings.audio_persistence,
    )

    # Verify DSGVO compliance settings
    if settings.audio_persistence:
        logger.error("DSGVO VIOLATION: Audio persistence is enabled!")
        raise RuntimeError("Audio persistence must be disabled for DSGVO compliance")

    # Initialize services
    from services.task_orchestrator import TaskOrchestrator
    from services.encryption_service import EncryptionService

    app.state.orchestrator = TaskOrchestrator()
    app.state.encryption = EncryptionService()

    logger.info("Voice Service initialized successfully")

    yield

    # Shutdown
    logger.info("Shutting down Voice Service")

    # Clear all active connections
    for session_id in list(active_connections.keys()):
        try:
            await active_connections[session_id].close()
        except Exception:
            pass
    active_connections.clear()

    logger.info("Voice Service shutdown complete")


# Create FastAPI app
app = FastAPI(
    title="Breakpilot Voice Service",
    description="Voice-First Interface mit PersonaPlex-7B und Task-Orchestrierung",
    version="1.0.0",
    docs_url="/docs" if settings.is_development else None,
    redoc_url="/redoc" if settings.is_development else None,
    lifespan=lifespan,
)

# CORS middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.cors_origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


# Request timing middleware
@app.middleware("http")
async def add_timing_header(request: Request, call_next):
    """Add X-Process-Time header to all responses."""
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response


# Import and register routers
from api.sessions import router as sessions_router
from api.streaming import router as streaming_router
from api.tasks import router as tasks_router
from api.bqas import router as bqas_router

app.include_router(sessions_router, prefix="/api/v1/sessions", tags=["Sessions"])
app.include_router(tasks_router, prefix="/api/v1/tasks", tags=["Tasks"])
app.include_router(bqas_router, prefix="/api/v1/bqas", tags=["BQAS"])
# Note: streaming router is mounted at root level for WebSocket
app.include_router(streaming_router, tags=["Streaming"])


# Health check endpoint
@app.get("/health", tags=["System"])
async def health_check():
    """
    Health check endpoint for Docker/Kubernetes probes.
    Returns service status and DSGVO compliance verification.
    """
    return {
        "status": "healthy",
        "service": "voice-service",
        "version": "1.0.0",
        "environment": settings.environment,
        "dsgvo_compliance": {
            "audio_persistence": settings.audio_persistence,
            "encryption_enabled": settings.encryption_enabled,
            "transcript_ttl_days": settings.transcript_ttl_days,
            "audit_log_ttl_days": settings.audit_log_ttl_days,
        },
        "backends": {
            "personaplex_enabled": settings.personaplex_enabled,
            "orchestrator_enabled": settings.orchestrator_enabled,
            "fallback_llm": settings.fallback_llm_provider,
        },
        "audio_config": {
            "sample_rate": settings.audio_sample_rate,
            "frame_size_ms": settings.audio_frame_size_ms,
        },
        "active_connections": len(active_connections),
    }


# Root endpoint
@app.get("/", tags=["System"])
async def root():
    """Root endpoint with service information."""
    return {
        "service": "Breakpilot Voice Service",
        "description": "Voice-First Interface fuer Breakpilot",
        "version": "1.0.0",
        "docs": "/docs" if settings.is_development else "disabled",
        "endpoints": {
            "sessions": "/api/v1/sessions",
            "tasks": "/api/v1/tasks",
            "websocket": "/ws/voice",
        },
        "privacy": {
            "audio_stored": False,
            "transcripts_encrypted": True,
            "data_retention": f"{settings.transcript_ttl_days} days",
        },
    }


# Error handlers
@app.exception_handler(404)
async def not_found_handler(request: Request, exc):
    """Handle 404 errors - preserve HTTPException details."""
    from fastapi import HTTPException

    # If this is an HTTPException with a detail, use that
    if isinstance(exc, HTTPException) and exc.detail:
        return JSONResponse(
            status_code=404,
            content={"detail": exc.detail},
        )

    # Generic 404 for route not found
    return JSONResponse(
        status_code=404,
        content={"error": "Not found", "path": str(request.url.path)},
    )


@app.exception_handler(500)
async def internal_error_handler(request: Request, exc):
    """Handle 500 errors."""
    logger.error("Internal server error", path=str(request.url.path), error=str(exc))
    return JSONResponse(
        status_code=500,
        content={"error": "Internal server error"},
    )


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=settings.port,
        reload=settings.is_development,
    )
