"""
REST API Serializers for Notifications Application

This module contains Django REST Framework serializers for notification
management, channels, templates, and rules.
"""

from rest_framework import serializers
from django.contrib.auth.models import User
from apps.notifications.models import (
    NotificationChannel, NotificationTemplate, Notification, NotificationRule,
    NotificationPreference, NotificationSubscription, NotificationHistory
)


class NotificationChannelSerializer(serializers.ModelSerializer):
    """
    Serializer for NotificationChannel model.
    
    Handles serialization of notification channel configurations
    with validation and security considerations.
    """
    
    created_by = serializers.StringRelatedField(read_only=True)
    is_configured = serializers.SerializerMethodField()
    last_used = serializers.SerializerMethodField()
    
    class Meta:
        model = NotificationChannel
        fields = [
            'id', 'name', 'channel_type', 'is_active', 'configuration',
            'rate_limit', 'retry_attempts', 'timeout_seconds',
            'created_by', 'is_configured', 'last_used',
            'created_at', 'updated_at'
        ]
        read_only_fields = ['id', 'created_by', 'created_at', 'updated_at']
        extra_kwargs = {
            'configuration': {'write_only': True}  # Hide sensitive config in responses
        }

    def get_is_configured(self, obj):
        """Check if channel is properly configured."""
        return obj.is_configured()

    def get_last_used(self, obj):
        """Get timestamp of last notification sent through this channel."""
        last_notification = obj.notifications.order_by('-sent_at').first()
        return last_notification.sent_at if last_notification and last_notification.sent_at else None

    def validate_configuration(self, value):
        """Validate channel configuration based on type."""
        channel_type = self.initial_data.get('channel_type')
        
        if channel_type == 'telegram':
            if not value.get('bot_token') or not value.get('chat_id'):
                raise serializers.ValidationError(
                    "Telegram channels require 'bot_token' and 'chat_id'"
                )
        elif channel_type == 'email':
            if not value.get('recipients'):
                raise serializers.ValidationError(
                    "Email channels require 'recipients' list"
                )
        elif channel_type == 'webhook':
            if not value.get('url'):
                raise serializers.ValidationError(
                    "Webhook channels require 'url'"
                )
        
        return value


class NotificationTemplateSerializer(serializers.ModelSerializer):
    """
    Serializer for NotificationTemplate model.
    
    Handles template data with variable validation and usage statistics.
    """
    
    usage_count = serializers.SerializerMethodField()
    last_used = serializers.SerializerMethodField()
    
    class Meta:
        model = NotificationTemplate
        fields = [
            'id', 'name', 'template_type', 'subject_template',
            'message_template', 'variables', 'channel_types',
            'is_active', 'usage_count', 'last_used',
            'created_at', 'updated_at'
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']

    def get_usage_count(self, obj):
        """Get number of times this template has been used."""
        return obj.notifications.count()

    def get_last_used(self, obj):
        """Get timestamp of last usage."""
        last_notification = obj.notifications.order_by('-created_at').first()
        return last_notification.created_at if last_notification else None

    def validate_variables(self, value):
        """Validate that template variables are properly defined."""
        if not isinstance(value, list):
            raise serializers.ValidationError("Variables must be a list")
        
        # Check for duplicate variables
        if len(value) != len(set(value)):
            raise serializers.ValidationError("Duplicate variables not allowed")
        
        return value


class NotificationSerializer(serializers.ModelSerializer):
    """
    Serializer for Notification model.
    
    Provides notification data with delivery status and metadata.
    """
    
    channel_name = serializers.StringRelatedField(source='channel.name', read_only=True)
    template_name = serializers.StringRelatedField(source='template.name', read_only=True)
    is_sent = serializers.SerializerMethodField()
    delivery_duration = serializers.SerializerMethodField()
    
    class Meta:
        model = Notification
        fields = [
            'id', 'channel', 'template', 'channel_name', 'template_name',
            'subject', 'message', 'context', 'status', 'is_sent',
            'scheduled_at', 'sent_at', 'delivery_duration', 'retry_count',
            'error_message', 'created_at', 'updated_at'
        ]
        read_only_fields = [
            'id', 'sent_at', 'retry_count', 'error_message',
            'created_at', 'updated_at'
        ]

    def get_is_sent(self, obj):
        """Check if notification was successfully sent."""
        return obj.is_sent()

    def get_delivery_duration(self, obj):
        """Get delivery duration in seconds."""
        if obj.sent_at and obj.created_at:
            delta = obj.sent_at - obj.created_at
            return int(delta.total_seconds())
        return None


class NotificationRuleSerializer(serializers.ModelSerializer):
    """
    Serializer for NotificationRule model.
    
    Handles rule configuration with condition validation.
    """
    
    channel_name = serializers.StringRelatedField(source='channel.name', read_only=True)
    template_name = serializers.StringRelatedField(source='template.name', read_only=True)
    
    class Meta:
        model = NotificationRule
        fields = [
            'id', 'name', 'event_type', 'channel', 'template',
            'channel_name', 'template_name', 'conditions', 'is_active',
            'priority', 'created_at', 'updated_at'
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']

    def validate_conditions(self, value):
        """Validate rule conditions format."""
        if not isinstance(value, dict):
            raise serializers.ValidationError("Conditions must be a dictionary")
        
        # Validate condition structure
        allowed_operators = ['eq', 'ne', 'gt', 'lt', 'gte', 'lte', 'in', 'contains']
        
        for field, condition in value.items():
            if isinstance(condition, dict):
                operator = condition.get('operator')
                if operator and operator not in allowed_operators:
                    raise serializers.ValidationError(
                        f"Invalid operator '{operator}' for field '{field}'"
                    )
        
        return value


class NotificationStatsSerializer(serializers.Serializer):
    """
    Serializer for notification statistics data.
    
    Provides aggregated notification metrics for reporting.
    """
    
    total_notifications = serializers.IntegerField()
    sent_notifications = serializers.IntegerField()
    failed_notifications = serializers.IntegerField()
    pending_notifications = serializers.IntegerField()
    delivery_rate = serializers.FloatField()
    avg_delivery_time = serializers.FloatField()
    channel_performance = serializers.DictField()
    recent_activity = serializers.ListField()


class NotificationPreferenceSerializer(serializers.ModelSerializer):
    """
    Serializer for NotificationPreference model.
    
    Handles user notification preferences and settings.
    """
    
    user_username = serializers.StringRelatedField(source='user.username', read_only=True)
    channel_name = serializers.StringRelatedField(source='channel.name', read_only=True)
    
    class Meta:
        model = NotificationPreference
        fields = [
            'id', 'user', 'user_username', 'channel', 'channel_name',
            'event_type', 'is_enabled', 'quiet_hours_start', 'quiet_hours_end',
            'settings', 'created_at', 'updated_at'
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']
    
    def validate(self, data):
        """Validate quiet hours configuration."""
        quiet_start = data.get('quiet_hours_start')
        quiet_end = data.get('quiet_hours_end')
        
        if quiet_start and quiet_end:
            if quiet_start >= quiet_end:
                raise serializers.ValidationError(
                    "Quiet hours start time must be before end time"
                )
        
        return data


class NotificationSubscriptionSerializer(serializers.ModelSerializer):
    """
    Serializer for NotificationSubscription model.
    
    Handles user subscriptions to notification topics.
    """
    
    user_username = serializers.StringRelatedField(source='user.username', read_only=True)
    
    class Meta:
        model = NotificationSubscription
        fields = [
            'id', 'user', 'user_username', 'topic', 'is_active',
            'frequency', 'last_notification_sent', 'metadata',
            'created_at', 'updated_at'
        ]
        read_only_fields = ['id', 'last_notification_sent', 'created_at', 'updated_at']
    
    def validate_frequency(self, value):
        """Validate frequency choice."""
        valid_frequencies = ['immediate', 'hourly', 'daily', 'weekly']
        if value not in valid_frequencies:
            raise serializers.ValidationError(
                f"Frequency must be one of: {', '.join(valid_frequencies)}"
            )
        return value


class NotificationHistorySerializer(serializers.ModelSerializer):
    """
    Serializer for NotificationHistory model.
    
    Provides detailed tracking and analytics for notification delivery.
    """
    
    notification_subject = serializers.StringRelatedField(source='notification.subject', read_only=True)
    notification_recipient = serializers.StringRelatedField(source='notification.recipient', read_only=True)
    
    class Meta:
        model = NotificationHistory
        fields = [
            'id', 'notification', 'notification_subject', 'notification_recipient',
            'action', 'status', 'timestamp', 'error_details', 'metadata'
        ]
        read_only_fields = ['id', 'timestamp']
    
    def validate_action(self, value):
        """Validate action choice."""
        valid_actions = ['created', 'queued', 'sent', 'failed', 'retried', 'cancelled']
        if value not in valid_actions:
            raise serializers.ValidationError(
                f"Action must be one of: {', '.join(valid_actions)}"
            )
        return value
    
    def validate_status(self, value):
        """Validate status choice."""
        valid_statuses = ['success', 'error', 'warning', 'info']
        if value not in valid_statuses:
            raise serializers.ValidationError(
                f"Status must be one of: {', '.join(valid_statuses)}"
            )
        return value
