"""
Consent API Endpoints für BreakPilot
Stellt die Consent-Funktionalität über das BreakPilot Backend bereit
"""

from fastapi import APIRouter, HTTPException, Header, Query
from typing import Optional, List
from pydantic import BaseModel

from consent_client import consent_client, DocumentType, generate_demo_token, generate_jwt_token

router = APIRouter(prefix="/consent", tags=["consent"])


# Request/Response Models
class ConsentRequest(BaseModel):
    document_type: str
    version_id: str
    consented: bool = True


class CookieConsentItem(BaseModel):
    category_id: str
    consented: bool


class CookieConsentRequest(BaseModel):
    categories: List[CookieConsentItem]


class DataDeletionRequest(BaseModel):
    reason: Optional[str] = None


# Helper für JWT Token
def get_token(authorization: Optional[str], allow_demo: bool = True) -> str:
    """
    Extrahiert JWT Token aus Authorization Header.
    Falls kein Token vorhanden und allow_demo=True, wird ein Demo-Token generiert.
    """
    if authorization:
        parts = authorization.split(" ")
        if len(parts) == 2 and parts[0] == "Bearer":
            return parts[1]

    if allow_demo:
        # Generiere einen Demo-Token für nicht-authentifizierte Benutzer
        return generate_demo_token()

    raise HTTPException(status_code=401, detail="Authorization header required")


# ==========================================
# Token Endpoints
# ==========================================

@router.get("/token/demo")
async def get_demo_token():
    """
    Generiert einen Demo-Token für nicht-authentifizierte Benutzer.
    Dieser Token ermöglicht das Lesen von öffentlichen Dokumenten.
    """
    token = generate_demo_token()
    return {
        "token": token,
        "type": "Bearer",
        "expires_in": 86400  # 24 Stunden
    }


# ==========================================
# Public Endpoints
# ==========================================

@router.get("/check/{document_type}")
async def check_consent(
    document_type: str,
    language: str = Query("de"),
    authorization: Optional[str] = Header(None)
):
    """
    Prüft ob der Benutzer einem Dokument zugestimmt hat.
    Gibt zurück ob Zustimmung vorliegt und ob sie aktualisiert werden muss.
    """
    token = get_token(authorization)

    try:
        doc_type = DocumentType(document_type)
    except ValueError:
        raise HTTPException(status_code=400, detail=f"Invalid document type: {document_type}")

    status = await consent_client.check_consent(token, doc_type, language)

    return {
        "has_consent": status.has_consent,
        "current_version_id": status.current_version_id,
        "consented_version": status.consented_version,
        "needs_update": status.needs_update,
        "consented_at": status.consented_at
    }


@router.get("/pending")
async def get_pending_consents(
    language: str = Query("de"),
    authorization: Optional[str] = Header(None)
):
    """
    Gibt alle Dokumente zurück, die noch Zustimmung benötigen.
    Nützlich für Anzeige beim Login oder in den Einstellungen.
    """
    token = get_token(authorization)
    pending = await consent_client.get_pending_consents(token, language)

    return {
        "pending_consents": pending,
        "has_pending": len(pending) > 0
    }


@router.get("/documents/{document_type}/latest")
async def get_latest_document(
    document_type: str,
    language: str = Query("de"),
    authorization: Optional[str] = Header(None)
):
    """Holt die aktuellste Version eines rechtlichen Dokuments"""
    token = get_token(authorization)

    doc = await consent_client.get_latest_document(token, document_type, language)

    if not doc:
        raise HTTPException(status_code=404, detail="Document not found")

    return {
        "id": doc.id,
        "document_id": doc.document_id,
        "version": doc.version,
        "language": doc.language,
        "title": doc.title,
        "content": doc.content,
        "summary": doc.summary
    }


@router.post("/give")
async def give_consent(
    request: ConsentRequest,
    authorization: Optional[str] = Header(None)
):
    """Speichert die Zustimmung des Benutzers zu einem Dokument"""
    token = get_token(authorization)

    success = await consent_client.give_consent(
        token,
        request.document_type,
        request.version_id,
        request.consented
    )

    if not success:
        raise HTTPException(status_code=500, detail="Failed to save consent")

    return {"success": True, "message": "Consent saved successfully"}


# ==========================================
# Cookie Consent Endpoints
# ==========================================

@router.get("/cookies/categories")
async def get_cookie_categories(
    language: str = Query("de"),
    authorization: Optional[str] = Header(None)
):
    """Holt alle Cookie-Kategorien für das Cookie-Banner"""
    token = get_token(authorization)
    categories = await consent_client.get_cookie_categories(token, language)

    return {"categories": categories}


@router.post("/cookies")
async def set_cookie_consent(
    request: CookieConsentRequest,
    authorization: Optional[str] = Header(None)
):
    """Speichert die Cookie-Präferenzen des Benutzers"""
    token = get_token(authorization)

    categories = [
        {"category_id": cat.category_id, "consented": cat.consented}
        for cat in request.categories
    ]

    success = await consent_client.set_cookie_consent(token, categories)

    if not success:
        raise HTTPException(status_code=500, detail="Failed to save cookie preferences")

    return {"success": True, "message": "Cookie preferences saved"}


# ==========================================
# GDPR / Privacy Endpoints
# ==========================================

@router.get("/privacy/my-data")
async def get_my_data(authorization: Optional[str] = Header(None)):
    """
    GDPR Art. 15: Auskunftsrecht
    Gibt alle über den Benutzer gespeicherten Daten zurück.
    """
    token = get_token(authorization)
    data = await consent_client.get_my_data(token)

    if not data:
        raise HTTPException(status_code=500, detail="Failed to retrieve data")

    return data


@router.post("/privacy/export")
async def request_data_export(authorization: Optional[str] = Header(None)):
    """
    GDPR Art. 20: Recht auf Datenübertragbarkeit
    Fordert einen Export aller Benutzerdaten an.
    """
    token = get_token(authorization)
    request_id = await consent_client.request_data_export(token)

    if not request_id:
        raise HTTPException(status_code=500, detail="Failed to create export request")

    return {
        "success": True,
        "request_id": request_id,
        "message": "Export request created. You will be notified when ready."
    }


@router.post("/privacy/delete")
async def request_data_deletion(
    request: DataDeletionRequest,
    authorization: Optional[str] = Header(None)
):
    """
    GDPR Art. 17: Recht auf Löschung
    Fordert die Löschung aller Benutzerdaten an.
    """
    token = get_token(authorization)
    request_id = await consent_client.request_data_deletion(token, request.reason)

    if not request_id:
        raise HTTPException(status_code=500, detail="Failed to create deletion request")

    return {
        "success": True,
        "request_id": request_id,
        "message": "Deletion request created. We will process it within 30 days."
    }


# ==========================================
# Health Check
# ==========================================

@router.get("/health")
async def consent_health():
    """Prüft die Verbindung zum Consent Service"""
    is_healthy = await consent_client.health_check()

    return {
        "consent_service": "healthy" if is_healthy else "unavailable",
        "connected": is_healthy
    }
