from rest_framework import serializers
from django.utils import timezone
from .models import BroadcastMessage, MessageRecipient


class MessageRecipientSerializer(serializers.ModelSerializer):
    """Serializer for message delivery tracking."""
    user_email = serializers.CharField(source='user.email', read_only=True)
    user_name = serializers.SerializerMethodField()

    class Meta:
        model = MessageRecipient
        fields = [
            'id', 'user', 'user_email', 'user_name',
            'delivery_status', 'delivered_at',
            'is_read', 'read_at', 'error_message'
        ]
        read_only_fields = fields

    def get_user_name(self, obj):
        return obj.user.get_full_name() or obj.user.username


class BroadcastMessageListSerializer(serializers.ModelSerializer):
    """Serializer for listing broadcast messages."""
    sender_name = serializers.SerializerMethodField()
    target_description = serializers.SerializerMethodField()

    class Meta:
        model = BroadcastMessage
        fields = [
            'id', 'subject', 'status', 'delivery_method',
            'sender_name', 'target_description',
            'total_recipients', 'delivered_count', 'read_count',
            'created_at', 'sent_at', 'scheduled_at'
        ]
        read_only_fields = fields

    def get_sender_name(self, obj):
        if obj.sender:
            return obj.sender.get_full_name() or obj.sender.username
        return 'Unknown'

    def get_target_description(self, obj):
        return obj.get_target_description()


class BroadcastMessageDetailSerializer(serializers.ModelSerializer):
    """Serializer for broadcast message detail view."""
    sender_name = serializers.SerializerMethodField()
    target_description = serializers.SerializerMethodField()
    recipients = MessageRecipientSerializer(many=True, read_only=True)
    individual_recipient_ids = serializers.ListField(
        child=serializers.IntegerField(),
        write_only=True,
        required=False
    )

    class Meta:
        model = BroadcastMessage
        fields = [
            'id', 'subject', 'body', 'status', 'delivery_method',
            'target_owners', 'target_managers', 'target_staff', 'target_customers',
            'individual_recipient_ids',
            'sender_name', 'target_description',
            'total_recipients', 'delivered_count', 'failed_count', 'read_count',
            'created_at', 'updated_at', 'sent_at', 'scheduled_at',
            'recipients'
        ]
        read_only_fields = [
            'id', 'sender_name', 'target_description',
            'total_recipients', 'delivered_count', 'failed_count', 'read_count',
            'created_at', 'updated_at', 'sent_at', 'recipients'
        ]

    def get_sender_name(self, obj):
        if obj.sender:
            return obj.sender.get_full_name() or obj.sender.username
        return 'Unknown'

    def get_target_description(self, obj):
        return obj.get_target_description()

    def validate(self, data):
        """Ensure at least one target is selected."""
        target_owners = data.get('target_owners', False)
        target_managers = data.get('target_managers', False)
        target_staff = data.get('target_staff', False)
        target_customers = data.get('target_customers', False)
        individual_recipients = data.get('individual_recipient_ids', [])

        if not any([target_owners, target_managers, target_staff, target_customers]) and not individual_recipients:
            raise serializers.ValidationError(
                "At least one target group or individual recipient must be selected."
            )
        return data


class BroadcastMessageCreateSerializer(serializers.ModelSerializer):
    """Serializer for creating broadcast messages."""
    individual_recipient_ids = serializers.ListField(
        child=serializers.IntegerField(),
        write_only=True,
        required=False,
        default=[]
    )
    send_immediately = serializers.BooleanField(write_only=True, default=True)

    class Meta:
        model = BroadcastMessage
        fields = [
            'subject', 'body', 'delivery_method',
            'target_owners', 'target_managers', 'target_staff', 'target_customers',
            'individual_recipient_ids', 'scheduled_at', 'send_immediately'
        ]

    def validate(self, data):
        """Ensure at least one target is selected."""
        target_owners = data.get('target_owners', False)
        target_managers = data.get('target_managers', False)
        target_staff = data.get('target_staff', False)
        target_customers = data.get('target_customers', False)
        individual_recipients = data.get('individual_recipient_ids', [])

        if not any([target_owners, target_managers, target_staff, target_customers]) and not individual_recipients:
            raise serializers.ValidationError(
                "At least one target group or individual recipient must be selected."
            )
        return data

    def create(self, validated_data):
        individual_recipient_ids = validated_data.pop('individual_recipient_ids', [])
        send_immediately = validated_data.pop('send_immediately', True)

        # Set status based on scheduling
        if validated_data.get('scheduled_at') and not send_immediately:
            validated_data['status'] = BroadcastMessage.Status.SCHEDULED
        else:
            validated_data['status'] = BroadcastMessage.Status.DRAFT

        message = BroadcastMessage.objects.create(**validated_data)

        # Add individual recipients
        if individual_recipient_ids:
            from smoothschedule.identity.users.models import User
            users = User.objects.filter(id__in=individual_recipient_ids)
            message.individual_recipients.set(users)

        return message


class InboxMessageSerializer(serializers.ModelSerializer):
    """Serializer for user's inbox (received messages)."""
    sender_name = serializers.SerializerMethodField()
    is_read = serializers.SerializerMethodField()
    read_at = serializers.SerializerMethodField()

    class Meta:
        model = BroadcastMessage
        fields = [
            'id', 'subject', 'body', 'sender_name',
            'is_read', 'read_at', 'sent_at', 'created_at'
        ]
        read_only_fields = fields

    def get_sender_name(self, obj):
        if obj.sender:
            return obj.sender.get_full_name() or obj.sender.username
        return 'System'

    def get_is_read(self, obj):
        """Get read status for the current user."""
        request = self.context.get('request')
        if request and request.user:
            recipient = obj.recipients.filter(user=request.user).first()
            if recipient:
                return recipient.is_read
        return False

    def get_read_at(self, obj):
        """Get read timestamp for the current user."""
        request = self.context.get('request')
        if request and request.user:
            recipient = obj.recipients.filter(user=request.user).first()
            if recipient:
                return recipient.read_at
        return None
