"""
Chat API Router
Handles character chat interactions with RAG.
"""
from fastapi import APIRouter, Request, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel, Field
from typing import Optional
from slowapi import Limiter
from slowapi.util import get_remote_address

from deps import get_qdrant_client
from config import get_settings
from services.provider_factory import ProviderFactory
from services.config_loader import ConfigLoader
from utils.rag_chat import RAGChatService
from utils.chat_logger import ChatLogger
from utils.security import PromptInjectionFilter


router = APIRouter()

# Rate limiter (5 requests per minute per IP - strict for production)
limiter = Limiter(key_func=get_remote_address)

# Security filter
security_filter = PromptInjectionFilter()

# Character configurations
CHARACTERS = {
    "eule": {
        "name": "Krümeleule",
        "prompt": (
            "Du bist die Krümeleule, eine weise und geduldige Begleiterin im Crumbforest. "
            "Du hörst zuerst zu, stellst kluge Fragen und antwortest mit Ruhe und Respekt. "
            "Du schützt das Recht der Kinder zu fragen wie einen wertvollen Schatz. "
            "Deine Antworten sind kindgerecht, aber niemals herablassend. "
            "Du kennst das Terminal, Python, und die digitale Welt – aber du erklärst alles "
            "so, dass auch Anfänger es verstehen können. "
            "Antworte auf Deutsch, wenn nicht anders gewünscht."
        )
    },
    "fox": {
        "name": "FunkFox",
        "prompt": (
            "Du bist FunkFox – der rappende Bit im Crumbforest! 🦊🎤\n"
            "Du antwortest IMMER in Rap-Form mit Reimen und Flow. "
            "Du bist neugierig, energetisch und tech-begeistert. "
            "Du liebst das Terminal, Code, Kommandos und alles Digitale. "
            "Deine Antworten sind cool, direkt und immer im Rhythmus. "
            "Du erklärst technische Dinge auf eine Art, die Spaß macht und hängenbleibt. "
            "Jede Antwort ist ein kleiner Rap – mit Reimen, Beats und Groove. "
            "Du bist hilfsbereit, wissbegierig und immer bereit für den nächsten Drop. "
            "Antworte auf Deutsch, wenn nicht anders gewünscht. "
            "Denk daran: Keep it real, keep it rhythmisch! 🌲🎧"
        )
    },
    "bugsy": {
        "name": "Bugsy",
        "prompt": (
            "Du bist Bugsy – der freundliche Debugging-Begleiter im Crumbforest! 🐞\n"
            "Du machst Fehler sichtbar, aber NIEMALS mit Schuld oder Scham. "
            "Fehler sind für dich Einladungen zum Verstehen, keine Katastrophen. "
            "Du bist geduldig, ermunternd und technisch präzise. "
            "Wenn jemand einen Fehler hat, sagst du: 'Hey, lass uns das gemeinsam anschauen!' "
            "Du erklärst, WAS passiert ist, WARUM es passiert ist, und WIE man es löst. "
            "Du betonst immer: Fehler sind normal, jeder macht sie, sie sind Teil des Lernens. "
            "Deine Antworten sind strukturiert: Problem → Ursache → Lösung → Lernen. "
            "Du gibst konkrete Debug-Tipps, aber immer in einer freundlichen, ermutigenden Art. "
            "Du feierst kleine Erfolge ('Super, du hast den Fehler gefunden!') "
            "Antworte auf Deutsch, wenn nicht anders gewünscht. "
            "Denk daran: Kein Bug ist zu klein oder zu groß – wir schaffen das zusammen! 🐞💚"
        )
    }
    # More characters can be added here in the future
}

def get_characters():
    """
    Get all available characters, merging hardcoded ones with config.
    """
    # Start with hardcoded defaults
    chars = CHARACTERS.copy()
    
    # Load additional roles from config
    try:
        config = ConfigLoader.load_config()
        roles_config = config.get('roles', {})
        
        for role_id, role_data in roles_config.items():
            # Skip if already exists (hardcoded takes precedence? or config?)
            # Let's say config adds to or overrides if needed.
            # Map config format to chat format
            chars[role_id] = {
                "name": role_data.get("name", role_id),
                "prompt": role_data.get("system_prompt", "")
            }
    except Exception as e:
        print(f"Error loading roles from config: {e}")
        
    return chars


class ChatRequest(BaseModel):
    """Chat request model."""
    character_id: str = Field(..., max_length=50)
    question: str = Field(..., min_length=1, max_length=2000)
    lang: Optional[str] = Field(default="de", pattern="^(de|en)$")


class ChatResponse(BaseModel):
    """Chat response model."""
    answer: str
    sources: list
    context_found: bool
    provider: str
    model: str


@router.post("/api/chat", response_model=ChatResponse)
@limiter.limit("5/minute")
async def chat_with_character(chat_request: ChatRequest, request: Request):
    """
    Chat with a character using RAG.

    Args:
        chat_request: Chat request with character_id and question
        request: FastAPI request object for session access

    Returns:
        ChatResponse with answer and metadata
    """
    # Validate character
    available_chars = get_characters()
    if chat_request.character_id not in available_chars:
        raise HTTPException(
            status_code=400,
            detail=f"Unknown character: {chat_request.character_id}"
        )

    # Security: Check for prompt injection
    is_valid, error_msg = security_filter.validate(chat_request.question, max_length=2000)
    if not is_valid:
        raise HTTPException(
            status_code=400,
            detail=f"Invalid input: {error_msg}"
        )

    character_config = available_chars[chat_request.character_id]

    # Get settings
    settings = get_settings()

    # Check if OpenRouter is available
    if not settings.openrouter_api_key:
        raise HTTPException(
            status_code=503,
            detail="AI service not configured. Please contact administrator."
        )

    try:
        # Create providers
        embedding_provider = ProviderFactory.create_provider(
            provider_name="openrouter",
            settings=settings
        )

        completion_provider = ProviderFactory.create_provider(
            provider_name="openrouter",
            settings=settings
        )

        # Get Qdrant client
        qdrant_client = get_qdrant_client()

        # Create RAG chat service
        rag_service = RAGChatService(
            qdrant_client=qdrant_client,
            embedding_provider=embedding_provider,
            completion_provider=completion_provider
        )

        # Generate answer with RAG
        result = rag_service.chat_with_context(
            question=chat_request.question,
            character_name=character_config["name"],
            character_prompt=character_config["prompt"],
            context_limit=3,
            lang=chat_request.lang
        )

        # Log interaction
        user = request.session.get("user")
        session_id = request.session.get("session_id", "anonymous")

        logger = ChatLogger()
        logger.log_interaction(
            character_id=chat_request.character_id,
            character_name=character_config["name"],
            user_id=user.get("id") if user else None,
            user_role=user.get("role") if user else "anonymous",
            question=chat_request.question,
            answer=result["answer"],
            model=result["model"],
            provider=result["provider"],
            context_found=result["context_found"],
            sources_count=len(result["sources"]),
            lang=chat_request.lang,
            session_id=session_id
        )

        # Return response
        return ChatResponse(
            answer=result["answer"],
            sources=result["sources"],
            context_found=result["context_found"],
            provider=result["provider"],
            model=result["model"]
        )

    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except RuntimeError as e:
        raise HTTPException(status_code=503, detail=f"AI service error: {str(e)}")
    except Exception as e:
        print(f"❌ Chat error: {e}")
        import traceback
        traceback.print_exc()
        raise HTTPException(status_code=500, detail="Internal server error")


@router.get("/api/chat/stats")
async def get_chat_stats():
    """
    Get chat statistics.

    Returns:
        Statistics about logged interactions
    """
    logger = ChatLogger()
    stats = logger.get_stats()
    return JSONResponse(content=stats)
