from rest_framework import serializers
from django.contrib.auth import get_user_model
from .models import Conversation, Message

User = get_user_model()


class UserMiniSerializer(serializers.ModelSerializer):
    profile_image = serializers.SerializerMethodField()

    class Meta:
        model  = User
        fields = ["id", "username", "profile_image"]

    def get_profile_image(self, obj):
        request = self.context.get("request")
        img = getattr(obj, "profile_image", None)
        if img and hasattr(img, "url"):
            return request.build_absolute_uri(img.url) if request else img.url
        return None


class MessageSerializer(serializers.ModelSerializer):
    sender         = UserMiniSerializer(read_only=True)
    is_mine        = serializers.SerializerMethodField()
    reply_to       = serializers.SerializerMethodField()
    forwarded_from = serializers.SerializerMethodField()

    reactions = serializers.SerializerMethodField()

    class Meta:
        model  = Message
    image_url = serializers.SerializerMethodField()
    audio_url = serializers.SerializerMethodField()

    class Meta:
        model  = Message
        fields = [
            "id", "sender", "content", "image_url", "audio_url",
            "created_at", "updated_at", "edited",
            "deleted_for_everyone",
            "reply_to", "forwarded_from", "is_mine", "reactions",
        ]

    def get_audio_url(self, obj):
        if not obj.audio: return None
        request = self.context.get("request")
        return request.build_absolute_uri(obj.audio.url) if request else obj.audio.url

    def get_image_url(self, obj):
        if not obj.image: return None
        request = self.context.get("request")
        return request.build_absolute_uri(obj.image.url) if request else obj.image.url

    def get_reactions(self, obj):
        result = {}
        for r in obj.reactions.all():
            result[r.emoji] = result.get(r.emoji, [])
            result[r.emoji].append(r.user.username)
        return result

    def get_is_mine(self, obj):
        request = self.context.get("request")
        return bool(request and obj.sender_id == request.user.id)

    def get_reply_to(self, obj):
        if not obj.reply_to:
            return None
        if obj.reply_to.deleted_for_everyone:
            return {"id": obj.reply_to.id, "content": "This message was deleted", "deleted": True}
        return {
            "id":      obj.reply_to.id,
            "content": obj.reply_to.content,
            "sender":  obj.reply_to.sender.username,
            "deleted": False,
        }

    def get_forwarded_from(self, obj):
        if not obj.forwarded_from:
            return None
        if obj.forwarded_from.deleted_for_everyone:
            return {"id": obj.forwarded_from.id, "content": "This message was deleted", "deleted": True}
        return {
            "id":      obj.forwarded_from.id,
            "content": obj.forwarded_from.content,
            "sender":  obj.forwarded_from.sender.username,
            "deleted": False,
        }


class ConversationListSerializer(serializers.ModelSerializer):
    participants = UserMiniSerializer(many=True, read_only=True)
    other_user   = serializers.SerializerMethodField()
    last_message = serializers.SerializerMethodField()
    unread_count = serializers.SerializerMethodField()

    class Meta:
        model  = Conversation
        fields = ["id", "participants", "other_user", "last_message", "unread_count", "updated_at"]

    def _me(self):
        return self.context["request"].user

    def get_other_user(self, obj):
        other = obj.participants.exclude(id=self._me().id).first()
        return UserMiniSerializer(other, context=self.context).data if other else None

    def get_last_message(self, obj):
        msg = obj.messages.order_by("-created_at").first()
        if not msg:
            return None
        if msg.deleted_for_everyone:
            return {"id": msg.id, "content": "This message was deleted",
                    "deleted_for_everyone": True, "created_at": msg.created_at}
        return MessageSerializer(msg, context=self.context).data

    def get_unread_count(self, obj):
        me = self._me()
        return obj.messages.exclude(sender=me).exclude(read_by=me).filter(deleted_for_everyone=False).count()
