"""
FastAPI routes for Legal Documents — Rechtliche Texte mit Versionierung und Approval-Workflow.

Extended with: Public endpoints, User Consents, Consent Audit Log, Cookie Categories.

Phase 1 Step 4 refactor: handlers delegate to LegalDocumentService and
LegalDocumentConsentService. Module-level helpers re-exported for legacy tests.
"""

import logging
from typing import Any, Optional

from fastapi import APIRouter, Depends, Header, Query, UploadFile, File
from sqlalchemy.orm import Session

from classroom_engine.database import get_db
from compliance.api._http_errors import translate_domain_errors
from compliance.schemas.legal_document import (
    ActionRequest,
    CookieCategoryCreate,
    CookieCategoryUpdate,
    DocumentCreate,
    DocumentResponse,
    UserConsentCreate,
    VersionCreate,
    VersionResponse,
    VersionUpdate,
)
from compliance.services.legal_document_consent_service import (
    LegalDocumentConsentService,
)
from compliance.services.legal_document_service import (
    LegalDocumentService,
    _doc_to_response,  # re-exported for legacy test imports
    _log_approval,  # re-exported for legacy test imports
    _transition,  # re-exported for legacy test imports
    _version_to_response,  # re-exported for legacy test imports
)

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/legal-documents", tags=["legal-documents"])

DEFAULT_TENANT = "9282a473-5c95-4b3a-bf78-0ecc0ec71d3e"


def _get_tenant(
    x_tenant_id: Optional[str] = Header(None, alias="X-Tenant-ID"),
) -> str:
    return x_tenant_id or DEFAULT_TENANT


def _get_doc_service(db: Session = Depends(get_db)) -> LegalDocumentService:
    return LegalDocumentService(db)


def _get_consent_service(
    db: Session = Depends(get_db),
) -> LegalDocumentConsentService:
    return LegalDocumentConsentService(db)


# ============================================================================
# Documents
# ============================================================================


@router.get("/documents", response_model=dict[str, Any])
async def list_documents(
    tenant_id: Optional[str] = Query(None),
    type: Optional[str] = Query(None),
    service: LegalDocumentService = Depends(_get_doc_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.list_documents(tenant_id, type)


@router.get("/documents-with-versions", response_model=dict[str, Any])
async def list_documents_with_versions(
    tenant_id: Optional[str] = Query(None),
    type: Optional[str] = Query(None),
    service: LegalDocumentService = Depends(_get_doc_service),
) -> dict[str, Any]:
    """Listet Docs inkl. jeweils latest + published Version — fuer Library-UI."""
    with translate_domain_errors():
        return service.list_documents_with_versions(tenant_id, type)


@router.post("/documents", response_model=DocumentResponse, status_code=201)
async def create_document(
    request: DocumentCreate,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> DocumentResponse:
    with translate_domain_errors():
        return service.create_document(request)


@router.get("/documents/{document_id}", response_model=DocumentResponse)
async def get_document(
    document_id: str,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> DocumentResponse:
    with translate_domain_errors():
        return service.get_document(document_id)


@router.delete("/documents/{document_id}", status_code=204)
async def delete_document(
    document_id: str,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> None:
    with translate_domain_errors():
        service.delete_document(document_id)


@router.get("/documents/{document_id}/versions", response_model=list[VersionResponse])
async def list_versions(
    document_id: str,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> list[VersionResponse]:
    with translate_domain_errors():
        return service.list_versions_for(document_id)


# ============================================================================
# Versions
# ============================================================================


@router.post("/versions", response_model=VersionResponse, status_code=201)
async def create_version(
    request: VersionCreate,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> VersionResponse:
    with translate_domain_errors():
        return service.create_version(request)


@router.put("/versions/{version_id}", response_model=VersionResponse)
async def update_version(
    version_id: str,
    request: VersionUpdate,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> VersionResponse:
    with translate_domain_errors():
        return service.update_version(version_id, request)


@router.get("/versions/{version_id}", response_model=VersionResponse)
async def get_version(
    version_id: str,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> VersionResponse:
    with translate_domain_errors():
        return service.get_version(version_id)


@router.post("/versions/upload-word", response_model=dict[str, Any])
async def upload_word(
    file: UploadFile = File(...),
    service: LegalDocumentService = Depends(_get_doc_service),
) -> dict[str, Any]:
    content_bytes = await file.read()
    with translate_domain_errors():
        return await service.upload_word(file.filename, content_bytes)


# ============================================================================
# Approval Workflow Actions
# ============================================================================


@router.post("/versions/{version_id}/submit-review", response_model=VersionResponse)
async def submit_review(
    version_id: str,
    request: ActionRequest,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> VersionResponse:
    with translate_domain_errors():
        return service.submit_review(version_id, request)


@router.post("/versions/{version_id}/approve", response_model=VersionResponse)
async def approve_version(
    version_id: str,
    request: ActionRequest,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> VersionResponse:
    with translate_domain_errors():
        return service.approve(version_id, request)


@router.post("/versions/{version_id}/reject", response_model=VersionResponse)
async def reject_version(
    version_id: str,
    request: ActionRequest,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> VersionResponse:
    with translate_domain_errors():
        return service.reject(version_id, request)


@router.post("/versions/{version_id}/publish", response_model=VersionResponse)
async def publish_version(
    version_id: str,
    request: ActionRequest,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> VersionResponse:
    with translate_domain_errors():
        return service.publish(version_id, request)


# ============================================================================
# 5-stage Workflow (draft → review_internal → review_client → approved → published)
# ============================================================================

@router.post(
    "/versions/{version_id}/submit-internal-review",
    response_model=VersionResponse,
)
async def submit_internal_review(
    version_id: str,
    request: ActionRequest,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> VersionResponse:
    """draft (oder rejected) → review_internal: DSB-Phase beginnt."""
    with translate_domain_errors():
        return service.submit_internal_review(version_id, request)


@router.post(
    "/versions/{version_id}/approve-internal",
    response_model=VersionResponse,
)
async def approve_internal(
    version_id: str,
    request: ActionRequest,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> VersionResponse:
    """review_internal → review_client: DSB hat freigegeben, Mandant ist dran."""
    with translate_domain_errors():
        return service.approve_internal(version_id, request)


@router.post(
    "/versions/{version_id}/approve-client",
    response_model=VersionResponse,
)
async def approve_client(
    version_id: str,
    request: ActionRequest,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> VersionResponse:
    """review_client → approved: Mandant hat freigegeben."""
    with translate_domain_errors():
        return service.approve_client(version_id, request)


# ============================================================================
# Approval History
# ============================================================================


@router.get("/versions/{version_id}/approval-history")
async def get_approval_history(
    version_id: str,
    service: LegalDocumentService = Depends(_get_doc_service),
) -> list[dict[str, Any]]:
    with translate_domain_errors():
        entries = service.approval_history(version_id)
        return [e.dict() for e in entries]


# ============================================================================
# Public Endpoints (for end users)
# ============================================================================


@router.get("/public")
async def list_public_documents(
    tenant_id: str = Depends(_get_tenant),
    service: LegalDocumentService = Depends(_get_doc_service),
) -> list[dict[str, Any]]:
    with translate_domain_errors():
        return service.list_public(tenant_id)


@router.get("/public/{document_type}/latest")
async def get_latest_published(
    document_type: str,
    language: str = Query("de"),
    tenant_id: str = Depends(_get_tenant),
    service: LegalDocumentService = Depends(_get_doc_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.get_latest_published(tenant_id, document_type, language)


# ============================================================================
# User Consents
# ============================================================================


@router.post("/consents")
async def record_consent(
    body: UserConsentCreate,
    tenant_id: str = Depends(_get_tenant),
    service: LegalDocumentConsentService = Depends(_get_consent_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.record_consent(tenant_id, body)


@router.get("/consents/my")
async def get_my_consents(
    user_id: str = Query(...),
    tenant_id: str = Depends(_get_tenant),
    service: LegalDocumentConsentService = Depends(_get_consent_service),
) -> list[dict[str, Any]]:
    with translate_domain_errors():
        return service.get_my_consents(tenant_id, user_id)


@router.get("/consents/check/{document_type}")
async def check_consent(
    document_type: str,
    user_id: str = Query(...),
    tenant_id: str = Depends(_get_tenant),
    service: LegalDocumentConsentService = Depends(_get_consent_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.check_consent(tenant_id, document_type, user_id)


@router.delete("/consents/{consent_id}")
async def withdraw_consent(
    consent_id: str,
    tenant_id: str = Depends(_get_tenant),
    service: LegalDocumentConsentService = Depends(_get_consent_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.withdraw_consent(tenant_id, consent_id)


# ============================================================================
# Consent Statistics
# ============================================================================


@router.get("/stats/consents")
async def get_consent_stats(
    tenant_id: str = Depends(_get_tenant),
    service: LegalDocumentConsentService = Depends(_get_consent_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.get_consent_stats(tenant_id)


# ============================================================================
# Audit Log
# ============================================================================


@router.get("/audit-log")
async def get_audit_log(
    limit: int = Query(50, ge=1, le=200),
    offset: int = Query(0, ge=0),
    action: Optional[str] = Query(None),
    entity_type: Optional[str] = Query(None),
    tenant_id: str = Depends(_get_tenant),
    service: LegalDocumentConsentService = Depends(_get_consent_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.get_audit_log(
            tenant_id, limit=limit, offset=offset,
            action=action, entity_type=entity_type,
        )


# ============================================================================
# Cookie Categories CRUD
# ============================================================================


@router.get("/cookie-categories")
async def list_cookie_categories(
    tenant_id: str = Depends(_get_tenant),
    service: LegalDocumentConsentService = Depends(_get_consent_service),
) -> list[dict[str, Any]]:
    with translate_domain_errors():
        return service.list_cookie_categories(tenant_id)


@router.post("/cookie-categories")
async def create_cookie_category(
    body: CookieCategoryCreate,
    tenant_id: str = Depends(_get_tenant),
    service: LegalDocumentConsentService = Depends(_get_consent_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.create_cookie_category(tenant_id, body)


@router.put("/cookie-categories/{category_id}")
async def update_cookie_category(
    category_id: str,
    body: CookieCategoryUpdate,
    tenant_id: str = Depends(_get_tenant),
    service: LegalDocumentConsentService = Depends(_get_consent_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.update_cookie_category(tenant_id, category_id, body)


@router.delete("/cookie-categories/{category_id}", status_code=204)
async def delete_cookie_category(
    category_id: str,
    tenant_id: str = Depends(_get_tenant),
    service: LegalDocumentConsentService = Depends(_get_consent_service),
) -> None:
    with translate_domain_errors():
        service.delete_cookie_category(tenant_id, category_id)


# Legacy re-exports so existing tests can still import from this module.
__all__ = [
    "router",
    "DEFAULT_TENANT",
    "DocumentCreate",
    "VersionCreate",
    "VersionUpdate",
    "ActionRequest",
    "_doc_to_response",
    "_version_to_response",
    "_transition",
    "_log_approval",
]
