"""
Consent Admin API Endpoints für BreakPilot
Stellt Admin-Funktionalität für die Verwaltung rechtlicher Dokumente bereit
"""

from fastapi import APIRouter, HTTPException, Header, Query, UploadFile, File
from typing import Optional, List
from pydantic import BaseModel
import httpx
import os
import io

from consent_client import generate_jwt_token, JWT_SECRET

# Try to import mammoth for Word document conversion
try:
    import mammoth
    MAMMOTH_AVAILABLE = True
except ImportError:
    MAMMOTH_AVAILABLE = False

# Consent Service URL
CONSENT_SERVICE_URL = os.getenv("CONSENT_SERVICE_URL", "http://localhost:8081")

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


# Request Models
class CreateDocumentRequest(BaseModel):
    type: str
    name: str
    description: Optional[str] = None
    is_mandatory: bool = True


class UpdateDocumentRequest(BaseModel):
    name: Optional[str] = None
    description: Optional[str] = None
    is_mandatory: Optional[bool] = None
    is_active: Optional[bool] = None
    sort_order: Optional[int] = None


class CreateVersionRequest(BaseModel):
    document_id: str
    version: str
    language: str = "de"
    title: str
    content: str
    summary: Optional[str] = None


class UpdateVersionRequest(BaseModel):
    title: Optional[str] = None
    content: Optional[str] = None
    summary: Optional[str] = None


class CreateCookieCategoryRequest(BaseModel):
    name: str
    display_name_de: str
    display_name_en: Optional[str] = None
    description_de: Optional[str] = None
    description_en: Optional[str] = None
    is_mandatory: bool = False
    sort_order: int = 0


# Admin User UUID (muss in der DB existieren!)
ADMIN_USER_UUID = "a0000000-0000-0000-0000-000000000001"


# Helper für Admin Token
def get_admin_token(authorization: Optional[str]) -> str:
    """
    Extrahiert Admin-Token aus Authorization Header oder generiert einen für Dev.
    In Produktion sollte hier eine echte Admin-Authentifizierung stattfinden.
    """
    if authorization:
        parts = authorization.split(" ")
        if len(parts) == 2 and parts[0] == "Bearer":
            return parts[1]

    # Für Entwicklung: Generiere einen Admin-Token mit gültiger UUID
    return generate_jwt_token(
        user_id=ADMIN_USER_UUID,
        email="admin@breakpilot.app",
        role="admin"
    )


async def proxy_request(method: str, path: str, token: str, json_data=None):
    """Proxied Anfragen an den Go Consent Service"""
    url = f"{CONSENT_SERVICE_URL}/api/v1/admin{path}"
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json"
    }

    async with httpx.AsyncClient() as client:
        try:
            if method == "GET":
                response = await client.get(url, headers=headers, timeout=10.0)
            elif method == "POST":
                response = await client.post(url, headers=headers, json=json_data, timeout=10.0)
            elif method == "PUT":
                response = await client.put(url, headers=headers, json=json_data, timeout=10.0)
            elif method == "DELETE":
                response = await client.delete(url, headers=headers, timeout=10.0)
            else:
                raise HTTPException(status_code=400, detail="Invalid method")

            if response.status_code >= 400:
                error_detail = response.json() if response.content else {"error": "Unknown error"}
                raise HTTPException(status_code=response.status_code, detail=error_detail)

            return response.json() if response.content else {"success": True}

        except httpx.RequestError as e:
            raise HTTPException(status_code=503, detail=f"Consent Service unavailable: {str(e)}")


# ==========================================
# Document Management
# ==========================================

@router.get("/documents")
async def admin_get_documents(authorization: Optional[str] = Header(None)):
    """Gibt alle Dokumente zurück (inkl. inaktive)"""
    token = get_admin_token(authorization)
    return await proxy_request("GET", "/documents", token)


@router.post("/documents")
async def admin_create_document(
    request: CreateDocumentRequest,
    authorization: Optional[str] = Header(None)
):
    """Erstellt ein neues rechtliches Dokument"""
    token = get_admin_token(authorization)
    return await proxy_request("POST", "/documents", token, request.dict())


@router.put("/documents/{doc_id}")
async def admin_update_document(
    doc_id: str,
    request: UpdateDocumentRequest,
    authorization: Optional[str] = Header(None)
):
    """Aktualisiert ein rechtliches Dokument"""
    token = get_admin_token(authorization)
    # Nur nicht-None Werte senden
    data = {k: v for k, v in request.dict().items() if v is not None}
    return await proxy_request("PUT", f"/documents/{doc_id}", token, data)


@router.delete("/documents/{doc_id}")
async def admin_delete_document(
    doc_id: str,
    authorization: Optional[str] = Header(None)
):
    """Deaktiviert ein rechtliches Dokument (Soft-Delete)"""
    token = get_admin_token(authorization)
    return await proxy_request("DELETE", f"/documents/{doc_id}", token)


# ==========================================
# Version Management
# ==========================================

@router.get("/documents/{doc_id}/versions")
async def admin_get_versions(
    doc_id: str,
    authorization: Optional[str] = Header(None)
):
    """Gibt alle Versionen eines Dokuments zurück"""
    token = get_admin_token(authorization)
    return await proxy_request("GET", f"/documents/{doc_id}/versions", token)


@router.post("/versions")
async def admin_create_version(
    request: CreateVersionRequest,
    authorization: Optional[str] = Header(None)
):
    """Erstellt eine neue Dokumentversion"""
    token = get_admin_token(authorization)
    return await proxy_request("POST", "/versions", token, request.dict())


@router.put("/versions/{version_id}")
async def admin_update_version(
    version_id: str,
    request: UpdateVersionRequest,
    authorization: Optional[str] = Header(None)
):
    """Aktualisiert eine Dokumentversion (nur draft Status)"""
    token = get_admin_token(authorization)
    data = {k: v for k, v in request.dict().items() if v is not None}
    return await proxy_request("PUT", f"/versions/{version_id}", token, data)


@router.post("/versions/{version_id}/publish")
async def admin_publish_version(
    version_id: str,
    authorization: Optional[str] = Header(None)
):
    """Veröffentlicht eine Dokumentversion"""
    token = get_admin_token(authorization)
    return await proxy_request("POST", f"/versions/{version_id}/publish", token)


@router.post("/versions/{version_id}/archive")
async def admin_archive_version(
    version_id: str,
    authorization: Optional[str] = Header(None)
):
    """Archiviert eine Dokumentversion"""
    token = get_admin_token(authorization)
    return await proxy_request("POST", f"/versions/{version_id}/archive", token)


@router.delete("/versions/{version_id}")
async def admin_delete_version(
    version_id: str,
    authorization: Optional[str] = Header(None)
):
    """
    Löscht eine Dokumentversion dauerhaft.

    Nur Versionen im Status 'draft' oder 'rejected' können gelöscht werden.
    Veröffentlichte Versionen müssen stattdessen archiviert werden.
    Die Versionsnummer wird nach dem Löschen wieder frei.
    """
    token = get_admin_token(authorization)
    return await proxy_request("DELETE", f"/versions/{version_id}", token)


# ==========================================
# Version Approval Workflow (DSB)
# ==========================================

class ApprovalCommentRequest(BaseModel):
    comment: Optional[str] = None
    scheduled_publish_at: Optional[str] = None  # ISO 8601: "2026-01-01T00:00:00Z"


class RejectRequest(BaseModel):
    comment: str


@router.post("/versions/{version_id}/submit-review")
async def admin_submit_for_review(
    version_id: str,
    authorization: Optional[str] = Header(None)
):
    """Reicht eine Version zur DSB-Prüfung ein"""
    token = get_admin_token(authorization)
    return await proxy_request("POST", f"/versions/{version_id}/submit-review", token)


@router.post("/versions/{version_id}/approve")
async def admin_approve_version(
    version_id: str,
    request: ApprovalCommentRequest = None,
    authorization: Optional[str] = Header(None)
):
    """
    Genehmigt eine Version (nur DSB).

    Mit scheduled_publish_at kann ein Veröffentlichungszeitpunkt festgelegt werden.
    Format: ISO 8601 (z.B. "2026-01-01T00:00:00Z")
    """
    token = get_admin_token(authorization)
    data = request.dict(exclude_none=True) if request else {}
    return await proxy_request("POST", f"/versions/{version_id}/approve", token, data)


@router.post("/versions/{version_id}/reject")
async def admin_reject_version(
    version_id: str,
    request: RejectRequest,
    authorization: Optional[str] = Header(None)
):
    """Lehnt eine Version ab (nur DSB)"""
    token = get_admin_token(authorization)
    return await proxy_request("POST", f"/versions/{version_id}/reject", token, request.dict())


@router.get("/versions/{version_id}/compare")
async def admin_compare_versions(
    version_id: str,
    authorization: Optional[str] = Header(None)
):
    """Vergleicht Version mit aktuell veröffentlichter Version"""
    token = get_admin_token(authorization)
    return await proxy_request("GET", f"/versions/{version_id}/compare", token)


@router.get("/versions/{version_id}/approval-history")
async def admin_get_approval_history(
    version_id: str,
    authorization: Optional[str] = Header(None)
):
    """Gibt die Genehmigungshistorie einer Version zurück"""
    token = get_admin_token(authorization)
    return await proxy_request("GET", f"/versions/{version_id}/approval-history", token)


# ==========================================
# Word Document Import
# ==========================================

@router.post("/versions/upload-word")
async def upload_word_document(
    file: UploadFile = File(...),
    authorization: Optional[str] = Header(None)
):
    """
    Konvertiert ein Word-Dokument (.docx) zu HTML.
    Erfordert mammoth Library.
    """
    if not MAMMOTH_AVAILABLE:
        raise HTTPException(
            status_code=501,
            detail="Word-Import nicht verfügbar. Bitte installieren Sie: pip install mammoth"
        )

    # Prüfe Dateityp
    if not file.filename.lower().endswith(('.docx', '.doc')):
        raise HTTPException(
            status_code=400,
            detail="Nur .docx und .doc Dateien werden unterstützt"
        )

    try:
        # Lese Datei-Inhalt
        content = await file.read()

        # Konvertiere zu HTML mit mammoth
        result = mammoth.convert_to_html(io.BytesIO(content))
        html = result.value

        # Bereinige das HTML für bessere Darstellung
        # Entferne leere Paragraphen
        html = html.replace('<p></p>', '')

        # Sammle Warnungen (z.B. nicht unterstützte Formate)
        messages = [msg.message for msg in result.messages]

        return {
            "html": html,
            "warnings": messages if messages else None,
            "filename": file.filename
        }

    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Fehler bei der Konvertierung: {str(e)}"
        )


# ==========================================
# Scheduled Publishing
# ==========================================

@router.get("/scheduled-versions")
async def admin_get_scheduled_versions(authorization: Optional[str] = Header(None)):
    """Gibt alle für Veröffentlichung geplanten Versionen zurück"""
    token = get_admin_token(authorization)
    return await proxy_request("GET", "/scheduled-versions", token)


@router.post("/scheduled-publishing/process")
async def admin_process_scheduled_publishing(authorization: Optional[str] = Header(None)):
    """
    Verarbeitet alle fälligen geplanten Veröffentlichungen.
    Sollte von einem Cronjob regelmäßig aufgerufen werden.
    """
    token = get_admin_token(authorization)
    return await proxy_request("POST", "/scheduled-publishing/process", token)


# ==========================================
# Cookie Category Management
# ==========================================

@router.get("/cookies/categories")
async def admin_get_cookie_categories(authorization: Optional[str] = Header(None)):
    """Gibt alle Cookie-Kategorien zurück"""
    token = get_admin_token(authorization)
    return await proxy_request("GET", "/cookies/categories", token)


@router.post("/cookies/categories")
async def admin_create_cookie_category(
    request: CreateCookieCategoryRequest,
    authorization: Optional[str] = Header(None)
):
    """Erstellt eine neue Cookie-Kategorie"""
    token = get_admin_token(authorization)
    return await proxy_request("POST", "/cookies/categories", token, request.dict())


@router.put("/cookies/categories/{cat_id}")
async def admin_update_cookie_category(
    cat_id: str,
    request: dict,
    authorization: Optional[str] = Header(None)
):
    """Aktualisiert eine Cookie-Kategorie"""
    token = get_admin_token(authorization)
    return await proxy_request("PUT", f"/cookies/categories/{cat_id}", token, request)


@router.delete("/cookies/categories/{cat_id}")
async def admin_delete_cookie_category(
    cat_id: str,
    authorization: Optional[str] = Header(None)
):
    """Deaktiviert eine Cookie-Kategorie"""
    token = get_admin_token(authorization)
    return await proxy_request("DELETE", f"/cookies/categories/{cat_id}", token)


# ==========================================
# Statistics
# ==========================================

@router.get("/statistics")
async def admin_get_statistics(authorization: Optional[str] = Header(None)):
    """Gibt Statistiken über Consents zurück"""
    token = get_admin_token(authorization)
    return await proxy_request("GET", "/statistics", token)


@router.get("/audit-log")
async def admin_get_audit_log(
    page: int = Query(1, ge=1),
    per_page: int = Query(50, ge=1, le=100),
    authorization: Optional[str] = Header(None)
):
    """Gibt das Audit-Log zurück"""
    token = get_admin_token(authorization)
    return await proxy_request("GET", f"/audit-log?page={page}&per_page={per_page}", token)
