from datetime import timezone
import json
from rest_framework.views import APIView
from rest_framework import status
from rest_framework.response import Response
from accounts.models import Users
from .serializers import  WorkListSerizlizer, WorkSerializer, WorkSubCategorySerializer, WorksSerializer
from utils.helpers import send_contract_notification, verify_token
from .models import  Works, Work_Images, Work_Sub_Categories, Work_Videos
from django.shortcuts import get_object_or_404
from utils.firebase import send_notification


class WorkView(APIView):

    def post(self, request):
        user_id = verify_token(request)
        if user_id == None:
            return Response({'message' : "User not logged in", 'status':status.HTTP_401_UNAUTHORIZED}) 
        else:
            try:
                print(request.POST.get('sub_categories'))
                work = Works()
                work.user_id = user_id
                work.name = request.POST.get('name')
                work.size = request.POST.get('size')
                work.material = request.POST.get('material')
                work.budget = request.POST.get('budget')
                work.description = request.POST.get('description')
                work.save()
                if work.id:
                    if len(request.FILES.getlist('images')):
                        Work_Images.objects.bulk_create([
                            Work_Images(work_id=work.id, image = image) for image in request.FILES.getlist('images')
                        ])

                    if len(request.FILES.getlist('videos')):
                        Work_Videos.objects.bulk_create([
                            Work_Videos(work_id=work.id, video = video) for video in request.FILES.getlist('videos')
                        ])

                    
                    if len(request.POST.getlist('sub_categories')):
                        Work_Sub_Categories.objects.bulk_create([
                            Work_Sub_Categories(work_id=work.id, sub_category_id = sub_category) for sub_category in request.POST.getlist('sub_categories')
                        ])

                        sub_categories = request.POST.getlist('sub_categories')
                        contractors = Users.objects.filter(contractor_profile__sub_categories__in=sub_categories, fcm_token__isnull=False).exclude(fcm_token="").distinct()

                        for contractor in contractors:
                            send_notification(
                                title="New Work Request",
                                message=f"{work.name} has been posted.",
                                token=contractor.fcm_token,
                                data={
                                    "type": "new_work",
                                    "work_id": str(work.id),
                                    "user_id": str(user_id),
                                }
                            )

                return Response({'message' : "Work created successfully.", 'status':status.HTTP_200_OK})
            except Exception as e:
                print(e)
                return Response({'message' : "Something went wrong.", 'status':status.HTTP_500_INTERNAL_SERVER_ERROR})
            

    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_images',
                'work_videos',
                'work_sub_categories',
                'work_sub_categories__work_progress_images',
                'work_sub_categories__work_progress_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 WorksView(APIView):

    def get(self, request):
        user_id = verify_token(request)
        if not user_id:
            return Response({"message": "User not logged in"}, status=401)
        work_cards = Work_Sub_Categories.objects.filter(work__user_id=user_id, status=request.GET.get('status')).select_related("work", "sub_category").prefetch_related("work__work_images", "work__work_videos")
        serializer = WorksSerializer(work_cards, many=True)
        return Response({"works": serializer.data, 'status':status.HTTP_200_OK})
    

class WorkListView(APIView):

    def get(self, request):
        user_id = verify_token(request)
        if not user_id:
            return Response({"message": "User not logged in"}, status=401)
        works = Works.objects.filter(user_id=user_id)
        serializer = WorkListSerizlizer(works, many=True)
        return Response({"works": serializer.data, 'status':status.HTTP_200_OK})
    

class WorkSubcategoriesView(APIView):

    def get(self, request):
        user_id = verify_token(request)
        if not user_id:
            return Response({"message": "User not logged in"}, status=401)
        sub_categories = Work_Sub_Categories.objects.filter(work_id = request.GET.get('work_id'))       
        serializer = WorkSubCategorySerializer(sub_categories, many=True)
        return Response({"sub_categories": serializer.data, 'status':status.HTTP_200_OK})
    

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")

        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 = [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
                .select_related(
                    "work",
                    "work__user",
                    "contractor",
                    "sub_category"
                )
                .get(
                    work_id=work_id,
                    sub_category_id=sub_category_id
                )
            )

        except Work_Sub_Categories.DoesNotExist:

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

        old_status = work_sub_category.status

        work_sub_category.status = int(status_value)
        work_sub_category.save()

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

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

        try:

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

            # ====================================
            # Notify Contractor
            # ====================================

            if work_sub_category.contractor:

                send_contract_notification(
                    user=work_sub_category.contractor,
                    title="Work Status Updated",
                    body=(
                        f"Status of "
                        f"{work_sub_category.work.name} "
                        f"({work_sub_category.sub_category.name}) "
                        f"has been updated to "
                        f"{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
                        )
                    }
                )

        except Exception as notification_error:

            print(
                "Status notification error:",
                notification_error
            )

        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 WorkRatingView(APIView):

    def post(self, request):
        try:
            work_id = request.data.get("work_id")
            sub_category_id = request.data.get("sub_category_id")
            rating = request.data.get("rating")
            review = request.data.get("review", "")

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

            # Get work-sub-category relation
            work_obj = get_object_or_404(
                Work_Sub_Categories,
                work_id=work_id,
                sub_category_id=sub_category_id
            )

            # Validate rating
            if rating is None:
                return Response(
                    {"message": "rating required"},
                    status=status.HTTP_400_BAD_REQUEST
                )

            rating = int(rating)

            if rating < 1 or rating > 5:
                return Response(
                    {"message": "rating must be between 1 and 5"},
                    status=status.HTTP_400_BAD_REQUEST
                )

            # Update fields
            work_obj.rating = rating
            work_obj.review = review
            work_obj.save()

            return Response(
                {
                    "status": status.HTTP_200_OK,
                    "message": "Rating submitted successfully",
                    "rating": work_obj.rating,
                    "review": work_obj.review
                },
                status=status.HTTP_200_OK
            )

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

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