"""
FastAPI routes for TOM — Technisch-Organisatorische Massnahmen (Art. 32 DSGVO).

Endpoints:
  GET    /tom/state              — Load TOM generator state for tenant
  POST   /tom/state              — Save state (with version check)
  DELETE /tom/state              — Reset/clear state for tenant
  GET    /tom/measures           — List measures (filter: category, status, tenant_id)
  POST   /tom/measures           — Create single measure
  PUT    /tom/measures/{id}      — Update measure
  POST   /tom/measures/bulk      — Bulk upsert (for deriveTOMs sync)
  GET    /tom/stats              — Statistics
  GET    /tom/export             — Export as CSV or JSON
  GET    /tom/measures/{id}/versions             — List measure versions
  GET    /tom/measures/{id}/versions/{n}         — Get specific version

Phase 1 Step 4 refactor: handlers are thin and delegate to TOMService.
"""

from typing import Any, Optional
from uuid import UUID

from fastapi import APIRouter, Depends, Query
from fastapi.responses import StreamingResponse
from sqlalchemy.orm import Session

from classroom_engine.database import get_db
from compliance.api._http_errors import translate_domain_errors
from compliance.schemas.tom import (
    TOMMeasureBulkBody,
    TOMMeasureBulkItem,  # re-exported for backwards compat (legacy test imports)
    TOMMeasureCreate,
    TOMMeasureUpdate,
    TOMStateBody,
)

# Keep the legacy import path ``from compliance.api.tom_routes import TOMMeasureBulkItem``
# working — it was the public name before the Step 3 schemas split.
__all__ = [
    "router",
    "TOMMeasureBulkBody",
    "TOMMeasureBulkItem",
    "TOMMeasureCreate",
    "TOMMeasureUpdate",
    "TOMStateBody",
    "DEFAULT_TENANT_ID",
    "_parse_dt",
    "_measure_to_dict",
]
from compliance.services.tom_service import (
    DEFAULT_TENANT_ID,
    TOMService,
    _measure_to_dict,  # re-exported for legacy test imports
    _parse_dt,  # re-exported for legacy test imports
)

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


def get_tom_service(db: Session = Depends(get_db)) -> TOMService:
    return TOMService(db)


# =============================================================================
# STATE
# =============================================================================

@router.get("/state")
async def get_tom_state(
    tenant_id: Optional[str] = Query(None, alias="tenant_id"),
    tenantId: Optional[str] = Query(None),
    service: TOMService = Depends(get_tom_service),
) -> dict[str, Any]:
    """Load TOM generator state for a tenant."""
    with translate_domain_errors():
        return service.get_state(tenant_id or tenantId or DEFAULT_TENANT_ID)


@router.post("/state")
async def save_tom_state(
    body: TOMStateBody,
    service: TOMService = Depends(get_tom_service),
) -> dict[str, Any]:
    """Save TOM generator state with optimistic locking (version check)."""
    with translate_domain_errors():
        return service.save_state(body)


@router.delete("/state")
async def delete_tom_state(
    tenant_id: Optional[str] = Query(None, alias="tenant_id"),
    tenantId: Optional[str] = Query(None),
    service: TOMService = Depends(get_tom_service),
) -> dict[str, Any]:
    """Clear TOM generator state for a tenant."""
    with translate_domain_errors():
        return service.delete_state(tenant_id or tenantId)


# =============================================================================
# MEASURES
# =============================================================================

@router.get("/measures")
async def list_measures(
    tenant_id: Optional[str] = Query(None),
    category: Optional[str] = Query(None),
    implementation_status: Optional[str] = Query(None),
    priority: Optional[str] = Query(None),
    search: Optional[str] = Query(None),
    limit: int = Query(100, ge=1, le=500),
    offset: int = Query(0, ge=0),
    service: TOMService = Depends(get_tom_service),
) -> dict[str, Any]:
    """List TOM measures with optional filters."""
    with translate_domain_errors():
        return service.list_measures(
            tenant_id=tenant_id or DEFAULT_TENANT_ID,
            category=category,
            implementation_status=implementation_status,
            priority=priority,
            search=search,
            limit=limit,
            offset=offset,
        )


@router.post("/measures", status_code=201)
async def create_measure(
    body: TOMMeasureCreate,
    tenant_id: Optional[str] = Query(None),
    service: TOMService = Depends(get_tom_service),
) -> dict[str, Any]:
    """Create a single TOM measure."""
    with translate_domain_errors():
        return service.create_measure(tenant_id or DEFAULT_TENANT_ID, body)


@router.put("/measures/{measure_id}")
async def update_measure(
    measure_id: UUID,
    body: TOMMeasureUpdate,
    service: TOMService = Depends(get_tom_service),
) -> dict[str, Any]:
    """Update a TOM measure."""
    with translate_domain_errors():
        return service.update_measure(measure_id, body)


@router.post("/measures/bulk")
async def bulk_upsert_measures(
    body: TOMMeasureBulkBody,
    service: TOMService = Depends(get_tom_service),
) -> dict[str, Any]:
    """Bulk upsert measures — used by deriveTOMs sync from frontend."""
    with translate_domain_errors():
        return service.bulk_upsert(body)


# =============================================================================
# STATS & EXPORT
# =============================================================================

@router.get("/stats")
async def get_tom_stats(
    tenant_id: Optional[str] = Query(None),
    service: TOMService = Depends(get_tom_service),
) -> dict[str, Any]:
    """Return TOM statistics for a tenant."""
    with translate_domain_errors():
        return service.stats(tenant_id or DEFAULT_TENANT_ID)


@router.get("/export")
async def export_measures(
    tenant_id: Optional[str] = Query(None),
    format: str = Query("csv"),
    service: TOMService = Depends(get_tom_service),
) -> StreamingResponse:
    """Export TOM measures as CSV (semicolon-separated) or JSON."""
    with translate_domain_errors():
        return service.export(tenant_id or DEFAULT_TENANT_ID, format)


# =============================================================================
# Versioning
# =============================================================================

@router.get("/measures/{measure_id}/versions")
async def list_measure_versions(
    measure_id: str,
    tenant_id: Optional[str] = Query(None, alias="tenant_id"),
    tenantId: Optional[str] = Query(None, alias="tenantId"),
    service: TOMService = Depends(get_tom_service),
) -> Any:
    """List all versions for a TOM measure."""
    with translate_domain_errors():
        return service.list_versions(
            measure_id, tenant_id or tenantId or DEFAULT_TENANT_ID
        )


@router.get("/measures/{measure_id}/versions/{version_number}")
async def get_measure_version(
    measure_id: str,
    version_number: int,
    tenant_id: Optional[str] = Query(None, alias="tenant_id"),
    tenantId: Optional[str] = Query(None, alias="tenantId"),
    service: TOMService = Depends(get_tom_service),
) -> Any:
    """Get a specific TOM measure version with full snapshot."""
    with translate_domain_errors():
        return service.get_version(
            measure_id, version_number, tenant_id or tenantId or DEFAULT_TENANT_ID
        )
