"""
Services domain serializers for ThrillWiki API v1.

This module contains serializers for various services like email, maps,
history tracking, moderation, and roadtrip planning.
"""

from drf_spectacular.utils import (
    extend_schema_field,
)
from rest_framework import serializers

# === HEALTH CHECK SERIALIZERS ===


class HealthCheckOutputSerializer(serializers.Serializer):
    """Output serializer for comprehensive health check responses."""

    status = serializers.CharField(help_text="Overall health status")
    timestamp = serializers.DateTimeField(help_text="Timestamp of health check")
    version = serializers.CharField(help_text="Application version")
    environment = serializers.CharField(help_text="Environment name")
    response_time_ms = serializers.FloatField(help_text="Response time in milliseconds")
    checks = serializers.DictField(help_text="Individual health check results")
    metrics = serializers.DictField(help_text="System metrics")


class PerformanceMetricsOutputSerializer(serializers.Serializer):
    """Output serializer for performance metrics responses."""

    timestamp = serializers.DateTimeField(help_text="Timestamp of metrics collection")
    database_analysis = serializers.DictField(help_text="Database performance analysis")
    cache_performance = serializers.DictField(help_text="Cache performance metrics")
    recent_slow_queries = serializers.DictField(help_text="Recent slow query analysis")


class SimpleHealthOutputSerializer(serializers.Serializer):
    """Output serializer for simple health check responses."""

    status = serializers.CharField(help_text="Simple health status")
    timestamp = serializers.DateTimeField(help_text="Timestamp of health check")
    error = serializers.CharField(required=False, help_text="Error message if unhealthy")


# === EMAIL SERVICE SERIALIZERS ===


class EmailSendInputSerializer(serializers.Serializer):
    """Input serializer for sending emails."""

    to = serializers.EmailField()
    subject = serializers.CharField(max_length=255)
    text = serializers.CharField()
    html = serializers.CharField(required=False)
    template = serializers.CharField(required=False)
    template_context = serializers.JSONField(required=False)


class EmailTemplateOutputSerializer(serializers.Serializer):
    """Output serializer for email templates."""

    id = serializers.CharField()
    name = serializers.CharField()
    subject = serializers.CharField()
    text_template = serializers.CharField()
    html_template = serializers.CharField(required=False)


# === MAP SERVICE SERIALIZERS ===


class MapDataOutputSerializer(serializers.Serializer):
    """Output serializer for map data."""

    parks = serializers.ListField(child=serializers.DictField())
    rides = serializers.ListField(child=serializers.DictField())
    bounds = serializers.DictField()
    zoom_level = serializers.IntegerField()


class CoordinateInputSerializer(serializers.Serializer):
    """Input serializer for coordinate-based requests."""

    latitude = serializers.FloatField(min_value=-90, max_value=90)
    longitude = serializers.FloatField(min_value=-180, max_value=180)
    radius_km = serializers.FloatField(min_value=0, max_value=1000, default=10)


# === HISTORY SERIALIZERS ===


class HistoryEventSerializer(serializers.Serializer):
    """Base serializer for history events from pghistory."""

    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_diff = serializers.SerializerMethodField()

    @extend_schema_field(serializers.DictField())
    def get_pgh_diff(self, obj) -> dict:
        """Get diff from previous version if available."""
        if hasattr(obj, "diff_against_previous"):
            return obj.diff_against_previous()
        return {}


class HistoryEntryOutputSerializer(serializers.Serializer):
    """Output serializer for history entries."""

    id = serializers.IntegerField()
    model_type = serializers.CharField()
    object_id = serializers.IntegerField()
    object_name = serializers.CharField()
    action = serializers.CharField()
    changes = serializers.JSONField()
    timestamp = serializers.DateTimeField()
    user = serializers.SerializerMethodField()

    @extend_schema_field(serializers.DictField(allow_null=True))
    def get_user(self, obj) -> dict | None:
        if hasattr(obj, "user") and obj.user:
            return {
                "id": obj.user.id,
                "username": obj.user.username,
            }
        return None


class HistoryCreateInputSerializer(serializers.Serializer):
    """Input serializer for creating history entries."""

    action = serializers.CharField(max_length=50)
    description = serializers.CharField(max_length=500)
    metadata = serializers.JSONField(required=False)


# === MODERATION SERIALIZERS ===


class ModerationSubmissionSerializer(serializers.Serializer):
    """Serializer for moderation submissions."""

    submission_type = serializers.ChoiceField(
        choices=[
            ("EDIT", "Edit Submission"),
            ("PHOTO", "Photo Submission"),
            ("REVIEW", "Review Submission"),
        ],
        help_text="Type of submission",
    )
    content_type = serializers.CharField(help_text="Content type being modified")
    object_id = serializers.IntegerField(help_text="ID of object being modified")
    changes = serializers.JSONField(help_text="Changes being submitted")
    reason = serializers.CharField(
        max_length=500,
        required=False,
        allow_blank=True,
        help_text="Reason for the changes",
    )


class ModerationSubmissionOutputSerializer(serializers.Serializer):
    """Output serializer for moderation submission responses."""

    status = serializers.CharField()
    message = serializers.CharField()
    submission_id = serializers.IntegerField(required=False)
    auto_approved = serializers.BooleanField(required=False)


# === ROADTRIP SERIALIZERS ===


class RoadtripParkSerializer(serializers.Serializer):
    """Serializer for parks in roadtrip planning."""

    id = serializers.IntegerField()
    name = serializers.CharField()
    slug = serializers.CharField()
    latitude = serializers.FloatField()
    longitude = serializers.FloatField()
    coaster_count = serializers.IntegerField()
    status = serializers.CharField()


class RoadtripCreateInputSerializer(serializers.Serializer):
    """Input serializer for creating roadtrips."""

    name = serializers.CharField(max_length=255)
    park_ids = serializers.ListField(
        child=serializers.IntegerField(),
        min_length=2,
        max_length=10,
        help_text="List of park IDs (2-10 parks)",
    )
    start_date = serializers.DateField(required=False)
    end_date = serializers.DateField(required=False)
    notes = serializers.CharField(max_length=1000, required=False, allow_blank=True)

    def validate_park_ids(self, value):
        """Validate park IDs."""
        if len(value) < 2:
            raise serializers.ValidationError("At least 2 parks are required")
        if len(value) > 10:
            raise serializers.ValidationError("Maximum 10 parks allowed")
        if len(set(value)) != len(value):
            raise serializers.ValidationError("Duplicate park IDs not allowed")
        return value


class RoadtripOutputSerializer(serializers.Serializer):
    """Output serializer for roadtrip responses."""

    id = serializers.CharField()
    name = serializers.CharField()
    parks = RoadtripParkSerializer(many=True)
    total_distance_miles = serializers.FloatField()
    estimated_drive_time_hours = serializers.FloatField()
    route_coordinates = serializers.ListField(child=serializers.ListField(child=serializers.FloatField()))
    created_at = serializers.DateTimeField()


class GeocodeInputSerializer(serializers.Serializer):
    """Input serializer for geocoding requests."""

    address = serializers.CharField(max_length=500, help_text="Address to geocode")


class GeocodeOutputSerializer(serializers.Serializer):
    """Output serializer for geocoding responses."""

    status = serializers.CharField()
    coordinates = serializers.JSONField(required=False)
    formatted_address = serializers.CharField(required=False)


# === DISTANCE CALCULATION SERIALIZERS ===
class DistanceCalculationInputSerializer(serializers.Serializer):
    """Input serializer for distance calculation requests."""

    park1_id = serializers.IntegerField(help_text="ID of first park")
    park2_id = serializers.IntegerField(help_text="ID of second park")

    def validate(self, attrs):
        """Validate that park IDs are different."""
        if attrs["park1_id"] == attrs["park2_id"]:
            raise serializers.ValidationError("Park IDs must be different")
        return attrs


class DistanceCalculationOutputSerializer(serializers.Serializer):
    """Output serializer for distance calculation responses."""

    status = serializers.CharField()
    distance_miles = serializers.FloatField(required=False)
    distance_km = serializers.FloatField(required=False)
    drive_time_hours = serializers.FloatField(required=False)
    message = serializers.CharField(required=False)
