"""
History domain serializers for ThrillWiki API v1.

This module contains serializers for history tracking and timeline functionality
using django-pghistory.
"""

from drf_spectacular.utils import extend_schema_field
from rest_framework import serializers


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
