from rest_framework import serializers

from accounts.serializers import UserSerializer
from operations.models import (
    Class,
    Course,
    Enrollment,
    Event,
    EventEnrollment,
    Material,
    Payment,
    Topic,
)


class CourseSerializer(serializers.ModelSerializer):
    topics_count = serializers.IntegerField(source="topics.count", read_only=True)

    class Meta:
        model = Course
        fields = ["id", "name", "code", "description", "is_active", "topics_count"]
        read_only_fields = ["id", "topics_count"]


class TopicSerializer(serializers.ModelSerializer):
    course_name = serializers.CharField(source="course.name", read_only=True)
    prerequisites = serializers.PrimaryKeyRelatedField(
        many=True, queryset=Topic.objects.all(), required=False
    )

    class Meta:
        model = Topic
        fields = [
            "id",
            "course",
            "course_name",
            "parent",
            "name",
            "description",
            "order",
            "prerequisites",
        ]


class ClassSerializer(serializers.ModelSerializer):
    course_name = serializers.CharField(source="course.name", read_only=True)
    instructor_name = serializers.CharField(
        source="instructor.get_full_name", read_only=True
    )
    is_paid = serializers.BooleanField(read_only=True)
    active_enrollments = serializers.IntegerField(read_only=True)
    available_slots = serializers.IntegerField(read_only=True)

    class Meta:
        model = Class
        fields = [
            "id",
            "name",
            "course",
            "course_name",
            "instructor",
            "instructor_name",
            "description",
            "schedule",
            "mode",
            "location_or_link",
            "max_capacity",
            "price",
            "is_paid",
            "start_date",
            "end_date",
            "community_link",
            "is_active",
            "active_enrollments",
            "available_slots",
        ]
        read_only_fields = ["id", "is_paid", "active_enrollments", "available_slots"]


class EnrollmentSerializer(serializers.ModelSerializer):
    student_name = serializers.CharField(
        source="student.get_full_name", read_only=True
    )
    class_name = serializers.CharField(source="klass.name", read_only=True)
    course_name = serializers.CharField(source="klass.course.name", read_only=True)
    payment_status = serializers.CharField(source="payment.status", read_only=True)

    class Meta:
        model = Enrollment
        fields = [
            "id",
            "student",
            "student_name",
            "klass",
            "class_name",
            "course_name",
            "status",
            "enrolled_at",
            "payment_status",
        ]
        read_only_fields = ["id", "enrolled_at"]

    def validate(self, attrs):
        klass = attrs.get("klass", getattr(self.instance, "klass", None))
        if klass:
            if klass.max_capacity > 0 and klass.active_enrollments >= klass.max_capacity:
                raise serializers.ValidationError("A turma atingiu a capacidade máxima.")
            if klass.is_paid and attrs.get("status") == Enrollment.Status.ACTIVE:
                raise serializers.ValidationError(
                    "Uma turma paga só fica ativa após pagamento confirmado."
                )
        return attrs


class EventSerializer(serializers.ModelSerializer):
    instructor_name = serializers.CharField(
        source="instructor.get_full_name", read_only=True
    )
    available_slots = serializers.IntegerField(read_only=True)

    class Meta:
        model = Event
        fields = [
            "id",
            "title",
            "description",
            "instructor",
            "instructor_name",
            "date",
            "time",
            "mode",
            "location_or_link",
            "max_capacity",
            "status",
            "requirements",
            "allow_guest_enrollment",
            "available_slots",
        ]
        read_only_fields = ["id"]


class EventEnrollmentSerializer(serializers.ModelSerializer):
    event_title = serializers.CharField(source="event.title", read_only=True)
    user_name = serializers.CharField(source="user.get_full_name", read_only=True)

    class Meta:
        model = EventEnrollment
        fields = [
            "id",
            "event",
            "event_title",
            "user",
            "user_name",
            "guest_name",
            "guest_phone",
            "status",
            "enrolled_at",
        ]
        read_only_fields = ["id", "enrolled_at"]

    def validate(self, attrs):
        event = attrs.get("event", getattr(self.instance, "event", None))
        user = attrs.get("user")
        guest_name = attrs.get("guest_name", "")
        if user is None and not guest_name:
            raise serializers.ValidationError(
                "Forneça o utilizador ou o nome do convidado."
            )
        if event and event.max_capacity > 0:
            if event.active_enrollments >= event.max_capacity:
                raise serializers.ValidationError("O evento atingiu a capacidade máxima.")
        return attrs


class PaymentSerializer(serializers.ModelSerializer):
    student_name = serializers.CharField(
        source="enrollment.student.get_full_name", read_only=True
    )
    class_name = serializers.CharField(source="enrollment.klass.name", read_only=True)

    class Meta:
        model = Payment
        fields = [
            "id",
            "enrollment",
            "student_name",
            "class_name",
            "amount",
            "method",
            "date",
            "reference",
            "status",
            "confirmed_by",
            "created_at",
        ]
        read_only_fields = ["id", "created_at"]


class MaterialSerializer(serializers.ModelSerializer):
    course_name = serializers.CharField(source="course.name", read_only=True)
    topic_name = serializers.CharField(source="topic.name", read_only=True)
    class_name = serializers.CharField(source="klass.name", read_only=True)

    class Meta:
        model = Material
        fields = [
            "id",
            "title",
            "material_type",
            "course",
            "course_name",
            "topic",
            "topic_name",
            "klass",
            "class_name",
            "file",
            "url",
            "description",
            "is_public",
            "created_at",
        ]
        read_only_fields = ["id", "created_at"]
