"""
LLM Comparison Route - Vergleicht Antworten verschiedener LLM Backends.

Dieses Modul ermoeglicht:
- Parallele Anfragen an OpenAI, Claude, Self-hosted+Tavily, Self-hosted+EduSearch
- Speichern von Vergleichsergebnissen fuer QA
- Parameter-Tuning fuer Self-hosted Modelle
"""

import asyncio
import logging
import uuid
from datetime import datetime, timezone
from typing import Optional
from fastapi import APIRouter, HTTPException, Depends

from ..middleware.auth import verify_api_key
from .comparison_models import (
    ComparisonRequest,
    LLMResponse,
    ComparisonResponse,
    SavedComparison,
    _comparisons_store,
    _system_prompts_store,
)
from .comparison_providers import (
    call_openai,
    call_claude,
    search_tavily,
    search_edusearch,
    call_selfhosted_with_search,
)

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/comparison", tags=["LLM Comparison"])


@router.post("/run", response_model=ComparisonResponse)
async def run_comparison(
    request: ComparisonRequest,
    _: str = Depends(verify_api_key),
):
    """
    Fuehrt LLM-Vergleich durch.

    Sendet den Prompt parallel an alle aktivierten Provider und
    sammelt die Antworten.
    """
    comparison_id = f"cmp-{uuid.uuid4().hex[:12]}"
    tasks = []

    system_prompt = request.system_prompt

    if request.enable_openai:
        tasks.append(("openai", call_openai(request.prompt, system_prompt)))

    if request.enable_claude:
        tasks.append(("claude", call_claude(request.prompt, system_prompt)))

    if request.enable_selfhosted_tavily:
        tavily_results = await search_tavily(request.prompt, request.search_results_count)
        tasks.append((
            "selfhosted_tavily",
            call_selfhosted_with_search(
                request.prompt,
                system_prompt,
                "tavily",
                tavily_results,
                request.selfhosted_model,
                request.temperature,
                request.top_p,
                request.max_tokens,
            )
        ))

    if request.enable_selfhosted_edusearch:
        edu_results = await search_edusearch(
            request.prompt,
            request.search_results_count,
            request.edu_search_filters,
        )
        tasks.append((
            "selfhosted_edusearch",
            call_selfhosted_with_search(
                request.prompt,
                system_prompt,
                "edusearch",
                edu_results,
                request.selfhosted_model,
                request.temperature,
                request.top_p,
                request.max_tokens,
            )
        ))

    responses = []
    if tasks:
        results = await asyncio.gather(*[t[1] for t in tasks], return_exceptions=True)
        for (name, _), result in zip(tasks, results):
            if isinstance(result, Exception):
                responses.append(LLMResponse(
                    provider=name,
                    model="unknown",
                    response="",
                    latency_ms=0,
                    error=str(result),
                ))
            else:
                responses.append(result)

    return ComparisonResponse(
        comparison_id=comparison_id,
        prompt=request.prompt,
        system_prompt=system_prompt,
        responses=responses,
    )


@router.post("/save/{comparison_id}")
async def save_comparison(
    comparison_id: str,
    comparison: ComparisonResponse,
    notes: Optional[str] = None,
    rating: Optional[dict] = None,
    _: str = Depends(verify_api_key),
):
    """Speichert einen Vergleich fuer spaetere Analyse."""
    saved = SavedComparison(
        comparison_id=comparison_id,
        prompt=comparison.prompt,
        system_prompt=comparison.system_prompt,
        responses=comparison.responses,
        notes=notes,
        rating=rating,
        created_at=comparison.created_at,
    )
    _comparisons_store[comparison_id] = saved
    return {"status": "saved", "comparison_id": comparison_id}


@router.get("/history")
async def get_comparison_history(
    limit: int = 50,
    _: str = Depends(verify_api_key),
):
    """Gibt gespeicherte Vergleiche zurueck."""
    comparisons = list(_comparisons_store.values())
    comparisons.sort(key=lambda x: x.created_at, reverse=True)
    return {"comparisons": comparisons[:limit]}


@router.get("/history/{comparison_id}")
async def get_comparison(
    comparison_id: str,
    _: str = Depends(verify_api_key),
):
    """Gibt einen bestimmten Vergleich zurueck."""
    if comparison_id not in _comparisons_store:
        raise HTTPException(status_code=404, detail="Vergleich nicht gefunden")
    return _comparisons_store[comparison_id]


# System Prompt Management

@router.get("/prompts")
async def list_system_prompts(
    _: str = Depends(verify_api_key),
):
    """Listet alle gespeicherten System Prompts."""
    return {"prompts": list(_system_prompts_store.values())}


@router.post("/prompts")
async def create_system_prompt(
    name: str,
    prompt: str,
    _: str = Depends(verify_api_key),
):
    """Erstellt einen neuen System Prompt."""
    prompt_id = f"sp-{uuid.uuid4().hex[:8]}"
    _system_prompts_store[prompt_id] = {
        "id": prompt_id,
        "name": name,
        "prompt": prompt,
        "created_at": datetime.now(timezone.utc).isoformat(),
    }
    return {"status": "created", "prompt_id": prompt_id}


@router.put("/prompts/{prompt_id}")
async def update_system_prompt(
    prompt_id: str,
    name: str,
    prompt: str,
    _: str = Depends(verify_api_key),
):
    """Aktualisiert einen System Prompt."""
    if prompt_id not in _system_prompts_store:
        raise HTTPException(status_code=404, detail="System Prompt nicht gefunden")

    _system_prompts_store[prompt_id].update({
        "name": name,
        "prompt": prompt,
        "updated_at": datetime.now(timezone.utc).isoformat(),
    })
    return {"status": "updated", "prompt_id": prompt_id}


@router.delete("/prompts/{prompt_id}")
async def delete_system_prompt(
    prompt_id: str,
    _: str = Depends(verify_api_key),
):
    """Loescht einen System Prompt."""
    if prompt_id not in _system_prompts_store:
        raise HTTPException(status_code=404, detail="System Prompt nicht gefunden")
    if prompt_id in ["default", "curriculum", "worksheet"]:
        raise HTTPException(status_code=400, detail="Standard-Prompts koennen nicht geloescht werden")

    del _system_prompts_store[prompt_id]
    return {"status": "deleted", "prompt_id": prompt_id}


@router.get("/prompts/{prompt_id}")
async def get_system_prompt(
    prompt_id: str,
    _: str = Depends(verify_api_key),
):
    """Gibt einen System Prompt zurueck."""
    if prompt_id not in _system_prompts_store:
        raise HTTPException(status_code=404, detail="System Prompt nicht gefunden")
    return _system_prompts_store[prompt_id]
