from rest_framework import serializers
from .models import Post, Comment, CommentLike, CommentDislike, Poll, PollOption, PollVote, Bookmark


class CommentSerializer(serializers.ModelSerializer):
    user_username = serializers.CharField(source="user.username", read_only=True)
    user_id = serializers.IntegerField(source="user.id", read_only=True)
    user = serializers.PrimaryKeyRelatedField(read_only=True)
    post = serializers.PrimaryKeyRelatedField(read_only=True)  # Make post read-only
    
    # Engagement counts
    likes_count = serializers.IntegerField(source="comment_likes.count", read_only=True)
    dislikes_count = serializers.IntegerField(source="comment_dislikes.count", read_only=True)
    
    # Current user's interaction status
    is_liked_by_user = serializers.SerializerMethodField()
    is_disliked_by_user = serializers.SerializerMethodField()
    
    class Meta:
        model = Comment
        fields = [
            "id",
            "user",
            "user_id",
            "user_username",
            "post",
            "text",
            "created_at",
            "updated_at",
            "likes_count",
            "dislikes_count",
            "is_liked_by_user",
            "is_disliked_by_user",
        ]
        read_only_fields = ["created_at", "updated_at", "post", "user"]
    
    def get_is_liked_by_user(self, obj):
        request = self.context.get('request')
        if request and request.user.is_authenticated:
            return CommentLike.objects.filter(user=request.user, comment=obj).exists()
        return False
    
    def get_is_disliked_by_user(self, obj):
        request = self.context.get('request')
        if request and request.user.is_authenticated:
            return CommentDislike.objects.filter(user=request.user, comment=obj).exists()
        return False


class PollOptionSerializer(serializers.ModelSerializer):
    votes_count = serializers.IntegerField(source="votes.count", read_only=True)
    is_voted_by_user = serializers.SerializerMethodField()

    class Meta:
        model = PollOption
        fields = ["id", "text", "order", "votes_count", "is_voted_by_user"]

    def get_is_voted_by_user(self, obj):
        request = self.context.get('request')
        if request and request.user.is_authenticated:
            return PollVote.objects.filter(user=request.user, option=obj).exists()
        return False


class PollSerializer(serializers.ModelSerializer):
    options = PollOptionSerializer(many=True, read_only=True)
    total_votes = serializers.IntegerField(read_only=True)
    user_voted_option = serializers.SerializerMethodField()

    class Meta:
        model = Poll
        fields = ["id", "question", "closes_at", "options", "total_votes", "user_voted_option"]

    def get_user_voted_option(self, obj):
        request = self.context.get('request')
        if request and request.user.is_authenticated:
            vote = PollVote.objects.filter(user=request.user, option__poll=obj).first()
            return vote.option_id if vote else None
        return None


class PostSerializer(serializers.ModelSerializer):
    author_username = serializers.CharField(source="author.username", read_only=True)
    author_id = serializers.IntegerField(source="author.id", read_only=True)
    author_is_verified = serializers.BooleanField(source="author.is_verified", read_only=True)
    
    # Engagement counts
    likes_count = serializers.IntegerField(source="likes.count", read_only=True)
    loves_count = serializers.IntegerField(source="loves.count", read_only=True)
    comments_count = serializers.IntegerField(source="comments.count", read_only=True)
    
    # Current user's interaction status
    is_liked_by_user = serializers.SerializerMethodField()
    is_loved_by_user = serializers.SerializerMethodField()
    
    # Make author read-only
    author = serializers.PrimaryKeyRelatedField(read_only=True)
    
    # Image URL
    image_url = serializers.SerializerMethodField()

    # Poll + bookmark
    poll = serializers.SerializerMethodField()
    is_bookmarked = serializers.SerializerMethodField()

    class Meta:
        model = Post
        fields = [
            "id",
            "author",
            "author_id",
            "author_username",
            "author_is_verified",
            "content",
            "image",
            "image_url",
            "created_at",
            "updated_at",
            "likes_count",
            "loves_count",
            "comments_count",
            "is_liked_by_user",
            "is_loved_by_user",
            "boosted_until",
            "tag",
            "poll",
            "is_bookmarked",
        ]
        read_only_fields = ["created_at", "updated_at", "author", "boosted_until"]
    
    def get_is_liked_by_user(self, obj):
        request = self.context.get('request')
        if request and request.user.is_authenticated:
            from .models import Like
            return Like.objects.filter(user=request.user, post=obj).exists()
        return False
    
    def get_is_loved_by_user(self, obj):
        request = self.context.get('request')
        if request and request.user.is_authenticated:
            from .models import Love
            return Love.objects.filter(user=request.user, post=obj).exists()
        return False
    
    def get_image_url(self, obj):
        if obj.image:
            request = self.context.get('request')
            if request:
                return request.build_absolute_uri(obj.image.url)
            return obj.image.url
        return None

    def get_poll(self, obj):
        poll = getattr(obj, "poll", None)
        if not poll:
            return None
        return PollSerializer(poll, context=self.context).data

    def get_is_bookmarked(self, obj):
        request = self.context.get('request')
        if request and request.user.is_authenticated:
            return Bookmark.objects.filter(user=request.user, post=obj).exists()
        return False


class PostDetailSerializer(PostSerializer):
    """Extended serializer with comments included"""
    comments = CommentSerializer(many=True, read_only=True)
    
    class Meta(PostSerializer.Meta):
        fields = PostSerializer.Meta.fields + ["comments"]