import json

import pytest

from app.models import FaceDetection, InferenceResponse


def test_face_detection_serialization():
    """FaceDetection should serialize to correct JSON structure."""
    det = FaceDetection(identity="Alice", confidence=0.85, bbox=[10.0, 20.0, 100.0, 200.0])
    data = json.loads(det.model_dump_json())
    assert data["identity"] == "Alice"
    assert data["confidence"] == pytest.approx(0.85)
    assert data["bbox"] == [10.0, 20.0, 100.0, 200.0]


def test_face_detection_null_identity():
    """FaceDetection should allow null identity with zero confidence."""
    det = FaceDetection(identity=None, confidence=0.0, bbox=[0.0, 0.0, 50.0, 50.0])
    data = json.loads(det.model_dump_json())
    assert data["identity"] is None
    assert data["confidence"] == 0.0


def test_inference_response_serialization():
    """InferenceResponse should serialize timestamp and detections list."""
    response = InferenceResponse(
        timestamp=1707840000.123,
        detections=[
            FaceDetection(identity="Bob", confidence=0.7, bbox=[5.0, 5.0, 55.0, 55.0]),
            FaceDetection(identity=None, confidence=0.0, bbox=[100.0, 100.0, 150.0, 150.0]),
        ],
    )
    data = json.loads(response.model_dump_json())
    assert data["timestamp"] == pytest.approx(1707840000.123)
    assert len(data["detections"]) == 2
    assert data["detections"][0]["identity"] == "Bob"
    assert data["detections"][1]["identity"] is None


def test_inference_response_empty_detections():
    """InferenceResponse should allow empty detections list."""
    response = InferenceResponse(timestamp=0.0, detections=[])
    data = json.loads(response.model_dump_json())
    assert data["detections"] == []


def test_inference_response_matches_contract():
    """Response JSON keys must match the documented WebSocket API contract."""
    response = InferenceResponse(
        timestamp=1.0,
        detections=[FaceDetection(identity="Alice", confidence=0.9, bbox=[0.0, 0.0, 10.0, 10.0])],
    )
    data = json.loads(response.model_dump_json())
    assert set(data.keys()) == {"timestamp", "detections"}
    assert set(data["detections"][0].keys()) == {"identity", "confidence", "bbox"}
