# core/serializers.py
import json
import ipaddress

from rest_framework import serializers
from .models import CoreSettings, UserAgent, StreamProfile, DVR_SETTINGS_KEY, NETWORK_ACCESS_KEY


class UserAgentSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserAgent
        fields = [
            "id",
            "name",
            "user_agent",
            "description",
            "is_active",
            "created_at",
            "updated_at",
        ]


class StreamProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = StreamProfile
        fields = [
            "id",
            "name",
            "command",
            "parameters",
            "is_active",
            "user_agent",
            "locked",
        ]


class CoreSettingsSerializer(serializers.ModelSerializer):
    class Meta:
        model = CoreSettings
        fields = "__all__"

    def update(self, instance, validated_data):
        if instance.key == NETWORK_ACCESS_KEY:
            errors = False
            invalid = {}
            value = validated_data.get("value")
            for key, val in value.items():
                cidrs = val.split(",")
                for cidr in cidrs:
                    try:
                        ipaddress.ip_network(cidr)
                    except:
                        errors = True
                        if key not in invalid:
                            invalid[key] = []
                        invalid[key].append(cidr)

            if errors:
                # Perform CIDR validation
                raise serializers.ValidationError(
                    {
                        "message": "Invalid CIDRs",
                        "value": invalid,
                    }
                )

        # Sanitize series_rules when DVR settings are saved through the
        # generic settings API (e.g. Settings page round-trip) to prevent
        # corrupted non-dict entries from persisting.
        if instance.key == DVR_SETTINGS_KEY:
            value = validated_data.get("value")
            if isinstance(value, dict) and "series_rules" in value:
                rules = value["series_rules"]
                value["series_rules"] = (
                    [r for r in rules if isinstance(r, dict)]
                    if isinstance(rules, list)
                    else []
                )

        result = super().update(instance, validated_data)

        # Note: Cache invalidation and notification sync is handled by post_save signal
        # in core/signals.py to ensure it happens even if settings are updated elsewhere

        return result

class ProxySettingsSerializer(serializers.Serializer):
    """Serializer for proxy settings stored as JSON in CoreSettings"""
    buffering_timeout = serializers.IntegerField(min_value=0, max_value=300)
    buffering_speed = serializers.FloatField(min_value=0.1, max_value=10.0)
    redis_chunk_ttl = serializers.IntegerField(min_value=10, max_value=3600)
    channel_shutdown_delay = serializers.IntegerField(min_value=0, max_value=300)
    channel_init_grace_period = serializers.IntegerField(min_value=0, max_value=60)
    new_client_behind_seconds = serializers.IntegerField(min_value=0, max_value=120, required=False, default=5)

    def validate_buffering_timeout(self, value):
        if value < 0 or value > 300:
            raise serializers.ValidationError("Buffering timeout must be between 0 and 300 seconds")
        return value

    def validate_buffering_speed(self, value):
        if value < 0.1 or value > 10.0:
            raise serializers.ValidationError("Buffering speed must be between 0.1 and 10.0")
        return value

    def validate_redis_chunk_ttl(self, value):
        if value < 10 or value > 3600:
            raise serializers.ValidationError("Redis chunk TTL must be between 10 and 3600 seconds")
        return value

    def validate_channel_shutdown_delay(self, value):
        if value < 0 or value > 300:
            raise serializers.ValidationError("Channel shutdown delay must be between 0 and 300 seconds")
        return value

    def validate_channel_init_grace_period(self, value):
        if value < 0 or value > 60:
            raise serializers.ValidationError("Channel init grace period must be between 0 and 60 seconds")
        return value

    def validate_new_client_behind_seconds(self, value):
        if value < 0 or value > 120:
            raise serializers.ValidationError("New client buffer must be between 0 and 120 seconds")
        return value


class SystemNotificationSerializer(serializers.ModelSerializer):
    """Serializer for system notifications."""
    is_dismissed = serializers.SerializerMethodField()

    class Meta:
        from .models import SystemNotification
        model = SystemNotification
        fields = [
            'id',
            'notification_key',
            'notification_type',
            'priority',
            'title',
            'message',
            'action_data',
            'is_active',
            'admin_only',
            'expires_at',
            'created_at',
            'is_dismissed',
            'source',
        ]
        read_only_fields = ['created_at']

    def get_is_dismissed(self, obj):
        """Check if the current user has dismissed this notification."""
        request = self.context.get('request')
        if request and request.user.is_authenticated:
            return obj.dismissals.filter(user=request.user).exists()
        return False


class NotificationDismissalSerializer(serializers.ModelSerializer):
    """Serializer for notification dismissals."""

    class Meta:
        from .models import NotificationDismissal
        model = NotificationDismissal
        fields = ['id', 'notification', 'dismissed_at', 'action_taken']
        read_only_fields = ['dismissed_at']
