""" History domain serializers for ThrillWiki API v1. This module contains serializers for history tracking and timeline functionality using django-pghistory. """ from rest_framework import serializers from drf_spectacular.utils import extend_schema_field class ParkHistoryEventSerializer(serializers.Serializer): """Serializer for park history events.""" pgh_id = serializers.IntegerField(read_only=True) pgh_created_at = serializers.DateTimeField(read_only=True) pgh_label = serializers.CharField(read_only=True) pgh_obj_id = serializers.IntegerField(read_only=True) pgh_context = serializers.JSONField(read_only=True, allow_null=True) pgh_data = serializers.JSONField(read_only=True) event_type = serializers.SerializerMethodField() changes = serializers.SerializerMethodField() @extend_schema_field(serializers.CharField()) def get_event_type(self, obj) -> str: """Get human-readable event type.""" return obj.pgh_label.replace("_", " ").title() @extend_schema_field(serializers.DictField()) def get_changes(self, obj) -> dict: """Get changes made in this event.""" if hasattr(obj, "pgh_diff") and obj.pgh_diff: return obj.pgh_diff return {} class RideHistoryEventSerializer(serializers.Serializer): """Serializer for ride history events.""" pgh_id = serializers.IntegerField(read_only=True) pgh_created_at = serializers.DateTimeField(read_only=True) pgh_label = serializers.CharField(read_only=True) pgh_obj_id = serializers.IntegerField(read_only=True) pgh_context = serializers.JSONField(read_only=True, allow_null=True) pgh_data = serializers.JSONField(read_only=True) event_type = serializers.SerializerMethodField() changes = serializers.SerializerMethodField() @extend_schema_field(serializers.CharField()) def get_event_type(self, obj) -> str: """Get human-readable event type.""" return obj.pgh_label.replace("_", " ").title() @extend_schema_field(serializers.DictField()) def get_changes(self, obj) -> dict: """Get changes made in this event.""" if hasattr(obj, "pgh_diff") and obj.pgh_diff: return obj.pgh_diff return {} class HistorySummarySerializer(serializers.Serializer): """Serializer for history summary information.""" total_events = serializers.IntegerField() first_recorded = serializers.DateTimeField(allow_null=True) last_modified = serializers.DateTimeField(allow_null=True) class ParkHistoryOutputSerializer(serializers.Serializer): """Output serializer for complete park history.""" park = serializers.SerializerMethodField() current_state = serializers.SerializerMethodField() summary = HistorySummarySerializer() events = ParkHistoryEventSerializer(many=True) @extend_schema_field(serializers.DictField()) def get_park(self, obj) -> dict: """Get basic park information.""" park = obj.get("park") if park: return { "id": park.id, "name": park.name, "slug": park.slug, "status": park.status, } return {} @extend_schema_field(serializers.DictField()) def get_current_state(self, obj) -> dict: """Get current park state.""" park = obj.get("current_state") if park: return { "id": park.id, "name": park.name, "slug": park.slug, "status": park.status, "opening_date": ( park.opening_date.isoformat() if hasattr(park, "opening_date") and park.opening_date else None ), "coaster_count": getattr(park, "coaster_count", 0), "ride_count": getattr(park, "ride_count", 0), } return {} class RideHistoryOutputSerializer(serializers.Serializer): """Output serializer for complete ride history.""" ride = serializers.SerializerMethodField() current_state = serializers.SerializerMethodField() summary = HistorySummarySerializer() events = RideHistoryEventSerializer(many=True) @extend_schema_field(serializers.DictField()) def get_ride(self, obj) -> dict: """Get basic ride information.""" ride = obj.get("ride") if ride: return { "id": ride.id, "name": ride.name, "slug": ride.slug, "park_name": ride.park.name if hasattr(ride, "park") else None, "status": getattr(ride, "status", "UNKNOWN"), } return {} @extend_schema_field(serializers.DictField()) def get_current_state(self, obj) -> dict: """Get current ride state.""" ride = obj.get("current_state") if ride: return { "id": ride.id, "name": ride.name, "slug": ride.slug, "park_name": ride.park.name if hasattr(ride, "park") else None, "status": getattr(ride, "status", "UNKNOWN"), "opening_date": ( ride.opening_date.isoformat() if hasattr(ride, "opening_date") and ride.opening_date else None ), "ride_type": getattr(ride, "ride_type", "Unknown"), } return {} class UnifiedHistoryTimelineSerializer(serializers.Serializer): """Serializer for unified history timeline.""" summary = serializers.SerializerMethodField() events = serializers.SerializerMethodField() @extend_schema_field(serializers.DictField()) def get_summary(self, obj) -> dict: """Get timeline summary.""" return obj.get("summary", {}) @extend_schema_field(serializers.ListField(child=serializers.DictField())) def get_events(self, obj) -> list: """Get timeline events.""" events = obj.get("events", []) event_data = [] for event in events: event_data.append( { "pgh_id": event.pgh_id, "pgh_created_at": event.pgh_created_at, "pgh_label": event.pgh_label, "pgh_model": event.pgh_model, "pgh_obj_id": event.pgh_obj_id, "pgh_context": event.pgh_context, "event_type": event.pgh_label.replace("_", " ").title(), "model_type": event.pgh_model.split(".")[-1].title(), } ) return event_data