import json
from rest_framework.views import APIView
from rest_framework import status
from rest_framework.response import Response
from accounts.models import ContractorProfile, Users
from django.db.models import Q, Subquery, OuterRef
from .serializers import WorkSerializer, WorkSubCategorySerializer, WorksSerializer
from utils.helpers import send_contract_notification, verify_token
from .models import Work_Progress_Images, Work_Progress_Videos, Works, Work_Images, Work_Sub_Categories, Work_Videos


class WorkView(APIView):

    def get(self, request):
        user_id = verify_token(request)

        if not user_id:
            return Response(
                {"message": "User not logged in"},
                status=status.HTTP_401_UNAUTHORIZED
            )

        work_id = request.GET.get('work_id')
        sub_category_id = request.GET.get('sub_category_id')

        if not work_id:
            return Response(
                {"message": "work_id is required"},
                status=status.HTTP_400_BAD_REQUEST
            )

        if not sub_category_id:
            return Response(
                {"message": "sub_category_id is required"},
                status=status.HTTP_400_BAD_REQUEST
            )

        try:
            work = Works.objects.prefetch_related(
                'work_sub_categories',
                'work_images',
                'work_videos'
            ).get(
                id=work_id,
                work_sub_categories__sub_category_id=sub_category_id
            )

        except Works.DoesNotExist:
            return Response(
                {"message": "Work not found"},
                status=status.HTTP_404_NOT_FOUND
            )

        serializer = WorkSerializer(work, context={"sub_category_id": int(sub_category_id)})

        return Response(
            {
                "work": serializer.data,
                "status": status.HTTP_200_OK
            },
            status=status.HTTP_200_OK
        )



class UnassignedWorksForContractorView(APIView):

    def get(self, request):
        user_id = verify_token(request)
        if not user_id:
            return Response(
                {"message": "User not logged in"},
                status=401
            )
        try:
            user = Users.objects.get(id=user_id)
            if user.user_type != 3:
                return Response(
                    {"message": "Only contractors allowed"},
                    status=403
                )
            
            print(user)
            profile = ContractorProfile.objects.get(user=user)
            print(profile)
            # ================================
            # STEP 1: contractor skills
            # ================================
            skill_ids = profile.sub_categories.values_list('id', flat=True)
            # ================================
            # STEP 2: FILTER WORK SUB CATEGORIES
            # ================================
            qs = Work_Sub_Categories.objects.filter(

                sub_category_id__in=skill_ids

            ).filter(

                Q(status=0) | Q(contractor__isnull=True)

            ).select_related("work", "sub_category")
            print(qs)
            # ================================
            # STEP 3: SERIALIZE DIRECTLY (NO GROUPING)
            # ================================
            serializer = WorksSerializer(qs, many=True)

            return Response({
                "message": "Unassigned works fetched successfully",
                "count": len(serializer.data),
                "works": serializer.data,
                "status" : status.HTTP_200_OK
            }, status=status.HTTP_200_OK)

        except Users.DoesNotExist:
            return Response({"message": "User not found"}, status=404)

        except ContractorProfile.DoesNotExist:
            return Response({"message": "Contractor profile not found"}, status=404)

        except Exception as e:
            return Response({"message": str(e)}, status=500)


# =========================================================
# CONTRACTOR WORKS VIEW
# =========================================================

class WorksView(APIView):

    def get(self, request):
        user_id = verify_token(request)
        if not user_id:
            return Response({"message": "Contractor not logged in"},status=401)

        try:
            status_value = request.GET.get("status")
            work_cards = Work_Sub_Categories.objects.filter(contractor_id=user_id)

            # OPTIONAL STATUS FILTER
            if status_value is not None:
                work_cards = work_cards.filter(status=status_value)

            work_cards = work_cards.select_related(
                "work",
                "sub_category"
            ).prefetch_related(
                "work__work_images",
                "work__work_videos"
            ).order_by("-id")

            serializer = WorksSerializer(
                work_cards,
                many=True
            )

            return Response(
                {
                    "works": serializer.data,
                    "status": status.HTTP_200_OK
                }
            )

        except Exception as e:

            return Response(
                {
                    "message": str(e)
                },
                status=500
            )



class UpdateWorkStatusView(APIView):

    def post(self, request):

        user_id = verify_token(request)

        if not user_id:

            return Response(
                {
                    "message": "User not logged in"
                },
                status=status.HTTP_401_UNAUTHORIZED
            )

        work_id = request.data.get('work_id')
        sub_category_id = request.data.get('sub_category_id')
        status_value = request.data.get('status')

        # =========================
        # VALIDATIONS
        # =========================
        if not work_id:

            return Response(
                {
                    "message": "work_id is required"
                },
                status=status.HTTP_400_BAD_REQUEST
            )

        if not sub_category_id:

            return Response(
                {
                    "message": "sub_category_id is required"
                },
                status=status.HTTP_400_BAD_REQUEST
            )

        if status_value is None:

            return Response(
                {
                    "message": "status is required"
                },
                status=status.HTTP_400_BAD_REQUEST
            )

        # =========================
        # VALID STATUS
        # =========================
        valid_status = [0, 1, 2, 3, 4]

        if int(status_value) not in valid_status:

            return Response(
                {
                    "message": "Invalid status"
                },
                status=status.HTTP_400_BAD_REQUEST
            )

        try:

            work_sub_category = Work_Sub_Categories.objects.get(
                work_id=work_id,
                sub_category_id=sub_category_id,
                contractor_id=user_id
            )

        except Work_Sub_Categories.DoesNotExist:

            return Response(
                {
                    "message": "Work not found"
                },
                status=status.HTTP_404_NOT_FOUND
            )

        # =========================
        # UPDATE STATUS
        # =========================
        work_sub_category.status = int(status_value)

        work_sub_category.save()

        # =========================
        # SEND NOTIFICATION TO WORK OWNER
        # =========================

        work_owner = work_sub_category.work.user

        contractor_name = (
            work_sub_category.contractor.name
            if work_sub_category.contractor
            else "Contractor"
        )

        status_messages = {
            0: "Pending",
            1: "Assigned",
            2: "Started",
            3: "Completed",
            4: "Canceled"
        }

        current_status = status_messages.get(
            work_sub_category.status,
            "Updated"
        )

        send_contract_notification(
            user=work_owner,
            title="Work Status Updated",
            body=(
                f"{contractor_name} updated "
                f"{work_sub_category.sub_category.name} "
                f"status to {current_status}."
            ),
            notification_type="work",
            reference_id=work_sub_category.work.id,
            data={
                "work_id": str(work_sub_category.work.id),
                "sub_category_id": str(work_sub_category.sub_category.id),
                "status": str(work_sub_category.status)
            }
        )

        return Response(
            {
                "message": "Work status updated successfully",
                "status": status.HTTP_200_OK,
                "work_status":work_sub_category.status,
                "status_label":work_sub_category.get_status_display()
            },
            status=status.HTTP_200_OK
        )
    




class ContractorWorkProgressView(APIView):

    def post(self, request):

        user_id = verify_token(request)

        if not user_id:

            return Response(
                {
                    "message": "User not logged in"
                },
                status=status.HTTP_401_UNAUTHORIZED
            )

        try:

            work_id = request.data.get("work_id")
            sub_category_id = request.data.get("sub_category_id")
            progress = request.data.get("progress", 0)

            # =========================
            # VALIDATION
            # =========================

            if not work_id:

                return Response(
                    {
                        "message": "work_id is required"
                    },
                    status=status.HTTP_400_BAD_REQUEST
                )

            if not sub_category_id:

                return Response(
                    {
                        "message": "sub_category_id is required"
                    },
                    status=status.HTTP_400_BAD_REQUEST
                )

            # =========================
            # GET WORK
            # =========================

            try:

                work = Works.objects.select_related(
                    "user"
                ).get(
                    id=work_id
                )

            except Works.DoesNotExist:

                return Response(
                    {
                        "message": "Work not found"
                    },
                    status=status.HTTP_404_NOT_FOUND
                )

            # =========================
            # GET WORK SUB CATEGORY
            # =========================

            try:

                work_sub_category = (
                    Work_Sub_Categories.objects
                    .select_related(
                        "contractor",
                        "sub_category",
                        "work"
                    )
                    .get(
                        work_id=work_id,
                        sub_category_id=sub_category_id,
                        contractor_id=user_id
                    )
                )

            except Work_Sub_Categories.DoesNotExist:

                return Response(
                    {
                        "message": "Work sub category not found"
                    },
                    status=status.HTTP_404_NOT_FOUND
                )

            # =========================
            # UPDATE PROGRESS
            # =========================

            progress = int(progress)

            if progress > 100:
                progress = 100

            if progress < 0:
                progress = 0

            old_progress = work_sub_category.progress

            work_sub_category.progress = progress

            # Optional auto complete
            # if progress == 100:
            #     work_sub_category.status = 3  # Completed

            work_sub_category.save()

            # =========================
            # SAVE IMAGES
            # =========================

            images = request.FILES.getlist("images")

            for image in images:

                Work_Progress_Images.objects.create(
                    work_sub_category=work_sub_category,
                    image=image
                )

            # =========================
            # SAVE VIDEOS
            # =========================

            videos = request.FILES.getlist("videos")

            for video in videos:

                Work_Progress_Videos.objects.create(
                    work_sub_category=work_sub_category,
                    video=video
                )

            # =========================
            # SEND NOTIFICATION
            # =========================

            try:

                contractor_name = (
                    work_sub_category.contractor.name
                    if work_sub_category.contractor
                    else "Contractor"
                )

                image_count = len(images)
                video_count = len(videos)

                body = (
                    f"{contractor_name} updated work progress "
                    f"to {progress}%."
                )

                if image_count:
                    body += f" Added {image_count} image(s)."

                if video_count:
                    body += f" Added {video_count} video(s)."

                # Progress changed or files uploaded
                if (
                    old_progress != progress
                    or image_count > 0
                    or video_count > 0
                ):

                    send_contract_notification(
                        user=work.user,
                        title="Work Progress Updated",
                        body=body,
                        notification_type="work",
                        reference_id=work.id,
                        data={
                            "work_id": str(work.id),
                            "sub_category_id": str(sub_category_id),
                            "progress": str(progress)
                        }
                    )

                # Special notification when completed
                if progress == 100:

                    send_contract_notification(
                        user=work.user,
                        title="Work Completed",
                        body=(
                            f"{contractor_name} marked "
                            f"the work as completed."
                        ),
                        notification_type="work",
                        reference_id=work.id,
                        data={
                            "work_id": str(work.id),
                            "sub_category_id": str(sub_category_id),
                            "progress": "100",
                            "status": "completed"
                        }
                    )

            except Exception as notification_error:

                print(
                    "Progress notification error:",
                    notification_error
                )

            return Response(
                {
                    "message": "Progress updated successfully",
                    "progress": work_sub_category.progress,
                    "status": status.HTTP_200_OK
                },
                status=status.HTTP_200_OK
            )

        except Exception as e:

            print(e)

            return Response(
                {
                    "message": "Something went wrong",
                    "error": str(e)
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )