from rest_framework import serializers from apps.courses.api.serializers import ( CategorySerializer, CourseFAQSerializer, CourseHighlightSerializer, LessonReadSerializer, SectionReadSerializer, ) from apps.courses.models import Lesson, LessonStatus from apps.enrollments.models import Enrollment, LessonProgress class EnrolledCourseSummarySerializer(serializers.Serializer): """Used by the my-courses dashboard list. Mirrors the design's MY_COURSES shape.""" id = serializers.IntegerField() slug = serializers.CharField() title = serializers.CharField() tagline = serializers.CharField() color = serializers.CharField() cover_image = serializers.SerializerMethodField() instructor_id = serializers.IntegerField() instructor_name = serializers.SerializerMethodField() enrolled_at = serializers.DateTimeField() completed_at = serializers.DateTimeField(allow_null=True) progress_percent = serializers.IntegerField() completed_lessons = serializers.IntegerField() total_lessons = serializers.IntegerField() last_lesson_id = serializers.IntegerField(allow_null=True) last_lesson_title = serializers.CharField(allow_null=True) next_lesson_id = serializers.IntegerField(allow_null=True) next_lesson_title = serializers.CharField(allow_null=True) def get_cover_image(self, obj): url = obj.get("cover_image_url") request = self.context.get("request") if url and request: return request.build_absolute_uri(url) return url def get_instructor_name(self, obj): return obj.get("instructor_name") class StudentCourseDetailSerializer(serializers.Serializer): """Full course detail for an enrolled student — all published lesson content unlocked.""" id = serializers.IntegerField() slug = serializers.CharField() title = serializers.CharField() tagline = serializers.CharField() description = serializers.CharField() level = serializers.CharField() language = serializers.CharField() color = serializers.CharField() cover_image = serializers.SerializerMethodField() instructor_id = serializers.IntegerField() instructor_name = serializers.CharField() category = CategorySerializer(allow_null=True) highlights = CourseHighlightSerializer(many=True) faqs = CourseFAQSerializer(many=True) sections = serializers.SerializerMethodField() enrollment = serializers.SerializerMethodField() def get_cover_image(self, obj): course = obj["course"] if not course.cover_image: return None request = self.context.get("request") if request: return request.build_absolute_uri(course.cover_image.url) return course.cover_image.url def get_sections(self, obj): course = obj["course"] completed_lesson_ids = obj["completed_lesson_ids"] sections = course.sections.all().prefetch_related( "lessons" ) out = [] for sec in sections: published = [l for l in sec.lessons.all() if l.status == LessonStatus.PUBLISHED] published.sort(key=lambda l: (l.order, l.id)) out.append({ "id": sec.id, "title": sec.title, "order": sec.order, "lessons": LessonReadSerializer( published, many=True ).data, "lessons_completed": [ l.id for l in published if l.id in completed_lesson_ids ], }) return out def get_enrollment(self, obj): e = obj["enrollment"] return { "enrolled_at": e.enrolled_at, "completed_at": e.completed_at, "progress_percent": e.progress_percent(), "completed_lessons": e.completed_lessons_count(), "total_lessons": e.total_lessons_count(), } class EnrollResponseSerializer(serializers.Serializer): enrolled = serializers.BooleanField() course_id = serializers.IntegerField() course_slug = serializers.CharField() enrolled_at = serializers.DateTimeField() class LessonProgressResponseSerializer(serializers.ModelSerializer): progress_percent = serializers.SerializerMethodField() course_completed = serializers.SerializerMethodField() class Meta: model = LessonProgress fields = ["id", "lesson", "completed_at", "progress_percent", "course_completed"] read_only_fields = fields def get_progress_percent(self, obj): return obj.enrollment.progress_percent() def get_course_completed(self, obj): return obj.enrollment.is_completed class InstructorEnrollmentSerializer(serializers.ModelSerializer): """Compact list view for the instructor's CRM-style student panel.""" student_id = serializers.IntegerField(source="student.id", read_only=True) student_name = serializers.CharField(source="student.full_name", read_only=True) student_phone = serializers.CharField(source="student.phone_number", read_only=True) student_last_active_at = serializers.DateTimeField(source="student.last_active_at", read_only=True) progress_percent = serializers.SerializerMethodField() completed_lessons = serializers.SerializerMethodField() total_lessons = serializers.SerializerMethodField() engagement_status = serializers.SerializerMethodField() class Meta: model = Enrollment fields = [ "id", "student_id", "student_name", "student_phone", "student_last_active_at", "course_id", "enrolled_at", "completed_at", "progress_percent", "completed_lessons", "total_lessons", "engagement_status", ] read_only_fields = fields def get_progress_percent(self, obj): return obj.progress_percent() def get_completed_lessons(self, obj): return obj.completed_lessons_count() def get_total_lessons(self, obj): return obj.total_lessons_count() def get_engagement_status(self, obj): return obj.engagement_status()