from rest_framework import serializers

from django.db.models import Avg
from works.models import Work_Images, Work_Sub_Categories

from accounts.models import ContractorProfile, ContractorWork, Users

class UserProfileSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField()
    email = serializers.CharField()
    mobile = serializers.CharField()
    address = serializers.CharField()
    profile_pic = serializers.ImageField()



class ContractorWorkSerializer(serializers.ModelSerializer):
    class Meta:
        model = ContractorWork
        fields = "__all__"


class ContractorProfileSerializer(serializers.ModelSerializer):

    name = serializers.CharField(source="user.name", read_only=True)
    email = serializers.CharField(source="user.email", read_only=True)
    mobile = serializers.CharField(source="user.mobile", read_only=True)
    profile_pic = serializers.ImageField(source="user.profile_pic", read_only=True)
    address = serializers.CharField(source="user.address", read_only=True)
    sub_categories = serializers.SerializerMethodField()
    works = ContractorWorkSerializer(many=True, read_only=True)

    class Meta:
        model = ContractorProfile
        fields = "__all__"

    def get_sub_categories(self, obj):
        return list(obj.sub_categories.values("id", "name"))
    

class ProfessionalsSerializer(serializers.ModelSerializer):

    bio = serializers.SerializerMethodField()
    hourly_rate = serializers.SerializerMethodField()
    experience_years = serializers.SerializerMethodField()
    location = serializers.SerializerMethodField()
    is_verified = serializers.SerializerMethodField()
    sub_categories = serializers.SerializerMethodField()

    # ⭐ NEW FIELD FROM ANNOTATION
    avg_rating = serializers.FloatField(read_only=True)

    class Meta:
        model = Users
        fields = [
            "id",
            "name",
            "email",
            "mobile",
            "profile_pic",
            "bio",
            "hourly_rate",
            "experience_years",
            "location",
            "is_verified",
            "sub_categories",
            "avg_rating",   # ✅ added
        ]

    # ------------------------
    # PROFILE HELPERS
    # ------------------------

    def get_profile(self, obj):
        return getattr(obj, "contractor_profile", None)

    def get_bio(self, obj):
        profile = self.get_profile(obj)
        return profile.bio if profile else ""

    def get_hourly_rate(self, obj):
        profile = self.get_profile(obj)
        return profile.hourly_rate if profile else 0

    def get_experience_years(self, obj):
        profile = self.get_profile(obj)
        return profile.experience_years if profile else 0

    def get_location(self, obj):
        profile = self.get_profile(obj)
        return profile.location if profile else ""

    def get_is_verified(self, obj):
        profile = self.get_profile(obj)
        return profile.is_verified if profile else False

    def get_sub_categories(self, obj):
        profile = self.get_profile(obj)

        if not profile:
            return []

        return [
            {
                "id": sc.id,
                "name": sc.name
            }
            for sc in profile.sub_categories.all()
        ]
    
# =========================================
# WORK IMAGE SERIALIZER
# =========================================
class WorkImageSerializer(serializers.ModelSerializer):

    class Meta:
        model = Work_Images
        fields = [
            "id",
            "image",
        ]


# =========================================
# REVIEW USER SERIALIZER
# =========================================
class ReviewUserSerializer(serializers.ModelSerializer):

    class Meta:
        model = Users
        fields = [
            "id",
            "name",
            "profile_pic",
        ]


# =========================================
# REVIEW SERIALIZER
# =========================================
class ProfessionalReviewSerializer(serializers.ModelSerializer):

    user = serializers.SerializerMethodField()

    class Meta:
        model = Work_Sub_Categories
        fields = [
            "rating",
            "review",
            "user",
        ]

    def get_user(self, obj):

        if obj.work and obj.work.user:

            return ReviewUserSerializer(
                obj.work.user
            ).data

        return None


# =========================================
# PROFESSIONAL SERIALIZER
# =========================================
class ProfessionalSerializer(serializers.ModelSerializer):

    bio = serializers.SerializerMethodField()
    hourly_rate = serializers.SerializerMethodField()
    experience_years = serializers.SerializerMethodField()
    location = serializers.SerializerMethodField()
    is_verified = serializers.SerializerMethodField()
    sub_categories = serializers.SerializerMethodField()

    avg_rating = serializers.SerializerMethodField()

    total_reviews = serializers.SerializerMethodField()
    reviews = serializers.SerializerMethodField()

    # NEW
    completed_work_images = serializers.SerializerMethodField()

    class Meta:
        model = Users
        fields = [
            "id",
            "name",
            "email",
            "mobile",
            "profile_pic",

            "bio",
            "hourly_rate",
            "experience_years",
            "location",
            "is_verified",
            "sub_categories",

            "avg_rating",

            "total_reviews",
            "reviews",

            # NEW
            "completed_work_images",
        ]

    # =====================================
    # PROFILE
    # =====================================
    def get_profile(self, obj):
        return getattr(obj, "contractor_profile", None)

    def get_bio(self, obj):

        profile = self.get_profile(obj)

        return profile.bio if profile else ""

    def get_hourly_rate(self, obj):

        profile = self.get_profile(obj)

        return profile.hourly_rate if profile else 0

    def get_experience_years(self, obj):

        profile = self.get_profile(obj)

        return profile.experience_years if profile else 0

    def get_location(self, obj):

        profile = self.get_profile(obj)

        return profile.location if profile else ""

    def get_is_verified(self, obj):

        profile = self.get_profile(obj)

        return profile.is_verified if profile else False

    def get_sub_categories(self, obj):

        profile = self.get_profile(obj)

        if not profile:
            return []

        return [
            {
                "id": sc.id,
                "name": sc.name
            }
            for sc in profile.sub_categories.all()
        ]

    # =====================================
    # AVG RATING
    # =====================================
    def get_avg_rating(self, obj):

        qs = Work_Sub_Categories.objects.filter(
            contractor=obj,
            rating__gt=0
        ).aggregate(
            avg=Avg("rating")
        )

        return round(qs["avg"] or 0, 1)

    # =====================================
    # TOTAL REVIEWS
    # =====================================
    def get_total_reviews(self, obj):

        return Work_Sub_Categories.objects.filter(
            contractor=obj,
            rating__gt=0
        ).count()

    # =====================================
    # REVIEWS
    # =====================================
    def get_reviews(self, obj):

        reviews = Work_Sub_Categories.objects.filter(
            contractor=obj,
            rating__gt=0
        ).select_related(
            "work__user"
        ).order_by("-id")

        return ProfessionalReviewSerializer(
            reviews,
            many=True
        ).data

    # =====================================
    # COMPLETED WORK IMAGES
    # =====================================
    def get_completed_work_images(self, obj):

        completed_works = Work_Sub_Categories.objects.filter(
            contractor=obj,
            status=3
        ).select_related("work")

        work_ids = completed_works.values_list(
            "work_id",
            flat=True
        )

        images = Work_Images.objects.filter(
            work_id__in=work_ids
        ).order_by("-id")[:6]

        return WorkImageSerializer(
            images,
            many=True
        ).data