import json
from django.db.models.query_utils import Q
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from core.models import (
    Course, CourseModule, ModuleContent, ElementContent, VideoContent, AttachmentContent,
    ContentNote, ModuleContentView, UserCourse, Instructor
)
from . serializers import (
    CourseModuleSerializer, ModuleContentSerializer,
    ElementContentSerializer, VideoContentSerializer,
    AttachmentContentSerializer, ContentNoteSerializer
)
from utils import add_course_activity


class CourseModuleList(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        usercourse_id = request.GET.get('usercourse_id', None)
        if request.user.userinformation.role == 'Student':
            if CourseModule.objects.filter(usercourse__user=request.user.id, usercourse_id=usercourse_id).exists():
                course_modules = CourseModule.objects.filter(usercourse_id=usercourse_id, is_active=True)
                serializer = CourseModuleSerializer(course_modules, many=True, context={'user': request.user})
            else:
                return Response({'No Moduls Found'},status=status.HTTP_400_BAD_REQUEST)
        elif request.user.userinformation.role == 'Instructor':
            instructor_id = Instructor.objects.get(user=request.user)
            if CourseModule.objects.filter(usercourse__instructor=instructor_id, usercourse_id=usercourse_id).exists():
                course_modules = CourseModule.objects.filter(usercourse_id=usercourse_id)
                serializer = CourseModuleSerializer(course_modules, many=True, context={'user': request.user})
            else:
                return Response({'No Moduls Found'},status=status.HTTP_400_BAD_REQUEST)
        elif request.user.userinformation.role == 'Admin':
                course_modules = CourseModule.objects.filter(usercourse_id=usercourse_id)
                serializer = CourseModuleSerializer(course_modules, many=True, context={'user': request.user})
        else:
            return Response({'Please Login'},status=status.HTTP_401_UNAUTHORIZED)


        return Response(serializer.data)

    def post(self, request):
        usercourse_id = request.data.get('usercourse_id', None)
        title = request.data.get('title', '')

        if not request.user.userinformation.role in ['Admin', 'AdminInstructor', 'Instructor']:
            return Response(status=status.HTTP_401_UNAUTHORIZED)

        if request.user.userinformation.role == 'Instructor':
            instructor_id = Instructor.objects.get(user=request.user)
            if UserCourse.objects.filter(instructor=instructor_id, id=usercourse_id).exists():
                course_module = CourseModule.objects.create(
                    usercourse_id=usercourse_id,
                    title=title
                )
            else:
                return Response({'You have not been assigned to the section'}, status=status.HTTP_401_UNAUTHORIZED)
        else:
            course_module = CourseModule.objects.create(
                usercourse_id=usercourse_id,
                title=title
            )

        serializer = CourseModuleSerializer(course_module, context={'user': request.user})

        return Response({'message': 'Created Successfully'}, status=status.HTTP_201_CREATED)


class CourseModuleDetails(APIView):
    permission_classes = [IsAuthenticated]

    def delete(self, request):
        id = request.data.get('id', None)

        if not request.user.userinformation.role in ['Admin', 'AdminInstructor', 'Instructor']:
            return Response({'message': 'Unauthorized access'}, status=status.HTTP_401_UNAUTHORIZED)

        if not id:
            return Response({'message': 'Module ID not provided'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            course_module = CourseModule.objects.get(id=id)
            course_module.delete()
            return Response({'message': 'Module Deleted'}, status=status.HTTP_200_OK)
        except CourseModule.DoesNotExist:
            return Response({'message': 'Module not found'}, status=status.HTTP_404_NOT_FOUND)


class ModuleContentList(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        course_module_id = request.data.get('course_module_id', None)

        if not request.user.userinformation.role in ['Admin', 'AdminInstructor', 'Instructor']:
            return Response(status=status.HTTP_401_UNAUTHORIZED)

        module_contents = ModuleContent.objects.filter(course_module_id=course_module_id)
        serializer = ModuleContentSerializer(module_contents, many=True)

        return Response(serializer.data)

    def post(self, request):
        course_module_id = request.data.get('course_module_id', None)
        type = request.data.get('type', '')
        title = request.data.get('title', '')
        file = request.data.get('file', None)

        if not request.user.userinformation.role in ['Admin', 'AdminInstructor', 'Instructor']:
            return Response(status=status.HTTP_401_UNAUTHORIZED)

        try:
            course_module = CourseModule.objects.get(id=course_module_id)
        except CourseModule.DoesNotExist:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        if type == 'Element':
            element_content = ElementContent.objects.create(
                usercourse=course_module.usercourse,
                title=title
            )

            module_content = ModuleContent.objects.create(
                course_module=course_module,
                element_content=element_content,
                type=type,
            )

            serializer = ModuleContentSerializer(module_content)

            return Response({'message': 'Created Successfully'}, status=status.HTTP_201_CREATED)
            
        elif type == 'Video':
            video_content = VideoContent.objects.create(
                usercourse=course_module.usercourse,
                title=title,
                file=file
            )

            module_content = ModuleContent.objects.create(
                course_module=course_module,
                video_content=video_content,
                type=type,
            )

            serializer = ModuleContentSerializer(module_content)

            return Response({'message': 'Created Successfully'}, status=status.HTTP_201_CREATED)

        elif type == 'Attachment':
            attachment_content = AttachmentContent.objects.create(
                usercourse=course_module.usercourse,
                title=title,
                file=file
            )

            module_content = ModuleContent.objects.create(
                course_module=course_module,
                attachment_content=attachment_content,
                type=type,
            )

            serializer = ModuleContentSerializer(module_content)

            return Response({'message': 'Created Successfully'}, status=status.HTTP_201_CREATED)
        else:
            return Response(status=status.HTTP_400_BAD_REQUEST)


class ModuleContentDetails(APIView):
    permission_classes = [IsAuthenticated]

    def delete(self, request):
        id = request.data.get('id', None)

        try:
            module_content = ModuleContent.objects.get(id=id)
            module_content.delete()
        except ModuleContent.DoesNotExist:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        return Response({'message': 'Course Module Content Deleted'},status=status.HTTP_200_OK)


class ElementContentDetails(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        id = request.data.get('id', None)

        if not request.user.userinformation.role in ['Admin', 'AdminInstructor',
                                                     'Instructor']:
            return Response(status=status.HTTP_401_UNAUTHORIZED)

        try:
            element_content = ElementContent.objects.get(id=id)
        except ElementContent.DoesNotExist:
            return Response({"No Data Found"},status=status.HTTP_400_BAD_REQUEST)

        serializer = ElementContentSerializer(element_content)

        return Response(serializer.data)

    def put(self, request):
        id = request.data.get('id', None)
        key = request.data.get('key', None)
        value = request.data.get('value', None)

        if not request.user.userinformation.role in ['Admin', 'AdminInstructor',
                                                     'Instructor']:
            return Response(status=status.HTTP_401_UNAUTHORIZED)

        try:
            element_content = ElementContent.objects.get(id=id)
        except ElementContent.DoesNotExist:
            return Response({"No Data Found"},status=status.HTTP_400_BAD_REQUEST)

        if key == 'title':
            element_content.title = value
        elif key == 'content':
            element_content.content = value
        else:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        element_content.save()

        serializer = ElementContentSerializer(element_content)

        return Response(serializer.data)


class VideoContentDetails(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        id = request.data.get('id', None)

        if not request.user.userinformation.role in ['Admin', 'AdminInstructor',
                                                     'Instructor']:
            return Response(status=status.HTTP_401_UNAUTHORIZED)

        try:
            video_content = VideoContent.objects.get(id=id)
        except VideoContent.DoesNotExist:
            return Response({'No Video Found'},status=status.HTTP_400_BAD_REQUEST)

        serializer = VideoContentSerializer(video_content)

        return Response(serializer.data)


class CurrentModuleContent(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        usercourse_id = request.data.get('usercourse_id', None)
        action = request.data.get('action', '')  # enter, first, next, previous
        module_content_id = request.data.get('module_content_id', None)

        if action == 'Enter':
            first_course_module = CourseModule.objects.filter(usercourse_id=usercourse_id, is_active=True).first()
            first_module_content = first_course_module.module_contents.filter(is_active=True).first()

            course_modules = CourseModule.objects.filter(usercourse_id=usercourse_id, is_active=True)
            for course_module in course_modules:
                for module_content in course_module.module_contents.all():
                    if ModuleContentView.objects.filter(module_content=module_content, user=request.user).exists():
                        module_content_id = module_content.id

            return Response({
                'module_content_id': module_content_id if module_content_id else first_module_content.id
            })
        elif action == 'First':
            try:
                module_content = ModuleContent.objects.get(id=module_content_id)
            except ModuleContent.DoesNotExist:
                return Response(status=status.HTTP_400_BAD_REQUEST)

            first_module_content = module_content.course_module.module_contents.filter(is_active=True).first()

            return Response({
                'module_content_id': first_module_content.id
            })
        elif action == 'Next':
            try:
                module_content = ModuleContent.objects.get(id=module_content_id)
            except ModuleContent.DoesNotExist:
                return Response(status=status.HTTP_400_BAD_REQUEST)

            next_module_content = ModuleContent.objects.filter(
                id__gt=module_content.id,
                course_module_id=module_content.course_module.id,
                is_active=True
            ).first()
            if next_module_content:
                return Response({
                    'module_content_id': next_module_content.id
                })
            else:
                course_module = module_content.course_module
                next_course_module = CourseModule.objects.filter(id__gt=course_module.id, is_active=True).first()
                if next_course_module:
                    next_module_content = next_course_module.module_contents.filter(is_active=True).first()

                    return Response({
                        'module_content_id': next_module_content.id
                    })
                else:
                    return Response({
                        'module_content_id': module_content.id
                    })
        elif action == 'Previous':
            try:
                module_content = ModuleContent.objects.get(id=module_content_id)
            except ModuleContent.DoesNotExist:
                return Response(status=status.HTTP_400_BAD_REQUEST)

            prev_module_content = ModuleContent.objects.filter(
                id__lt=module_content.id,
                course_module_id=module_content.course_module.id,
                is_active=True
            ).last()
            if prev_module_content:
                return Response({
                    'module_content_id': prev_module_content.id
                })
            else:
                course_module = module_content.course_module
                prev_course_module = CourseModule.objects.filter(id__lt=course_module.id, is_active=True).last()
                if prev_course_module:
                    prev_module_content = prev_course_module.module_contents.filter(is_active=True).last()

                    return Response({
                        'module_content_id': prev_module_content.id
                    })
                else:
                    return Response({
                        'module_content_id': module_content.id
                    })


class StudyView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        module_content_id = request.GET.get('module_content_id', None)

        try:
            selected_module_content = ModuleContent.objects.get(id=module_content_id)
        except ModuleContent.DoesNotExist:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        if not ModuleContentView.objects.filter(module_content=selected_module_content, user=request.user).exists():
            ModuleContentView.objects.create(
                module_content=selected_module_content,
                user=request.user
            )

        if selected_module_content.type == 'Element':
            content_serializer = ElementContentSerializer(selected_module_content.element_content)
        elif selected_module_content.type == 'Video':
            content_serializer = VideoContentSerializer(selected_module_content.video_content)
        elif selected_module_content.type == 'Attachment':
            content_serializer = AttachmentContentSerializer(selected_module_content.attachment_content)
        else:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        course_module_serializer = CourseModuleSerializer(selected_module_content.course_module, context={'user': request.user})

        module_contents = selected_module_content.course_module.module_contents.filter(is_active=True)
        module_contents_serializer = ModuleContentSerializer(module_contents, many=True, context={'user': request.user})

        add_course_activity(selected_module_content.course_module.usercourse.course.id, request.user.id, 'content_view')

        return Response({
            'module': course_module_serializer.data,
            'contents': module_contents_serializer.data,
            'content': content_serializer.data
        })


class ContentNoteList(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        module_content_id = request.data.get('module_content_id', None)

        content_notes = ContentNote.objects.filter(
            module_content_id=module_content_id,
            user=request.user
        )
        serializer = ContentNoteSerializer(content_notes, many=True)

        return Response(serializer.data)

    def post(self, request):
        module_content_id = request.data.get('module_content_id', None)
        text = request.data.get('text', None)

        if not text:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        else:
            content_note = ContentNote.objects.create(
                module_content_id=module_content_id,
                user=request.user,
                text=text
            )
            serializer = ContentNoteSerializer(content_note)

            return Response(serializer.data, status=status.HTTP_201_CREATED)


class PublishCourseModule(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        course_module_id = request.data.get('course_module_id', None)
        is_active = request.data.get('is_active', True)

        if not request.user.userinformation.role in ['Admin', 'AdminInstructor',
                                                     'Instructor']:
            return Response(status=status.HTTP_401_UNAUTHORIZED)

        try:
            course_module = CourseModule.objects.get(id=course_module_id)
        except CourseModule.DoesNotExist:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        course_module.is_active = is_active
        course_module.save()

        return Response({'message': 'Course Module Published'},status=status.HTTP_200_OK)


class PublishModuleContent(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        module_content_id = request.data.get('module_content_id', None)
        is_active = request.data.get('is_active', True)

        if not request.user.userinformation.role in ['Admin', 'AdminInstructor',
                                                     'Instructor']:
            return Response(status=status.HTTP_401_UNAUTHORIZED)

        try:
            module_content = ModuleContent.objects.get(id=module_content_id)
        except ModuleContent.DoesNotExist:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        module_content.is_active = is_active
        module_content.save()

        return Response({'message': 'Course Module Content Published'},status=status.HTTP_200_OK)


class PublishAll(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        usercourse_id = request.data.get('usercourse_id')
        is_active = request.data.get('is_active', True)

        if request.user.userinformation.role not in ['Admin', 'AdminInstructor', 'Instructor']:
            return Response({"error": "Permission denied"}, status=status.HTTP_403_FORBIDDEN)

        if not usercourse_id:
            return Response({"error": "section is required"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            user_course = UserCourse.objects.get(id=usercourse_id)
            course_modules = user_course.course_module.all()
        except UserCourse.DoesNotExist:
            return Response({"error": "Section not found"}, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        try:
            for course_module in course_modules:
                course_module.is_active = is_active
                course_module.save()
                if hasattr(course_module, 'module_contents'):
                    for module_content in course_module.module_contents.all():
                        module_content.is_active = is_active
                        module_content.save()
        except Exception as e:
            return Response({"error": "Error updating course modules"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response({"message": "All Course modules and contents published successfully"}, status=status.HTTP_200_OK)


# For student view
class PercentCompletion(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        usercourse_id = request.GET.get('usercourse_id', None)

        content_count = 0
        completion_count = 0

        course_modules = CourseModule.objects.filter(usercourse_id=usercourse_id)
        for course_module in course_modules:
            for module_content in course_module.module_contents.all():
                content_count += 1
                if ModuleContentView.objects.filter(module_content=module_content, user=request.user).exists():
                    completion_count += 1

        if content_count != 0:
            percent_completion = round(completion_count * 100 / content_count)
        else:
            percent_completion = 0

        return Response(percent_completion)
