"""
FastAPI routes for Incidents / Datenpannen-Management (DSGVO Art. 33/34).

Endpoints:
  POST   /incidents                              — create incident
  GET    /incidents                              — list (filter: status, severity, category)
  GET    /incidents/stats                        — statistics
  GET    /incidents/{id}                         — detail + measures + deadline_info
  PUT    /incidents/{id}                         — update
  DELETE /incidents/{id}                         — delete
  PUT    /incidents/{id}/status                  — quick status change
  POST   /incidents/{id}/assess-risk             — risk assessment
  POST   /incidents/{id}/notify-authority        — Art. 33 authority notification
  POST   /incidents/{id}/notify-subjects         — Art. 34 data subject notification
  POST   /incidents/{id}/measures                — add measure
  PUT    /incidents/{id}/measures/{mid}          — update measure
  POST   /incidents/{id}/measures/{mid}/complete — complete measure
  POST   /incidents/{id}/timeline                — add timeline entry
  POST   /incidents/{id}/close                   — close incident

Phase 1 Step 4 refactor: handlers delegate to IncidentService (CRUD/
stats/status/timeline/close) and IncidentWorkflowService (risk/
notifications/measures). Module-level helpers re-exported for legacy tests.
"""

import logging
from typing import Any, Optional
from uuid import UUID

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

from classroom_engine.database import get_db
from compliance.api._http_errors import translate_domain_errors
from compliance.schemas.incident import (
    AuthorityNotificationRequest,
    CloseIncidentRequest,
    DataSubjectNotificationRequest,
    IncidentCreate,
    IncidentUpdate,
    MeasureCreate,
    MeasureUpdate,
    RiskAssessmentRequest,
    StatusUpdate,
    TimelineEntryRequest,
)
from compliance.services.incident_service import (
    DEFAULT_TENANT_ID,
    IncidentService,
    _calculate_72h_deadline,  # re-exported for legacy test imports
    _calculate_risk_level,  # re-exported for legacy test imports
    _incident_to_response,  # re-exported for legacy test imports
    _is_notification_required,  # re-exported for legacy test imports
    _measure_to_response,  # re-exported for legacy test imports
    _parse_jsonb,  # re-exported for legacy test imports
)
from compliance.services.incident_workflow_service import IncidentWorkflowService

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


def get_incident_service(db: Session = Depends(get_db)) -> IncidentService:
    return IncidentService(db)


def get_workflow_service(db: Session = Depends(get_db)) -> IncidentWorkflowService:
    return IncidentWorkflowService(db)


# =============================================================================
# CRUD Endpoints
# =============================================================================

@router.post("")
def create_incident(
    body: IncidentCreate,
    x_tenant_id: Optional[str] = Header(None),
    x_user_id: Optional[str] = Header(None),
    service: IncidentService = Depends(get_incident_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.create(
            x_tenant_id or DEFAULT_TENANT_ID,
            x_user_id or "system",
            body,
        )


@router.get("")
def list_incidents(
    x_tenant_id: Optional[str] = Header(None),
    status: Optional[str] = Query(None),
    severity: Optional[str] = Query(None),
    category: Optional[str] = Query(None),
    limit: int = Query(50),
    offset: int = Query(0),
    service: IncidentService = Depends(get_incident_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.list_incidents(
            x_tenant_id or DEFAULT_TENANT_ID,
            status, severity, category, limit, offset,
        )


@router.get("/stats")
def get_stats(
    x_tenant_id: Optional[str] = Header(None),
    service: IncidentService = Depends(get_incident_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.stats(x_tenant_id or DEFAULT_TENANT_ID)


@router.get("/{incident_id}")
def get_incident(
    incident_id: UUID,
    service: IncidentService = Depends(get_incident_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.get(str(incident_id))


@router.put("/{incident_id}")
def update_incident(
    incident_id: UUID,
    body: IncidentUpdate,
    service: IncidentService = Depends(get_incident_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.update(str(incident_id), body)


@router.delete("/{incident_id}")
def delete_incident(
    incident_id: UUID,
    service: IncidentService = Depends(get_incident_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.delete(str(incident_id))


# =============================================================================
# Status Update
# =============================================================================

@router.put("/{incident_id}/status")
def update_status(
    incident_id: UUID,
    body: StatusUpdate,
    x_user_id: Optional[str] = Header(None),
    service: IncidentService = Depends(get_incident_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.update_status(str(incident_id), x_user_id or "system", body)


# =============================================================================
# Risk Assessment
# =============================================================================

@router.post("/{incident_id}/assess-risk")
def assess_risk(
    incident_id: UUID,
    body: RiskAssessmentRequest,
    x_user_id: Optional[str] = Header(None),
    service: IncidentWorkflowService = Depends(get_workflow_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.assess_risk(str(incident_id), x_user_id or "system", body)


# =============================================================================
# Authority Notification (Art. 33)
# =============================================================================

@router.post("/{incident_id}/notify-authority")
def notify_authority(
    incident_id: UUID,
    body: AuthorityNotificationRequest,
    x_user_id: Optional[str] = Header(None),
    service: IncidentWorkflowService = Depends(get_workflow_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.notify_authority(str(incident_id), x_user_id or "system", body)


# =============================================================================
# Data Subject Notification (Art. 34)
# =============================================================================

@router.post("/{incident_id}/notify-subjects")
def notify_subjects(
    incident_id: UUID,
    body: DataSubjectNotificationRequest,
    x_user_id: Optional[str] = Header(None),
    service: IncidentWorkflowService = Depends(get_workflow_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.notify_subjects(str(incident_id), x_user_id or "system", body)


# =============================================================================
# Measures
# =============================================================================

@router.post("/{incident_id}/measures")
def add_measure(
    incident_id: UUID,
    body: MeasureCreate,
    x_user_id: Optional[str] = Header(None),
    service: IncidentWorkflowService = Depends(get_workflow_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.add_measure(str(incident_id), x_user_id or "system", body)


@router.put("/{incident_id}/measures/{measure_id}")
def update_measure(
    incident_id: UUID,
    measure_id: UUID,
    body: MeasureUpdate,
    service: IncidentWorkflowService = Depends(get_workflow_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.update_measure(str(measure_id), body)


@router.post("/{incident_id}/measures/{measure_id}/complete")
def complete_measure(
    incident_id: UUID,
    measure_id: UUID,
    service: IncidentWorkflowService = Depends(get_workflow_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.complete_measure(str(measure_id))


# =============================================================================
# Timeline
# =============================================================================

@router.post("/{incident_id}/timeline")
def add_timeline_entry(
    incident_id: UUID,
    body: TimelineEntryRequest,
    x_user_id: Optional[str] = Header(None),
    service: IncidentService = Depends(get_incident_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.add_timeline(str(incident_id), x_user_id or "system", body)


# =============================================================================
# Close Incident
# =============================================================================

@router.post("/{incident_id}/close")
def close_incident(
    incident_id: UUID,
    body: CloseIncidentRequest,
    x_user_id: Optional[str] = Header(None),
    service: IncidentService = Depends(get_incident_service),
) -> dict[str, Any]:
    with translate_domain_errors():
        return service.close(str(incident_id), x_user_id or "system", body)


# Legacy re-exports
__all__ = [
    "router",
    "DEFAULT_TENANT_ID",
    "_calculate_risk_level",
    "_is_notification_required",
    "_calculate_72h_deadline",
    "_incident_to_response",
    "_measure_to_response",
    "_parse_jsonb",
]
