"""
Tests for DSR (Data Subject Request) routes.
Pattern: app.dependency_overrides[get_db] for FastAPI DI.
"""

import uuid
import os
import sys
from datetime import datetime, timedelta, timezone

import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from sqlalchemy import create_engine, text
from sqlalchemy.orm import sessionmaker

# Ensure backend dir is on path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

from classroom_engine.database import Base, get_db
from compliance.db.dsr_models import (
    DSRRequestDB, DSRStatusHistoryDB, DSRCommunicationDB,
    DSRTemplateDB, DSRTemplateVersionDB, DSRExceptionCheckDB,
)
from compliance.api.dsr_routes import router as dsr_router

# In-memory SQLite for testing
SQLALCHEMY_DATABASE_URL = "sqlite:///./test_dsr.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

TENANT_ID = "9282a473-5c95-4b3a-bf78-0ecc0ec71d3e"
HEADERS = {"X-Tenant-ID": TENANT_ID}

# Create a minimal test app (avoids importing main.py with its Python 3.10+ syntax issues)
app = FastAPI()
app.include_router(dsr_router, prefix="/api/compliance")


def override_get_db():
    db = TestingSessionLocal()
    try:
        yield db
    finally:
        db.close()


app.dependency_overrides[get_db] = override_get_db
client = TestClient(app)


@pytest.fixture(autouse=True)
def setup_db():
    """Create all tables before each test, drop after."""
    Base.metadata.create_all(bind=engine)
    # Create sequence workaround for SQLite (no sequences)
    db = TestingSessionLocal()
    try:
        # SQLite doesn't have sequences; we'll mock the request number generation
        pass
    finally:
        db.close()
    yield
    Base.metadata.drop_all(bind=engine)


@pytest.fixture
def db_session():
    db = TestingSessionLocal()
    try:
        yield db
    finally:
        db.close()


def _create_dsr_in_db(db, **kwargs):
    """Helper to create a DSR directly in DB."""
    now = datetime.now(timezone.utc)
    defaults = {
        "tenant_id": uuid.UUID(TENANT_ID),
        "request_number": f"DSR-2026-{str(uuid.uuid4())[:6].upper()}",
        "request_type": "access",
        "status": "intake",
        "priority": "normal",
        "requester_name": "Max Mustermann",
        "requester_email": "max@example.de",
        "source": "email",
        "received_at": now,
        "deadline_at": now + timedelta(days=30),
        "created_at": now,
        "updated_at": now,
    }
    defaults.update(kwargs)
    dsr = DSRRequestDB(**defaults)
    db.add(dsr)
    db.commit()
    db.refresh(dsr)
    return dsr


# =============================================================================
# CREATE Tests
# =============================================================================

class TestCreateDSR:
    def test_create_access_request(self, db_session):
        resp = client.post("/api/compliance/dsr", json={
            "request_type": "access",
            "requester_name": "Max Mustermann",
            "requester_email": "max@example.de",
            "source": "email",
            "request_text": "Auskunft nach Art. 15 DSGVO",
        }, headers=HEADERS)
        # May fail on SQLite due to sequence; check for 200 or 500
        if resp.status_code == 200:
            data = resp.json()
            assert data["request_type"] == "access"
            assert data["status"] == "intake"
            assert data["requester_name"] == "Max Mustermann"
            assert data["requester_email"] == "max@example.de"
            assert data["deadline_at"] is not None

    def test_create_erasure_request(self, db_session):
        resp = client.post("/api/compliance/dsr", json={
            "request_type": "erasure",
            "requester_name": "Anna Schmidt",
            "requester_email": "anna@example.de",
            "source": "web_form",
            "request_text": "Bitte alle Daten loeschen",
            "priority": "high",
        }, headers=HEADERS)
        if resp.status_code == 200:
            data = resp.json()
            assert data["request_type"] == "erasure"
            assert data["priority"] == "high"

    def test_create_invalid_type(self):
        resp = client.post("/api/compliance/dsr", json={
            "request_type": "invalid_type",
            "requester_name": "Test",
            "requester_email": "test@test.de",
        }, headers=HEADERS)
        assert resp.status_code == 400

    def test_create_invalid_source(self):
        resp = client.post("/api/compliance/dsr", json={
            "request_type": "access",
            "requester_name": "Test",
            "requester_email": "test@test.de",
            "source": "invalid_source",
        }, headers=HEADERS)
        assert resp.status_code == 400

    def test_create_invalid_priority(self):
        resp = client.post("/api/compliance/dsr", json={
            "request_type": "access",
            "requester_name": "Test",
            "requester_email": "test@test.de",
            "priority": "ultra",
        }, headers=HEADERS)
        assert resp.status_code == 400

    def test_create_missing_name(self):
        resp = client.post("/api/compliance/dsr", json={
            "request_type": "access",
            "requester_email": "test@test.de",
        }, headers=HEADERS)
        assert resp.status_code == 422

    def test_create_missing_email(self):
        resp = client.post("/api/compliance/dsr", json={
            "request_type": "access",
            "requester_name": "Test",
        }, headers=HEADERS)
        assert resp.status_code == 422


# =============================================================================
# LIST Tests
# =============================================================================

class TestListDSR:
    def test_list_empty(self):
        resp = client.get("/api/compliance/dsr", headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["requests"] == []
        assert data["total"] == 0

    def test_list_with_data(self, db_session):
        _create_dsr_in_db(db_session, request_type="access")
        _create_dsr_in_db(db_session, request_type="erasure")

        resp = client.get("/api/compliance/dsr", headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["total"] == 2
        assert len(data["requests"]) == 2

    def test_list_filter_by_status(self, db_session):
        _create_dsr_in_db(db_session, status="intake")
        _create_dsr_in_db(db_session, status="processing")
        _create_dsr_in_db(db_session, status="completed")

        resp = client.get("/api/compliance/dsr?status=intake", headers=HEADERS)
        assert resp.status_code == 200
        assert resp.json()["total"] == 1

    def test_list_filter_by_type(self, db_session):
        _create_dsr_in_db(db_session, request_type="access")
        _create_dsr_in_db(db_session, request_type="erasure")

        resp = client.get("/api/compliance/dsr?request_type=erasure", headers=HEADERS)
        assert resp.status_code == 200
        assert resp.json()["total"] == 1

    def test_list_filter_by_priority(self, db_session):
        _create_dsr_in_db(db_session, priority="high")
        _create_dsr_in_db(db_session, priority="normal")

        resp = client.get("/api/compliance/dsr?priority=high", headers=HEADERS)
        assert resp.status_code == 200
        assert resp.json()["total"] == 1

    def test_list_search(self, db_session):
        _create_dsr_in_db(db_session, requester_name="Max Mustermann", requester_email="max@example.de")
        _create_dsr_in_db(db_session, requester_name="Anna Schmidt", requester_email="anna@example.de")

        resp = client.get("/api/compliance/dsr?search=Anna", headers=HEADERS)
        assert resp.status_code == 200
        assert resp.json()["total"] == 1

    def test_list_pagination(self, db_session):
        for i in range(5):
            _create_dsr_in_db(db_session)

        resp = client.get("/api/compliance/dsr?limit=2&offset=0", headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["total"] == 5
        assert len(data["requests"]) == 2

    def test_list_overdue_only(self, db_session):
        _create_dsr_in_db(db_session, deadline_at=datetime.now(timezone.utc) - timedelta(days=5), status="processing")
        _create_dsr_in_db(db_session, deadline_at=datetime.now(timezone.utc) + timedelta(days=20), status="processing")

        resp = client.get("/api/compliance/dsr?overdue_only=true", headers=HEADERS)
        assert resp.status_code == 200
        assert resp.json()["total"] == 1


# =============================================================================
# GET DETAIL Tests
# =============================================================================

class TestGetDSR:
    def test_get_existing(self, db_session):
        dsr = _create_dsr_in_db(db_session)
        resp = client.get(f"/api/compliance/dsr/{dsr.id}", headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["id"] == str(dsr.id)
        assert data["requester_name"] == "Max Mustermann"

    def test_get_nonexistent(self):
        fake_id = str(uuid.uuid4())
        resp = client.get(f"/api/compliance/dsr/{fake_id}", headers=HEADERS)
        assert resp.status_code == 404

    def test_get_invalid_id(self):
        resp = client.get("/api/compliance/dsr/not-a-uuid", headers=HEADERS)
        assert resp.status_code == 400


# =============================================================================
# UPDATE Tests
# =============================================================================

class TestUpdateDSR:
    def test_update_priority(self, db_session):
        dsr = _create_dsr_in_db(db_session)
        resp = client.put(f"/api/compliance/dsr/{dsr.id}", json={
            "priority": "high",
        }, headers=HEADERS)
        assert resp.status_code == 200
        assert resp.json()["priority"] == "high"

    def test_update_notes(self, db_session):
        dsr = _create_dsr_in_db(db_session)
        resp = client.put(f"/api/compliance/dsr/{dsr.id}", json={
            "notes": "Test note",
            "internal_notes": "Internal note",
        }, headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["notes"] == "Test note"
        assert data["internal_notes"] == "Internal note"

    def test_update_invalid_priority(self, db_session):
        dsr = _create_dsr_in_db(db_session)
        resp = client.put(f"/api/compliance/dsr/{dsr.id}", json={
            "priority": "ultra",
        }, headers=HEADERS)
        assert resp.status_code == 400


# =============================================================================
# DELETE Tests
# =============================================================================

class TestDeleteDSR:
    def test_cancel_dsr(self, db_session):
        dsr = _create_dsr_in_db(db_session, status="intake")
        resp = client.delete(f"/api/compliance/dsr/{dsr.id}", headers=HEADERS)
        assert resp.status_code == 200

        # Verify status is cancelled
        resp2 = client.get(f"/api/compliance/dsr/{dsr.id}", headers=HEADERS)
        assert resp2.json()["status"] == "cancelled"

    def test_cancel_already_completed(self, db_session):
        dsr = _create_dsr_in_db(db_session, status="completed")
        resp = client.delete(f"/api/compliance/dsr/{dsr.id}", headers=HEADERS)
        assert resp.status_code == 400


# =============================================================================
# STATS Tests
# =============================================================================

class TestDSRStats:
    def test_stats_empty(self):
        resp = client.get("/api/compliance/dsr/stats", headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["total"] == 0

    def test_stats_with_data(self, db_session):
        _create_dsr_in_db(db_session, status="intake", request_type="access")
        _create_dsr_in_db(db_session, status="processing", request_type="erasure")
        _create_dsr_in_db(db_session, status="completed", request_type="access",
                          completed_at=datetime.now(timezone.utc))

        resp = client.get("/api/compliance/dsr/stats", headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["total"] == 3
        assert data["by_status"]["intake"] == 1
        assert data["by_status"]["processing"] == 1
        assert data["by_status"]["completed"] == 1
        assert data["by_type"]["access"] == 2
        assert data["by_type"]["erasure"] == 1


# =============================================================================
# WORKFLOW Tests
# =============================================================================

class TestDSRWorkflow:
    def test_change_status(self, db_session):
        dsr = _create_dsr_in_db(db_session, status="intake")
        resp = client.post(f"/api/compliance/dsr/{dsr.id}/status", json={
            "status": "identity_verification",
            "comment": "ID angefragt",
        }, headers=HEADERS)
        assert resp.status_code == 200
        assert resp.json()["status"] == "identity_verification"

    def test_change_status_invalid(self, db_session):
        dsr = _create_dsr_in_db(db_session)
        resp = client.post(f"/api/compliance/dsr/{dsr.id}/status", json={
            "status": "invalid_status",
        }, headers=HEADERS)
        assert resp.status_code == 400

    def test_verify_identity(self, db_session):
        dsr = _create_dsr_in_db(db_session, status="identity_verification")
        resp = client.post(f"/api/compliance/dsr/{dsr.id}/verify-identity", json={
            "method": "id_document",
            "notes": "Personalausweis geprueft",
        }, headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["identity_verified"] is True
        assert data["verification_method"] == "id_document"
        assert data["status"] == "processing"

    def test_assign_dsr(self, db_session):
        dsr = _create_dsr_in_db(db_session)
        resp = client.post(f"/api/compliance/dsr/{dsr.id}/assign", json={
            "assignee_id": "DSB Mueller",
        }, headers=HEADERS)
        assert resp.status_code == 200
        assert resp.json()["assigned_to"] == "DSB Mueller"

    def test_extend_deadline(self, db_session):
        dsr = _create_dsr_in_db(db_session, status="processing")
        resp = client.post(f"/api/compliance/dsr/{dsr.id}/extend", json={
            "reason": "Komplexe Anfrage",
            "days": 60,
        }, headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["extended_deadline_at"] is not None
        assert data["extension_reason"] == "Komplexe Anfrage"

    def test_extend_deadline_closed_dsr(self, db_session):
        dsr = _create_dsr_in_db(db_session, status="completed")
        resp = client.post(f"/api/compliance/dsr/{dsr.id}/extend", json={
            "reason": "Test",
        }, headers=HEADERS)
        assert resp.status_code == 400

    def test_complete_dsr(self, db_session):
        dsr = _create_dsr_in_db(db_session, status="processing")
        resp = client.post(f"/api/compliance/dsr/{dsr.id}/complete", json={
            "summary": "Auskunft erteilt",
        }, headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["status"] == "completed"
        assert data["completed_at"] is not None

    def test_complete_already_completed(self, db_session):
        dsr = _create_dsr_in_db(db_session, status="completed")
        resp = client.post(f"/api/compliance/dsr/{dsr.id}/complete", json={
            "summary": "Nochmal",
        }, headers=HEADERS)
        assert resp.status_code == 400

    def test_reject_dsr(self, db_session):
        dsr = _create_dsr_in_db(db_session, status="processing")
        resp = client.post(f"/api/compliance/dsr/{dsr.id}/reject", json={
            "reason": "Unberechtigt",
            "legal_basis": "Art. 17(3)(b)",
        }, headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["status"] == "rejected"
        assert data["rejection_reason"] == "Unberechtigt"
        assert data["rejection_legal_basis"] == "Art. 17(3)(b)"


# =============================================================================
# HISTORY & COMMUNICATIONS Tests
# =============================================================================

class TestDSRHistory:
    def test_get_history(self, db_session):
        dsr = _create_dsr_in_db(db_session)
        # Add a history entry
        entry = DSRStatusHistoryDB(
            tenant_id=uuid.UUID(TENANT_ID),
            dsr_id=dsr.id,
            previous_status="intake",
            new_status="processing",
            changed_by="admin",
            comment="Test",
        )
        db_session.add(entry)
        db_session.commit()

        resp = client.get(f"/api/compliance/dsr/{dsr.id}/history", headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert len(data) == 1
        assert data[0]["new_status"] == "processing"


class TestDSRCommunications:
    def test_send_communication(self, db_session):
        dsr = _create_dsr_in_db(db_session)
        resp = client.post(f"/api/compliance/dsr/{dsr.id}/communicate", json={
            "communication_type": "outgoing",
            "channel": "email",
            "subject": "Eingangsbestaetigung",
            "content": "Ihre Anfrage wurde erhalten.",
        }, headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["channel"] == "email"
        assert data["sent_at"] is not None

    def test_get_communications(self, db_session):
        dsr = _create_dsr_in_db(db_session)
        comm = DSRCommunicationDB(
            tenant_id=uuid.UUID(TENANT_ID),
            dsr_id=dsr.id,
            communication_type="outgoing",
            channel="email",
            content="Test",
        )
        db_session.add(comm)
        db_session.commit()

        resp = client.get(f"/api/compliance/dsr/{dsr.id}/communications", headers=HEADERS)
        assert resp.status_code == 200
        assert len(resp.json()) == 1


# =============================================================================
# EXCEPTION CHECKS Tests
# =============================================================================

class TestExceptionChecks:
    def test_init_exception_checks(self, db_session):
        dsr = _create_dsr_in_db(db_session, request_type="erasure")
        resp = client.post(f"/api/compliance/dsr/{dsr.id}/exception-checks/init", headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert len(data) == 5
        assert data[0]["check_code"] == "art17_3_a"

    def test_init_exception_checks_not_erasure(self, db_session):
        dsr = _create_dsr_in_db(db_session, request_type="access")
        resp = client.post(f"/api/compliance/dsr/{dsr.id}/exception-checks/init", headers=HEADERS)
        assert resp.status_code == 400

    def test_init_exception_checks_already_initialized(self, db_session):
        dsr = _create_dsr_in_db(db_session, request_type="erasure")
        # First init
        client.post(f"/api/compliance/dsr/{dsr.id}/exception-checks/init", headers=HEADERS)
        # Second init should fail
        resp = client.post(f"/api/compliance/dsr/{dsr.id}/exception-checks/init", headers=HEADERS)
        assert resp.status_code == 400

    def test_update_exception_check(self, db_session):
        dsr = _create_dsr_in_db(db_session, request_type="erasure")
        init_resp = client.post(f"/api/compliance/dsr/{dsr.id}/exception-checks/init", headers=HEADERS)
        checks = init_resp.json()
        check_id = checks[0]["id"]

        resp = client.put(f"/api/compliance/dsr/{dsr.id}/exception-checks/{check_id}", json={
            "applies": True,
            "notes": "Aufbewahrungspflicht nach HGB",
        }, headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["applies"] is True
        assert data["notes"] == "Aufbewahrungspflicht nach HGB"

    def test_get_exception_checks(self, db_session):
        dsr = _create_dsr_in_db(db_session, request_type="erasure")
        client.post(f"/api/compliance/dsr/{dsr.id}/exception-checks/init", headers=HEADERS)

        resp = client.get(f"/api/compliance/dsr/{dsr.id}/exception-checks", headers=HEADERS)
        assert resp.status_code == 200
        assert len(resp.json()) == 5


# =============================================================================
# DEADLINE PROCESSING Tests
# =============================================================================

class TestDeadlineProcessing:
    def test_process_deadlines_empty(self):
        resp = client.post("/api/compliance/dsr/deadlines/process", headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["processed"] == 0

    def test_process_deadlines_with_overdue(self, db_session):
        _create_dsr_in_db(db_session, status="processing",
                          deadline_at=datetime.now(timezone.utc) - timedelta(days=5))
        _create_dsr_in_db(db_session, status="processing",
                          deadline_at=datetime.now(timezone.utc) + timedelta(days=20))

        resp = client.post("/api/compliance/dsr/deadlines/process", headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["processed"] == 1


# =============================================================================
# TEMPLATE Tests
# =============================================================================

class TestDSRTemplates:
    def test_get_templates(self, db_session):
        t = DSRTemplateDB(
            tenant_id=uuid.UUID(TENANT_ID),
            name="Eingangsbestaetigung",
            template_type="receipt",
            language="de",
        )
        db_session.add(t)
        db_session.commit()

        resp = client.get("/api/compliance/dsr/templates", headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert len(data) >= 1

    def test_get_published_templates(self, db_session):
        t = DSRTemplateDB(
            tenant_id=uuid.UUID(TENANT_ID),
            name="Test",
            template_type="receipt",
            language="de",
            is_active=True,
        )
        db_session.add(t)
        db_session.commit()
        db_session.refresh(t)

        v = DSRTemplateVersionDB(
            template_id=t.id,
            version="1.0",
            subject="Bestaetigung",
            body_html="<p>Test</p>",
            status="published",
            published_at=datetime.now(timezone.utc),
        )
        db_session.add(v)
        db_session.commit()

        resp = client.get("/api/compliance/dsr/templates/published", headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert len(data) >= 1
        assert data[0]["latest_version"] is not None

    def test_create_template_version(self, db_session):
        t = DSRTemplateDB(
            tenant_id=uuid.UUID(TENANT_ID),
            name="Test",
            template_type="receipt",
            language="de",
        )
        db_session.add(t)
        db_session.commit()
        db_session.refresh(t)

        resp = client.post(f"/api/compliance/dsr/templates/{t.id}/versions", json={
            "version": "1.0",
            "subject": "Bestaetigung {{referenceNumber}}",
            "body_html": "<p>Ihre Anfrage wurde erhalten.</p>",
        }, headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["version"] == "1.0"
        assert data["status"] == "draft"

    def test_publish_template_version(self, db_session):
        t = DSRTemplateDB(
            tenant_id=uuid.UUID(TENANT_ID),
            name="Test",
            template_type="receipt",
            language="de",
        )
        db_session.add(t)
        db_session.commit()
        db_session.refresh(t)

        v = DSRTemplateVersionDB(
            template_id=t.id,
            version="1.0",
            subject="Test",
            body_html="<p>Test</p>",
            status="draft",
        )
        db_session.add(v)
        db_session.commit()
        db_session.refresh(v)

        resp = client.put(f"/api/compliance/dsr/template-versions/{v.id}/publish", headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert data["status"] == "published"
        assert data["published_at"] is not None

    def test_get_template_versions(self, db_session):
        t = DSRTemplateDB(
            tenant_id=uuid.UUID(TENANT_ID),
            name="Test",
            template_type="receipt",
            language="de",
        )
        db_session.add(t)
        db_session.commit()
        db_session.refresh(t)

        v = DSRTemplateVersionDB(
            template_id=t.id,
            version="1.0",
            subject="V1",
            body_html="<p>V1</p>",
        )
        db_session.add(v)
        db_session.commit()

        resp = client.get(f"/api/compliance/dsr/templates/{t.id}/versions", headers=HEADERS)
        assert resp.status_code == 200
        assert len(resp.json()) == 1

    def test_get_template_versions_not_found(self):
        fake_id = str(uuid.uuid4())
        resp = client.get(f"/api/compliance/dsr/templates/{fake_id}/versions", headers=HEADERS)
        assert resp.status_code == 404


class TestDSRExport:
    """Tests for DSR export endpoint."""

    def test_export_csv_empty(self):
        resp = client.get("/api/compliance/dsr/export?format=csv", headers=HEADERS)
        assert resp.status_code == 200
        assert "text/csv" in resp.headers.get("content-type", "")
        lines = resp.text.strip().split("\n")
        assert len(lines) == 1  # Header only
        assert "Referenznummer" in lines[0]
        assert "Zugewiesen" in lines[0]

    def test_export_csv_with_data(self):
        # Create a DSR first
        body = {
            "request_type": "access",
            "requester_name": "Export Test",
            "requester_email": "export@example.de",
            "source": "email",
        }
        create_resp = client.post("/api/compliance/dsr", json=body, headers=HEADERS)
        assert create_resp.status_code == 200

        resp = client.get("/api/compliance/dsr/export?format=csv", headers=HEADERS)
        assert resp.status_code == 200
        lines = resp.text.strip().split("\n")
        assert len(lines) >= 2  # Header + at least 1 data row
        # Check data row contains our test data
        assert "Export Test" in lines[1]
        assert "export@example.de" in lines[1]
        assert "access" in lines[1]

    def test_export_json(self):
        resp = client.get("/api/compliance/dsr/export?format=json", headers=HEADERS)
        assert resp.status_code == 200
        data = resp.json()
        assert "exported_at" in data
        assert "total" in data
        assert "requests" in data
        assert isinstance(data["requests"], list)

    def test_export_invalid_format(self):
        resp = client.get("/api/compliance/dsr/export?format=xml", headers=HEADERS)
        assert resp.status_code == 422  # Validation error
