"""
FastAPI routes for Vendor Compliance — Auftragsverarbeitung (Art. 28 DSGVO).

Endpoints:
  Vendors (7):
    GET    /vendor-compliance/vendors           — Liste + Filter
    GET    /vendor-compliance/vendors/stats      — Statistiken
    GET    /vendor-compliance/vendors/{id}       — Detail
    POST   /vendor-compliance/vendors            — Erstellen
    PUT    /vendor-compliance/vendors/{id}       — Update
    DELETE /vendor-compliance/vendors/{id}       — Loeschen
    PATCH  /vendor-compliance/vendors/{id}/status — Status aendern

  Contracts (5):
    GET    /vendor-compliance/contracts          — Liste
    GET    /vendor-compliance/contracts/{id}     — Detail
    POST   /vendor-compliance/contracts          — Erstellen
    PUT    /vendor-compliance/contracts/{id}     — Update
    DELETE /vendor-compliance/contracts/{id}     — Loeschen

  Findings (5):
    GET    /vendor-compliance/findings           — Liste
    GET    /vendor-compliance/findings/{id}      — Detail
    POST   /vendor-compliance/findings           — Erstellen
    PUT    /vendor-compliance/findings/{id}      — Update
    DELETE /vendor-compliance/findings/{id}      — Loeschen

  Control Instances (5):
    GET    /vendor-compliance/control-instances          — Liste
    GET    /vendor-compliance/control-instances/{id}     — Detail
    POST   /vendor-compliance/control-instances          — Erstellen
    PUT    /vendor-compliance/control-instances/{id}     — Update
    DELETE /vendor-compliance/control-instances/{id}     — Loeschen

  Controls Library (3):
    GET    /vendor-compliance/controls           — Alle Controls
    POST   /vendor-compliance/controls           — Erstellen
    DELETE /vendor-compliance/controls/{id}      — Loeschen

  Export Stubs (3):
    POST   /vendor-compliance/export             — 501
    GET    /vendor-compliance/export/{id}        — 501
    GET    /vendor-compliance/export/{id}/download — 501

Phase 1 Step 4 refactor: handlers delegate to VendorService,
ContractService, FindingService, ControlInstanceService, and
ControlsLibraryService. Module-level helpers re-exported for legacy
test imports.
"""

import logging
from typing import Optional

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

from classroom_engine.database import get_db
from compliance.api._http_errors import translate_domain_errors
from compliance.services.vendor_compliance_service import (
    DEFAULT_TENANT_ID,  # noqa: F401 — re-export
    VendorService,
    _get,  # noqa: F401 — re-export
    _now_iso,
    _ok,  # noqa: F401 — re-export
    _parse_json,  # noqa: F401 — re-export
    _to_camel,  # noqa: F401 — re-export
    _to_snake,  # noqa: F401 — re-export
    _ts,  # noqa: F401 — re-export
    _vendor_to_response,  # noqa: F401 — re-export
    _VENDOR_CAMEL_TO_SNAKE,  # noqa: F401 — re-export
    _VENDOR_SNAKE_TO_CAMEL,  # noqa: F401 — re-export
)
from compliance.services.vendor_compliance_sub_service import (
    ContractService,
    _contract_to_response,  # noqa: F401 — re-export
    _control_instance_to_response,  # noqa: F401 — re-export
    _finding_to_response,  # noqa: F401 — re-export
)
from compliance.services.vendor_compliance_extra_service import (
    ControlInstanceService,
    ControlsLibraryService,
    FindingService,
)

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


# ---------------------------------------------------------------------------
# Service factories
# ---------------------------------------------------------------------------

def _vendor_svc(db: Session = Depends(get_db)) -> VendorService:
    return VendorService(db)


def _contract_svc(db: Session = Depends(get_db)) -> ContractService:
    return ContractService(db)


def _finding_svc(db: Session = Depends(get_db)) -> FindingService:
    return FindingService(db)


def _ci_svc(db: Session = Depends(get_db)) -> ControlInstanceService:
    return ControlInstanceService(db)


def _ctrl_svc(db: Session = Depends(get_db)) -> ControlsLibraryService:
    return ControlsLibraryService(db)


# ============================================================================
# Vendors
# ============================================================================


@router.get("/vendors/stats")
def get_vendor_stats(
    tenant_id: Optional[str] = Query(None),
    svc: VendorService = Depends(_vendor_svc),
):
    with translate_domain_errors():
        return svc.get_stats(tenant_id)


@router.get("/vendors")
def list_vendors(
    tenant_id: Optional[str] = Query(None),
    status: Optional[str] = Query(None),
    risk_level: Optional[str] = Query(None, alias="riskLevel"),
    search: Optional[str] = Query(None),
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=500),
    svc: VendorService = Depends(_vendor_svc),
):
    with translate_domain_errors():
        return svc.list_vendors(tenant_id, status, risk_level, search, skip, limit)


@router.get("/vendors/{vendor_id}")
def get_vendor(
    vendor_id: str,
    svc: VendorService = Depends(_vendor_svc),
):
    with translate_domain_errors():
        return svc.get_vendor(vendor_id)


@router.post("/vendors", status_code=201)
def create_vendor(
    body: dict = {},
    svc: VendorService = Depends(_vendor_svc),
):
    with translate_domain_errors():
        return svc.create_vendor(body)


@router.put("/vendors/{vendor_id}")
def update_vendor(
    vendor_id: str,
    body: dict = {},
    svc: VendorService = Depends(_vendor_svc),
):
    with translate_domain_errors():
        return svc.update_vendor(vendor_id, body)


@router.delete("/vendors/{vendor_id}")
def delete_vendor(
    vendor_id: str,
    svc: VendorService = Depends(_vendor_svc),
):
    with translate_domain_errors():
        return svc.delete_vendor(vendor_id)


@router.patch("/vendors/{vendor_id}/status")
def patch_vendor_status(
    vendor_id: str,
    body: dict = {},
    svc: VendorService = Depends(_vendor_svc),
):
    with translate_domain_errors():
        return svc.patch_status(vendor_id, body)


# ============================================================================
# Contracts
# ============================================================================


@router.get("/contracts")
def list_contracts(
    tenant_id: Optional[str] = Query(None),
    vendor_id: Optional[str] = Query(None),
    status: Optional[str] = Query(None),
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=500),
    svc: ContractService = Depends(_contract_svc),
):
    with translate_domain_errors():
        return svc.list_contracts(tenant_id, vendor_id, status, skip, limit)


@router.get("/contracts/{contract_id}")
def get_contract(
    contract_id: str,
    svc: ContractService = Depends(_contract_svc),
):
    with translate_domain_errors():
        return svc.get_contract(contract_id)


@router.post("/contracts", status_code=201)
def create_contract(
    body: dict = {},
    svc: ContractService = Depends(_contract_svc),
):
    with translate_domain_errors():
        return svc.create_contract(body)


@router.put("/contracts/{contract_id}")
def update_contract(
    contract_id: str,
    body: dict = {},
    svc: ContractService = Depends(_contract_svc),
):
    with translate_domain_errors():
        return svc.update_contract(contract_id, body)


@router.delete("/contracts/{contract_id}")
def delete_contract(
    contract_id: str,
    svc: ContractService = Depends(_contract_svc),
):
    with translate_domain_errors():
        return svc.delete_contract(contract_id)


# ============================================================================
# Findings
# ============================================================================


@router.get("/findings")
def list_findings(
    tenant_id: Optional[str] = Query(None),
    vendor_id: Optional[str] = Query(None),
    severity: Optional[str] = Query(None),
    status: Optional[str] = Query(None),
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=500),
    svc: FindingService = Depends(_finding_svc),
):
    with translate_domain_errors():
        return svc.list_findings(tenant_id, vendor_id, severity, status, skip, limit)


@router.get("/findings/{finding_id}")
def get_finding(
    finding_id: str,
    svc: FindingService = Depends(_finding_svc),
):
    with translate_domain_errors():
        return svc.get_finding(finding_id)


@router.post("/findings", status_code=201)
def create_finding(
    body: dict = {},
    svc: FindingService = Depends(_finding_svc),
):
    with translate_domain_errors():
        return svc.create_finding(body)


@router.put("/findings/{finding_id}")
def update_finding(
    finding_id: str,
    body: dict = {},
    svc: FindingService = Depends(_finding_svc),
):
    with translate_domain_errors():
        return svc.update_finding(finding_id, body)


@router.delete("/findings/{finding_id}")
def delete_finding(
    finding_id: str,
    svc: FindingService = Depends(_finding_svc),
):
    with translate_domain_errors():
        return svc.delete_finding(finding_id)


# ============================================================================
# Control Instances
# ============================================================================


@router.get("/control-instances")
def list_control_instances(
    tenant_id: Optional[str] = Query(None),
    vendor_id: Optional[str] = Query(None),
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=500),
    svc: ControlInstanceService = Depends(_ci_svc),
):
    with translate_domain_errors():
        return svc.list_instances(tenant_id, vendor_id, skip, limit)


@router.get("/control-instances/{instance_id}")
def get_control_instance(
    instance_id: str,
    svc: ControlInstanceService = Depends(_ci_svc),
):
    with translate_domain_errors():
        return svc.get_instance(instance_id)


@router.post("/control-instances", status_code=201)
def create_control_instance(
    body: dict = {},
    svc: ControlInstanceService = Depends(_ci_svc),
):
    with translate_domain_errors():
        return svc.create_instance(body)


@router.put("/control-instances/{instance_id}")
def update_control_instance(
    instance_id: str,
    body: dict = {},
    svc: ControlInstanceService = Depends(_ci_svc),
):
    with translate_domain_errors():
        return svc.update_instance(instance_id, body)


@router.delete("/control-instances/{instance_id}")
def delete_control_instance(
    instance_id: str,
    svc: ControlInstanceService = Depends(_ci_svc),
):
    with translate_domain_errors():
        return svc.delete_instance(instance_id)


# ============================================================================
# Controls Library
# ============================================================================


@router.get("/controls")
def list_controls(
    tenant_id: Optional[str] = Query(None),
    domain: Optional[str] = Query(None),
    svc: ControlsLibraryService = Depends(_ctrl_svc),
):
    with translate_domain_errors():
        return svc.list_controls(tenant_id, domain)


@router.post("/controls", status_code=201)
def create_control(
    body: dict = {},
    svc: ControlsLibraryService = Depends(_ctrl_svc),
):
    with translate_domain_errors():
        return svc.create_control(body)


@router.delete("/controls/{control_id}")
def delete_control(
    control_id: str,
    svc: ControlsLibraryService = Depends(_ctrl_svc),
):
    with translate_domain_errors():
        return svc.delete_control(control_id)


# ============================================================================
# Export Stubs (501 Not Implemented)
# ============================================================================


@router.post("/export", status_code=501)
def export_report():
    return {"success": False, "error": "Export not implemented yet", "timestamp": _now_iso()}


@router.get("/export/{report_id}", status_code=501)
def get_export(report_id: str):
    return {"success": False, "error": "Export not implemented yet", "timestamp": _now_iso()}


@router.get("/export/{report_id}/download", status_code=501)
def download_export(report_id: str):
    return {"success": False, "error": "Export not implemented yet", "timestamp": _now_iso()}
