"""
Notification API Serializers.
"""
from rest_framework import serializers

from .models import (
    NotificationCategory,
    NotificationTemplate,
    Notification,
    NotificationLog,
    UserNotificationPreference,
    NotificationChannel,
    NotificationPriority,
)


class NotificationCategorySerializer(serializers.ModelSerializer):
    """Serializer for NotificationCategory model."""
    
    class Meta:
        model = NotificationCategory
        fields = [
            'id',
            'name',
            'label',
            'description',
            'icon',
            'color',
            'is_active',
            'created_at',
            'updated_at',
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']


class NotificationTemplateSerializer(serializers.ModelSerializer):
    """Serializer for NotificationTemplate model."""
    
    category_name = serializers.CharField(source='category.label', read_only=True)
    channel_display = serializers.CharField(source='get_channel_display', read_only=True)
    
    class Meta:
        model = NotificationTemplate
        fields = [
            'id',
            'name',
            'title',
            'channel',
            'channel_display',
            'subject',
            'content',
            'variables',
            'category',
            'category_name',
            'is_active',
            'created_at',
            'updated_at',
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']


class NotificationTemplatePreviewSerializer(serializers.Serializer):
    """Serializer for template preview request."""
    
    content = serializers.CharField()
    variables = serializers.DictField(required=False, default=dict)


class NotificationLogSerializer(serializers.ModelSerializer):
    """Serializer for NotificationLog model."""
    
    status_display = serializers.CharField(source='get_status_display', read_only=True)
    channel_display = serializers.CharField(source='get_channel_display', read_only=True)
    
    class Meta:
        model = NotificationLog
        fields = [
            'id',
            'channel',
            'channel_display',
            'status',
            'status_display',
            'provider_response',
            'error_message',
            'retry_count',
            'created_at',
        ]
        read_only_fields = fields


class NotificationSerializer(serializers.ModelSerializer):
    """Serializer for Notification model."""
    
    category_name = serializers.CharField(source='category.label', read_only=True)
    template_name = serializers.CharField(source='template.name', read_only=True)
    channel_display = serializers.CharField(source='get_channel_display', read_only=True)
    status_display = serializers.CharField(source='get_status_display', read_only=True)
    priority_display = serializers.CharField(source='get_priority_display', read_only=True)
    logs = NotificationLogSerializer(many=True, read_only=True)
    
    class Meta:
        model = Notification
        fields = [
            'id',
            'channel',
            'channel_display',
            'title',
            'content',
            'priority',
            'priority_display',
            'status',
            'status_display',
            'is_read',
            'read_at',
            'scheduled_at',
            'sent_at',
            'metadata',
            'category',
            'category_name',
            'template',
            'template_name',
            'logs',
            'created_at',
        ]
        read_only_fields = fields


class NotificationListSerializer(serializers.ModelSerializer):
    """Lightweight serializer for notification list."""
    
    category_name = serializers.CharField(source='category.label', read_only=True)
    channel_display = serializers.CharField(source='get_channel_display', read_only=True)
    priority_display = serializers.CharField(source='get_priority_display', read_only=True)
    
    class Meta:
        model = Notification
        fields = [
            'id',
            'channel',
            'channel_display',
            'title',
            'priority',
            'priority_display',
            'is_read',
            'category_name',
            'metadata',
            'created_at',
        ]
        read_only_fields = fields


class SendNotificationSerializer(serializers.Serializer):
    """Serializer for sending notification."""
    
    user_id = serializers.IntegerField(required=False, help_text="User ID to send to")
    user_ids = serializers.ListField(
        child=serializers.IntegerField(),
        required=False,
        help_text="List of User IDs for bulk send"
    )
    template_name = serializers.CharField(required=False, help_text="Template name to use")
    channel = serializers.ChoiceField(
        choices=NotificationChannel.choices,
        required=False,
        help_text="Override channel"
    )
    title = serializers.CharField(required=False, max_length=255)
    content = serializers.CharField(required=False)
    variables = serializers.DictField(required=False, default=dict)
    priority = serializers.ChoiceField(
        choices=NotificationPriority.choices,
        default=NotificationPriority.NORMAL,
    )
    metadata = serializers.DictField(required=False, default=dict)
    
    def validate(self, attrs):
        """Validate that either user_id or user_ids is provided."""
        if not attrs.get('user_id') and not attrs.get('user_ids'):
            raise serializers.ValidationError(
                "Either 'user_id' or 'user_ids' must be provided."
            )
        
        if not attrs.get('template_name') and not attrs.get('content'):
            raise serializers.ValidationError(
                "Either 'template_name' or 'content' must be provided."
            )
        
        return attrs


class ScheduleNotificationSerializer(SendNotificationSerializer):
    """Serializer for scheduling notification."""
    
    scheduled_at = serializers.DateTimeField(required=True)
    
    def validate_scheduled_at(self, value):
        """Ensure scheduled time is in the future."""
        from django.utils import timezone
        
        if value <= timezone.now():
            raise serializers.ValidationError(
                "Scheduled time must be in the future."
            )
        return value


class UserNotificationPreferenceSerializer(serializers.ModelSerializer):
    """Serializer for UserNotificationPreference model."""
    
    category_name = serializers.CharField(source='category.label', read_only=True)
    
    class Meta:
        model = UserNotificationPreference
        fields = [
            'id',
            'category',
            'category_name',
            'sms_enabled',
            'email_enabled',
            'panel_enabled',
            'created_at',
            'updated_at',
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']


class UpdatePreferencesSerializer(serializers.Serializer):
    """Serializer for bulk updating preferences."""
    
    preferences = serializers.ListField(
        child=serializers.DictField(),
        help_text="List of preference updates"
    )
    
    def validate_preferences(self, value):
        """Validate preference updates."""
        for pref in value:
            if 'category_id' not in pref:
                raise serializers.ValidationError(
                    "Each preference must have 'category_id'."
                )
        return value


class UnreadCountSerializer(serializers.Serializer):
    """Serializer for unread count response."""
    
    count = serializers.IntegerField()
