from rest_framework import serializers
from .models import CommunityPost, PostComment, PostReaction, CommentReaction


class ReplySerializer(serializers.ModelSerializer):
    author = serializers.SerializerMethodField()
    is_own = serializers.SerializerMethodField()
    reaction_counts = serializers.SerializerMethodField()
    user_reaction = serializers.SerializerMethodField()

    class Meta:
        model = PostComment
        fields = ["id", "content", "author", "is_own",
                  "reaction_counts", "user_reaction", "created_at"]

    def get_author(self, obj):
        request = self.context.get("request")
        avatar = None
        if obj.author.profile_image:
            avatar = request.build_absolute_uri(obj.author.profile_image.url) if request else obj.author.profile_image.url
        return {
            "id": obj.author.id,
            "username": obj.author.username,
            "profile_image": avatar,
            "neighborhood": obj.author.neighborhood or "",
        }

    def get_is_own(self, obj):
        request = self.context.get("request")
        if not request or not request.user.is_authenticated:
            return False
        return obj.author == request.user

    def get_reaction_counts(self, obj):
        return obj.reaction_counts()

    def get_user_reaction(self, obj):
        request = self.context.get("request")
        if not request or not request.user.is_authenticated:
            return None
        r = obj.comment_reactions.filter(user=request.user).first()
        return r.reaction_type if r else None


class PostCommentSerializer(serializers.ModelSerializer):
    author = serializers.SerializerMethodField()
    is_own = serializers.SerializerMethodField()
    reaction_counts = serializers.SerializerMethodField()
    user_reaction = serializers.SerializerMethodField()
    replies = serializers.SerializerMethodField()

    class Meta:
        model = PostComment
        fields = ["id", "content", "author", "is_own",
                  "reaction_counts", "user_reaction",
                  "replies", "created_at"]

    def get_author(self, obj):
        request = self.context.get("request")
        avatar = None
        if obj.author.profile_image:
            avatar = request.build_absolute_uri(obj.author.profile_image.url) if request else obj.author.profile_image.url
        return {
            "id": obj.author.id,
            "username": obj.author.username,
            "profile_image": avatar,
            "neighborhood": obj.author.neighborhood or "",
        }

    def get_is_own(self, obj):
        request = self.context.get("request")
        if not request or not request.user.is_authenticated:
            return False
        return obj.author == request.user

    def get_reaction_counts(self, obj):
        return obj.reaction_counts()

    def get_user_reaction(self, obj):
        request = self.context.get("request")
        if not request or not request.user.is_authenticated:
            return None
        r = obj.comment_reactions.filter(user=request.user).first()
        return r.reaction_type if r else None

    def get_replies(self, obj):
        replies = obj.replies.filter(is_deleted=False).order_by("created_at")
        return ReplySerializer(replies, many=True, context=self.context).data


class CommunityPostSerializer(serializers.ModelSerializer):
    author = serializers.SerializerMethodField()
    reaction_counts = serializers.SerializerMethodField()
    user_reaction = serializers.SerializerMethodField()
    comment_count = serializers.SerializerMethodField()
    is_own = serializers.SerializerMethodField()

    class Meta:
        model = CommunityPost
        fields = [
            "id", "content", "image", "author",
            "reaction_counts", "user_reaction",
            "comment_count", "is_own", "created_at",
        ]
        read_only_fields = ["author", "created_at"]
        extra_kwargs = {
            "content": {"required": False, "allow_blank": True},
            "image":   {"required": False, "allow_null": True},
        }

    def get_author(self, obj):
        request = self.context.get("request")
        avatar = None
        if obj.author.profile_image:
            avatar = request.build_absolute_uri(obj.author.profile_image.url) if request else obj.author.profile_image.url
        return {
            "id": obj.author.id,
            "username": obj.author.username,
            "profile_image": avatar,
            "neighborhood": obj.author.neighborhood or "",
        }

    def get_reaction_counts(self, obj):
        return obj.reaction_counts()

    def get_user_reaction(self, obj):
        request = self.context.get("request")
        if not request or not request.user.is_authenticated:
            return None
        reaction = obj.reactions.filter(user=request.user).first()
        return reaction.reaction_type if reaction else None

    def get_comment_count(self, obj):
        return obj.comments.filter(is_deleted=False, parent=None).count()

    def get_is_own(self, obj):
        request = self.context.get("request")
        if not request or not request.user.is_authenticated:
            return False
        return obj.author == request.user

    def validate(self, data):
        if not data.get("content") and not data.get("image"):
            raise serializers.ValidationError(
                "Post must have either text content or an image."
            )
        return data