from rest_framework.response import Response
from django.shortcuts import get_list_or_404,get_object_or_404
from rest_framework.views import APIView
from rest_framework import generics,status
from authentication.models import User,Role
from rest_framework_simplejwt.views import TokenObtainPairView
from django.core.mail import EmailMessage
from quotation.models import Order,Order_Item, Technician_Assigned_Order_Item,Order,Technician_Comment,Invoice
# from product.models import Product
from service.models import Service,Service_Request_image,Question,Chat
from rest_framework.exceptions import PermissionDenied, NotFound, ValidationError
from rest_framework_simplejwt.backends import TokenBackend
from django.db.models import Q
from technician.models import Job_Time,CallDetail,Notification,Job_Interval_Time
from django.utils import timezone
from datetime import datetime
from datetime import date
from customer.models import Customer
from rest_framework.permissions import IsAuthenticated
from django.contrib.auth import login
from authentication.models import User
from django.contrib.auth.hashers import make_password
from django.db.models import Q
from django.core.mail import send_mail
from django.conf import settings
from django.db import transaction
from django.http import FileResponse
import random
import string
import json
from customer.models import Customer,Customer_Info
from service.models import Heading,SubHeading,Question,Answer,Parts_Request,ChatImage,Service_Signature,Accepted_Image
from django.core.exceptions import ObjectDoesNotExist
from django.core.mail import EmailMessage
from product.models import Product
from django.shortcuts import render
from django.template.loader import render_to_string
from django.http import HttpResponse
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework.pagination import PageNumberPagination            
from leads.models import Lead,Leadnote,Lead_Quote,LeadAttachmentPhotos,LeadAttachmentFiles
from weasyprint import HTML
from django.template.loader import get_template
from io import BytesIO
from xhtml2pdf import pisa
from technician.firebaseManager import sendPush
from fcm_django.models import FCMDevice
from django.http import JsonResponse
from itertools import zip_longest
from django.db.models import Max, Q
from django.db.models import F, Func

from technician.technician_api.serializers import (
    NoteActionSerializer,
    LeadAttachmentPhotosSerializer,
    LeadAttachmentFilesSerializer,
    LeadQuoteListSerializer,
    UserSerializer,
    LeadNoteCreateSerializer,
    ProductSerializer,
    LeadSerializer,
    TechnicianTokenSerializer,
    ForgotPasswordSerializer,
    PasswordResetSerializer,
    AssignedOrderSerializer,
    AssignedItemSerializer,
    AssignedJobsSerializer,
    JobTimeSerializer,
    JobStartStopSerializer,
    JobsViewTechnicianSerializer,
    TechnicianUpdateInstallationStatusSerializer,
    TechnicianCommentSerializer,
    CallDetailSerializer,
    CallDetailPostSerializer,
    CustomerOrderSerializer,
    CustomerOrderItemSerializer,
    CustomerWarrantyOrderSerializer,
    # CustomerServiceSerializer,
    TechnicianServiceAssignedOrderItemSerializer,
    CustomerServiceOrderSerializer,
    # ServiceSerializer,
    AssignedOrderItemDetailSerializer,
    ServiceRequestImageSerializer,
    NotificationSerializer,
    QuestionSerializer,
    QuestionAnsSerializer,
    AnswerSerializer,
    PartsRequestSerializer,
    ChatSerializer,
    ChatImageSerializer ,
    ServiceSignatureSerializer,
    TechnicianAssignedOrderItemSerializer,
    ActivitySerializer,
    CustomerInvoiceSerializer,
    Accepted_ImageSerializer,
    CustomerAnswerSerializer,
    # JobTimerSerializer,
    JobIntervalTimeSerializer,
#     HeadingSerializer,
#     SubheadingSerializer,
    )

def get_context(serializer):
    context ={
            "status": status.HTTP_200_OK,
            "success": True,
            "response": serializer.data
    }
    return Response(context,status=status.HTTP_200_OK)

def get_exception_context(exception):
    context ={
            "status": status.HTTP_400_BAD_REQUEST,
            "success": False,
            "response": str(exception)
    }
    return Response(context,status=status.HTTP_400_BAD_REQUEST)


class TechnicianMultiRoleLoginAPI(TokenObtainPairView):
    serializer_class = TechnicianTokenSerializer
    def post(self, request, *args, **kwargs):
        data = request.data
        email = data.get('email')
        password = data.get('password')
        fcm_registration_token = data.get('fcm_registration_token',None)
        print(fcm_registration_token)
        device_type = data.get('device_type',None)
        print(device_type)
        if fcm_registration_token is None:
            context = {
                "status":status.HTTP_400_BAD_REQUEST,
                "success":False,
                "erros_status":True,
                "response":"fcm_registration_token field may not be empty!"
            }
            return Response(context,status=status.HTTP_400_BAD_REQUEST)
        if device_type is None:
            context = {
                "status":status.HTTP_400_BAD_REQUEST,
                "success":False,
                "erros_status":True,
                "response":"device_type field may not be empty!"
            }
            return Response(context,status=status.HTTP_400_BAD_REQUEST)
        # if User.objects.filter(email__exact =email,is_active=False):
        #     context = {
        #         "status":status.HTTP_400_BAD_REQUEST,
        #         "success":False,
        #         "erros_status":True,
        #         "response":"'Your account is inactive."
        #     }
        #     return Response(context,status=status.HTTP_400_BAD_REQUEST)
        check_user_email = User.objects.filter(email__exact = email,is_active=True)
        if check_user_email.exists():
            from django.contrib.auth import authenticate
            user = authenticate(email = email, password = password)
            print(user)
            if user is not None:
                if user.role.filter(id__in='3').exists() or user.role.filter(id__in='4').exists()  or user.role.filter(id__in='2').exists():
                    if  user.role.filter(id__in='3'):
                        
                        first_name = user.userinfo.first_name.capitalize()
                        last_name = user.userinfo.last_name.capitalize()
                        username = f"{first_name} {last_name}"
                        is_primary=False
                        role_id=3
                    elif  user.role.filter(id__in='4'):
                        from customer.models import Customer
                        if Customer.objects.filter(email=user.email):
                            customer = Customer.objects.get(email=user.email)
                            if customer.company_name:
                                company_name=customer.company_name.capitalize()
                                is_primary=customer.is_primary

                                username=f"{company_name}"
                            else:
                                first_name = customer.first_name.capitalize()
                                last_name = customer.last_name.capitalize()
                                is_primary=customer.is_primary

                                username = f"{first_name} {last_name}"
                        
                            role_id = 4
                        else:
                            cust = Customer_Info.objects.get(email=user.email)
                            first_name = cust.first_name.capitalize()
                            last_name = cust.last_name.capitalize()
                            is_primary=cust.is_primary
                            username = f"{first_name} {last_name}"
                            
                            # if cust.customer.company_name:
                            #     company_name=customer.company_name.capitalize()
                            #     is_primary=cust.is_primary

                            #     username=f"{company_name}"
                            # else:
                            #     first_name = cust.customer.first_name.capitalize()
                            #     last_name = cust.customer.last_name.capitalize()
                            #     is_primary=cust.is_primary
                            #     username = f"{first_name} {last_name}"
                            role_id = 4
                    else:
                        first_name = user.userinfo.first_name.capitalize()
                        last_name = user.userinfo.last_name.capitalize()
                        username = f"{first_name} {last_name}"
                        is_primary=False
                        role_id=2
                    fcm_device_exists = FCMDevice.objects.filter(user_id=user.id,registration_id=fcm_registration_token)
                    print(fcm_device_exists)
                    print(fcm_device_exists)
                    if fcm_device_exists:
                        print(fcm_registration_token)
                        print("deepak")
                        # print(json.loads(fcm_registration_token))
                        get_fcm_device = FCMDevice.objects.get(user_id=user.id,registration_id=fcm_registration_token)
                        
                        get_fcm_device.registration_id = fcm_registration_token
                        get_fcm_device.type = device_type
                        get_fcm_device.active = True
                        get_fcm_device.save()
                    else:
                        fcm_instance = FCMDevice(
                        registration_id  = fcm_registration_token,
                        type  = device_type,
                        user_id = user.id,
                        # active = True
                        )
                        
                        # print(fcm_instance.__dir__())
                        fcm_instance.save()
                    print('here')
                    token = self.get_serializer().get_token(user)
                    print('token here')
                    print(token)
                    context = {
                        "status": status.HTTP_200_OK,
                        "success": True,
                        "erros_status": False,
                        "response": "Successfully Logged In!",
                        "refresh": str(token),
                        "access": str(token.access_token),
                        "username": username,
                        "useid": user.id,
                        "reset_password": user.reset_password,
                        "email": user.email,
                        "is_primary":is_primary,

                        "role": int(role_id)
                    }
                    return Response(context, status=status.HTTP_200_OK)
                else:
                    context = {
                        "status": status.HTTP_200_OK,
                        "success": False,
                        "erros_status": True,
                        "response": "You are not authorized to access!"
                    }
                    return Response(context, status=status.HTTP_200_OK)
            else:
                context = {
                    "status":status.HTTP_200_OK,
                    "success":False,
                    "erros_status":True,
                    "response":"Incorrect Password!"
                }
                return Response(context,status=status.HTTP_200_OK)
        else:
            context = {
                "status":status.HTTP_200_OK,
                "success":False,
                "erros_status":True,
                "response":"Email Address Does Not Exist."
            }
            return Response(context, status=status.HTTP_200_OK)


            
            
class TechnicianLogoutAPI(APIView):
    def post(self, request, *args, **kwargs):
        try:
            # user=request.data["user_id"]
            data = request.data
            fcm_registration_token = data.get('fcm_registration_token',None)
            fcm_device_exists = FCMDevice.objects.filter(registration_id=fcm_registration_token,active = True)
            if fcm_device_exists:
                # Deactivate the FCM device
                fcm_device = FCMDevice.objects.filter(registration_id=fcm_registration_token,active = True)
                for f in fcm_device:
                    f.active = False
                    f.save()
                context = {
                    "detail": "Successfully logged out.",
                    "status": status.HTTP_200_OK,
                    "success": True,
                    "erros_status": False,
                }
                return Response(context, status=status.HTTP_200_OK)
            else:
                context = {
                    "detail": "Successfully logged out.",
                    "status": status.HTTP_200_OK,
                    "success": True,
                    "erros_status": False,
                }
                return Response(context, status=status.HTTP_200_OK)
        except Exception as exception:
            return get_exception_context(exception)


class AssignedOrderListAPI(APIView):
    authentication_classes = []

    def get(self, request, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            
            queryset = Technician_Assigned_Order_Item.objects.filter(Q(technician=get_logged_in_user, order_item__installation_complete=False) | Q(technician=get_logged_in_user, service__service_completed=False))

            serializer = AssignedOrderSerializer(queryset, many=True)
            return get_context(serializer)
        
        except Exception as exception:
            return get_exception_context(exception)
            
            
      
class AssignedItemListAPI(APIView):
    authentication_classes = []
    def get(self, request,order_id, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token,verify=False)
            get_logged_in_user = valid_data['user_id']
            order= Order.objects.get(id=order_id)
          
            # queryset = Technician_Assigned_Order_Item.objects.filter(Q(order_item__order=order, technician=get_logged_in_user, order_item__installation_complete=False) |Q(order_item__order=order, technician=get_logged_in_user, service__service_completed=False))
            queryset = Technician_Assigned_Order_Item.objects.filter(Q(order_item__order=order, technician=get_logged_in_user) & ~Q(working_status=3))
            
            serializer = AssignedItemSerializer(queryset, many=True)
            return get_context(serializer)
        
        except Exception as exception:
            return get_exception_context(exception)
            


class ForgotPasswordAPIView(APIView):
    authentication_classes = []
    def post(self, request):
        try:
            serializer = ForgotPasswordSerializer(data=request.data)
            if serializer.is_valid():
                email = serializer.validated_data['email']
                user = User.objects.filter(email=email).first()

                if user:
                    # Generate a random password
                    new_password = ''.join(random.choices(string.ascii_letters + string.digits, k=12))

                    # Update the user's password
                    user.password = make_password(new_password)
                    user.reset_password=1
                    user.save()

                    # Compose the password reset email
                    subject = 'New Password'
                    message = f'Your new password is: {new_password}'
                    from_email = settings.FROM_EMAIL
                    recipient_list = [email]

                    # Send the email
                    send_mail(subject, message, from_email, recipient_list)
                    
                    context = {
                    "status":status.HTTP_200_OK,
                    "success":True,
                    'message':'New password sent to your email.'
                    }

                    return Response(context, status=status.HTTP_200_OK)
                else:

                    context={
                        "status":status.HTTP_200_OK,
                        "success":True,
                        'message': 'Email address does not exist.'
                        }

                    return Response(context, status=status.HTTP_200_OK)
            else:
                context = {
                        'status': status.HTTP_400_BAD_REQUEST,
                        'success':False,
                        'response': serializer.errors
                    }
                return Response(context, status=status.HTTP_400_BAD_REQUEST)
        except Exception as exception:
            return get_exception_context(exception)
            
class ResetPasswordAPIView(generics.UpdateAPIView):
    authentication_classes = []
    serializer_class = PasswordResetSerializer
    def update(self, request, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']

            print(get_logged_in_user)

            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            
            new_password = serializer.validated_data['new_password']
            confirm_password = serializer.validated_data['confirm_password']

            if new_password and confirm_password and new_password != confirm_password:
                error_message = "New password and confirm password do not match."
                return Response({"status": 200, "success": False, "response": error_message}, status=status.HTTP_200_OK)
            
            user = User.objects.get(id=get_logged_in_user)
            if user:
                user.set_password(new_password)
                user.reset_password=0
                user.save()

                login(request, user)  
                context = {
                        "status":status.HTTP_200_OK,
                        "success":True,
                        'message': 'Password reset successfully.'
                        }
                return Response(context, status=status.HTTP_200_OK)
            else:
                context={
                        "status":status.HTTP_200_OK,
                        "success":False,
                        'error': 'User not found.'
                        }
                return Response(context, status=status.HTTP_200_OK)
        except Exception as exception:
            return get_exception_context(exception)
            

class CustomPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    max_page_size = 100  
    
    
class AssignedNewJobsListAPI(APIView):
    authentication_classes = []
    pagination_class = CustomPagination
    def get(self, request, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token,verify=False)
            get_logged_in_user = valid_data['user_id']
            queryset = Technician_Assigned_Order_Item.objects.filter(Q(technician=get_logged_in_user) & Q(job_completed=False) & Q(view_by_technician=False)).order_by('installation_date')
            
            page = self.request.GET.get('page', 1)
            
            print("fff",page)
            # Pagination
            paginator = self.pagination_class()
            paginated_queryset = paginator.paginate_queryset(queryset, request)
            
            
            serializer_data = AssignedJobsSerializer(paginated_queryset, many=True)
            next_page = paginator.get_next_link() or ''
            previous_page = paginator.get_previous_link() or ''
            total_pages = paginator.page.paginator.num_pages or ''
            
            serializer = {
                'results': serializer_data.data,  # Use the serialized data here
                'next': next_page,
                'previous': previous_page,
                'total_pages': total_pages,
            }
            
            context ={
            "status": status.HTTP_200_OK,
            "success": True,
            "response": serializer
            }
            return Response(context,status=status.HTTP_200_OK)
                    
            
           
        except Exception as exception:
            return get_exception_context(exception)    
            
            
class AssignedTodayJobsListAPI(APIView):
    authentication_classes = []
    pagination_class = CustomPagination
    def get(self, request, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token,verify=False)
            get_logged_in_user = valid_data['user_id']
            
            today_date = date.today()
            print(today_date)
            queryset = Technician_Assigned_Order_Item.objects.filter(Q(technician=get_logged_in_user) & Q(job_completed=False) & Q(view_by_technician=True) & Q(installation_date=today_date)).order_by('installation_time')
            
            page = self.request.GET.get('page', 1)
            
            print("fff",page)
            # Pagination
            paginator = self.pagination_class()
            paginated_queryset = paginator.paginate_queryset(queryset, request)
            next_page = paginator.get_next_link() or ''
            previous_page = paginator.get_previous_link() or ''
            total_pages = paginator.page.paginator.num_pages or ''
            
            serializer_data = AssignedJobsSerializer(paginated_queryset, many=True)
            serializer = {
                'results': serializer_data.data,  # Use the serialized data here
                'next': next_page,
                'previous': previous_page,
                'total_pages': total_pages,
            }
            
            context ={
            "status": status.HTTP_200_OK,
            "success": True,
            "response": serializer
            }
            return Response(context,status=status.HTTP_200_OK)
           
        
        except Exception as exception:
            return get_exception_context(exception)  
            
# class AssignedAllOtherJobsListAPI(APIView):
#     authentication_classes = []
#     pagination_class = CustomPagination
#     def get(self, request, *args, **kwargs):
#         try:
#             token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
#             valid_data = TokenBackend(algorithm='HS256').decode(token,verify=False)
#             get_logged_in_user = valid_data['user_id']
#             today_date = date.today()
#             queryset = Technician_Assigned_Order_Item.objects.filter(Q(technician=get_logged_in_user) & Q(job_completed=False) & Q(view_by_technician=True)).exclude(installation_date=today_date).order_by('installation_date')
            
#             page = self.request.GET.get('page', 1)
            
#             print("fff",page)
#             # Pagination
#             paginator = self.pagination_class()
#             paginated_queryset = paginator.paginate_queryset(queryset, request)
#             next_page = paginator.get_next_link() or ''
#             previous_page = paginator.get_previous_link() or ''
#             total_pages = paginator.page.paginator.num_pages or ''
            
#             serializer_data = AssignedJobsSerializer(paginated_queryset, many=True)
#             serializer = {
#                 'results': serializer_data.data,  # Use the serialized data here
#                 'next': next_page,
#                 'previous': previous_page,
#                 'total_pages': total_pages,
#             }
            
#             context ={
#             "status": status.HTTP_200_OK,
#             "success": True,
#             "response": serializer
#             }
#             return Response(context,status=status.HTTP_200_OK)
            
#         except Exception as exception:
#             return get_exception_context(exception)  
class AssignedAllServiceJobsListAPI(APIView):
    authentication_classes = []
    pagination_class = CustomPagination
    def get(self, request, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token,verify=False)
            get_logged_in_user = valid_data['user_id']
            today_date = date.today()
            queryset = Technician_Assigned_Order_Item.objects.filter(Q(technician=get_logged_in_user) & Q(job_completed=False) & Q(view_by_technician=True) & Q(job_type=2) ).exclude(installation_date=today_date).order_by('installation_date')
            
            page = self.request.GET.get('page', 1)
            
            print("fff",page)
            # Pagination
            paginator = self.pagination_class()
            paginated_queryset = paginator.paginate_queryset(queryset, request)
            next_page = paginator.get_next_link() or ''
            previous_page = paginator.get_previous_link() or ''
            total_pages = paginator.page.paginator.num_pages or ''
            
            serializer_data = AssignedJobsSerializer(paginated_queryset, many=True)
            serializer = {
                'results': serializer_data.data,  # Use the serialized data here
                'next': next_page,
                'previous': previous_page,
                'total_pages': total_pages,
            }
            
            context ={
            "status": status.HTTP_200_OK,
            "success": True,
            "response": serializer
            }
            return Response(context,status=status.HTTP_200_OK)
            
        except Exception as exception:
            return get_exception_context(exception)  
class AssignedAllInstallJobsListAPI(APIView):
    authentication_classes = []
    pagination_class = CustomPagination
    def get(self, request, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token,verify=False)
            get_logged_in_user = valid_data['user_id']
            today_date = date.today()
            queryset = Technician_Assigned_Order_Item.objects.filter(Q(technician=get_logged_in_user) & Q(job_completed=False) & Q(view_by_technician=True) & Q(job_type=1) ).exclude(installation_date=today_date).order_by('installation_date')
            
            page = self.request.GET.get('page', 1)
            
            print("fff",page)
            # Pagination
            paginator = self.pagination_class()
            paginated_queryset = paginator.paginate_queryset(queryset, request)
            next_page = paginator.get_next_link() or ''
            previous_page = paginator.get_previous_link() or ''
            total_pages = paginator.page.paginator.num_pages or ''
            
            serializer_data = AssignedJobsSerializer(paginated_queryset, many=True)
            serializer = {
                'results': serializer_data.data,  # Use the serialized data here
                'next': next_page,
                'previous': previous_page,
                'total_pages': total_pages,
            }
            
            context ={
            "status": status.HTTP_200_OK,
            "success": True,
            "response": serializer
            }
            return Response(context,status=status.HTTP_200_OK)
            
        except Exception as exception:
            return get_exception_context(exception)  
            
class AssignedCompletedJobsListAPI(APIView):
    authentication_classes = []
    pagination_class = CustomPagination
    def get(self, request, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token,verify=False)
            get_logged_in_user = valid_data['user_id']
            queryset = Technician_Assigned_Order_Item.objects.filter(Q(technician=get_logged_in_user) & Q(job_completed=True)).order_by('-job_complete_datetime')
            
            page = self.request.GET.get('page', 1)
            
            print("fff",page)
            # Pagination
            paginator = self.pagination_class()
            paginated_queryset = paginator.paginate_queryset(queryset, request)
            
            
            serializer_data = AssignedJobsSerializer(paginated_queryset, many=True)
            next_page = paginator.get_next_link() or ''
            previous_page = paginator.get_previous_link() or ''
            total_pages = paginator.page.paginator.num_pages or ''
            
            serializer = {
                'results': serializer_data.data,  # Use the serialized data here
                'next': next_page,
                'previous': previous_page,
                'total_pages': total_pages,
            }
            
            context ={
            "status": status.HTTP_200_OK,
            "success": True,
            "response": serializer
            }
            return Response(context,status=status.HTTP_200_OK)
                    
            
           
        except Exception as exception:
            return get_exception_context(exception)                
   
    

class AssignedJobsListAPI(APIView):
    authentication_classes = []

    def post(self, request, job_id, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = User.objects.get(id=valid_data['user_id'])  # Ensure you get a User instance

            
         
            assigned_orderitem = Technician_Assigned_Order_Item.objects.get(
                id=job_id,
                technician=get_logged_in_user,
            )
            order_item=Order_Item.objects.get(id=assigned_orderitem.order_item.id)

         
            serializer = TechnicianCommentSerializer(data=request.data)

            if serializer.is_valid():
                installation_date = serializer.validated_data.get('installation_date')
                installation_time = serializer.validated_data.get('installation_time')
                comment = serializer.validated_data.get('comment')

                if installation_date and comment:
                    # Use serializer.save() to create the Technician_Comment instance
                    serializer.save(
                        technician_assigend_order_item=assigned_orderitem,
                        installation_date=installation_date,
                        installation_time=installation_time,
                        comment=comment
                    )

                    # Update the assigned_orderitem installation_date
                    assigned_orderitem.installation_date = installation_date
                    assigned_orderitem.installation_time = installation_time
                    # assigned_orderitem.working_status = 1  #Accepted Installation
                    
                    # assigned_orderitem.job_status=0
                    assigned_orderitem.save()
                    
                    
                    # order_item.status=5
                    # order_item.save()
                    
                    try:
                        get_registration_token = FCMDevice.objects.filter(user_id=assigned_orderitem.order_item.order.invoice.customer.user.id, active=True)
                        for i in get_registration_token:
                            sendPush('Job Reschedule Notification',f'EXCITECH Australia-Job Reschedule For Job Id-{assigned_orderitem.id}',[i.registration_id])     
                    except FCMDevice.DoesNotExist:
                        print("FCMDevice not found for the specified conditions. Push notification not sent.")
                    except Exception as e:
                        print(f"Error sending push notification: {e}")
                
                    
                    
                    
                    
                    context = {
                        'status': status.HTTP_201_CREATED,
                        'success': True,
                        'response': 'Installation date and comment Update successfully.',
                    }
                    return Response(context, status=status.HTTP_201_CREATED)
            else:
                context = {
                    'status': status.HTTP_400_BAD_REQUEST,
                    'success': False,
                    'response': serializer.errors
                }
                return Response(context, status=status.HTTP_400_BAD_REQUEST)        
            

        except Exception as exception:
            return get_exception_context(exception)
            
            
            
class JobsViewByTechnicianAPIView(APIView):
    authentication_classes = []
    def put(self, request, job_id):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
         
            assigned_order_item=Technician_Assigned_Order_Item.objects.get(id=job_id,technician=get_logged_in_user)
            order_item = Order_Item.objects.get(id=assigned_order_item.order_item.id)
            serializer = JobsViewTechnicianSerializer(assigned_order_item, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                order_item.view_by_technician=serializer.validated_data['view_by_technician']
                # assigned_order_item.working_status=
                order_item.save()
                if assigned_order_item.job_type == 1:
                    assigned_order_item.working_status = 1  #Accepted Installation
                if assigned_order_item.job_type == 2:
                    assigned_order_item.working_status = 5   #Accepted Service 
                assigned_order_item.save()
                
                context = {
                    'status': status.HTTP_200_OK,
                    'success': True,
                    'response':serializer.data,
                }
                return Response(context, status=status.HTTP_200_OK)
            else:
                context = {
                    'status': status.HTTP_400_BAD_REQUEST,
                    'success': False,
                    'response': serializer.errors
                }
                return Response(context, status=status.HTTP_400_BAD_REQUEST)
        except Exception as exception:
            return get_exception_context(exception)   
                        
 

class JobStartStopAPIView(APIView):

    authentication_classes = []
    def post(self, request, job_id):
        # try:
        token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
        valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
        get_logged_in_user = valid_data['user_id']
        assigned_order_item=Technician_Assigned_Order_Item.objects.get(id=job_id,technician=get_logged_in_user)
        order_item = Order_Item.objects.get(id=assigned_order_item.order_item.id)
        
        
        serializer = JobStartStopSerializer(data=request.data)
        if serializer.is_valid():
            action = serializer.validated_data['action']
            if action == 'start':
                # Check if start_time is set for the given job_id
                existing_job = Job_Time.objects.filter(
                    assigned_order_item=job_id,
                    start_time__isnull=False,
                    stop_time__isnull=True
                ).first()
                
                
                existing_job1 = Job_Time.objects.filter(
                    assigned_order_item=job_id,
                    
                ).first()

                if existing_job:
                    # Stop the existing job
                    existing_job.stop_time = timezone.now()
                    existing_job.save()
    
                    new_job = Job_Time.objects.create(
                        start_time=timezone.now(),
                        assigned_order_item_id=job_id
                    )
                    
                    print("gopal chandrawanshi")
                    
                    
                    assigned_order_item.job_status=1
                    
                    if assigned_order_item.job_type == 1:
                        assigned_order_item.working_status=2
                    if assigned_order_item.job_type == 2:
                        assigned_order_item.working_status=6
                    
                    
                    
                    assigned_order_item.save()
                    order_item.status=6  
                    order_item.save()
                    message="Job Start successfully."

                    
                    try:
                        get_registration_token = FCMDevice.objects.filter(user_id=assigned_order_item.order_item.order.invoice.customer.user.id, active=True)
                        for i in get_registration_token:
                            sendPush('Job Start Notification',f'EXCITECH Australia-Job Started For Job Id-{assigned_order_item.id}',[i.registration_id])     
                    except FCMDevice.DoesNotExist:
                        print("FCMDevice not found for the specified conditions. Push notification not sent.")
                    except Exception as e:
                        print(f"Error sending push notification: {e}")
                    context = {
                        'status': status.HTTP_200_OK,
                        'success': True,
                        'response': message,
                    }
                    return Response(context, status=status.HTTP_200_OK)
                    
                elif existing_job1:
                    new_job = Job_Time.objects.create(
                        start_time=timezone.now(),
                        assigned_order_item_id=job_id
                    )
                    
                    print("deepak chandrawanshi",order_item.status)
                    # assigned_order_item.job_status=1
                    if order_item.status == '3':
                       
                        assigned_order_item.job_status=1
                        if assigned_order_item.job_type==1:
                            assigned_order_item.working_status=2
                        if assigned_order_item.job_type==2:
                            assigned_order_item.working_status=6
                        
                        assigned_order_item.save()
                        order_item.status=6  
                        order_item.save()
                    message="Job Start successfully."
                    

                    try:
                        get_registration_token = FCMDevice.objects.filter(user_id=assigned_order_item.order_item.order.invoice.customer.user.id, active=True)
                        for i in get_registration_token:
                            sendPush('Job Start Notification',f'EXCITECH Australia-Job Started For Job Id-{assigned_order_item.id}',[i.registration_id])     
                    except FCMDevice.DoesNotExist:
                        print("FCMDevice not found for the specified conditions. Push notification not sent.")
                    except Exception as e:
                        print(f"Error sending push notification: {e}")
                

                    context = {
                        'status': status.HTTP_200_OK,
                        'success': True,
                        'response': message,
                    }
                    return Response(context, status=status.HTTP_200_OK)
                    
                    
    
                # If there is no existing job in progress, start a new job
                else:
                    new_job = Job_Time.objects.create(
                        start_time=timezone.now(),
                        assigned_order_item_id=job_id
                    )
                    
                    assigned_order_item.job_status=1
                    if assigned_order_item.job_type==1:
                        assigned_order_item.working_status=2
                    if assigned_order_item.job_type==2:
                        assigned_order_item.working_status=6
                    
                    assigned_order_item.save()
                    
                    order_item.status=6     #  in Progress
                    order_item.save()
                    message="New job started successfully."
                    

                    try:
                        get_registration_token = FCMDevice.objects.filter(user_id=assigned_order_item.order_item.order.invoice.customer.user.id, active=True)
                        for i in get_registration_token:
                            sendPush('Job Start Notification',f'EXCITECH Australia-Job Started For Job Id-{assigned_order_item.id}',[i.registration_id])     
                    except FCMDevice.DoesNotExist:
                        print("FCMDevice not found for the specified conditions. Push notification not sent.")
                    except Exception as e:
                        print(f"Error sending push notification: {e}")
                    
                    
                    context = {
                        'status': status.HTTP_201_CREATED,
                        'success': True,
                        'response': message,
                    }
                    return Response(context, status=status.HTTP_201_CREATED)

        else:
            context = {
                'status': status.HTTP_400_BAD_REQUEST,
                'success': False,
                'response': serializer.errors
            }
            return Response(context, status=status.HTTP_400_BAD_REQUEST)        

class TechnicianUpdateInstallationStatusAPIView(APIView):
    authentication_classes = []
    def put(self, request, order_item_id):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']

            order_item = Order_Item.objects.get(id=order_item_id)
            
            if not order_item:
                context = {
                            "status": status.HTTP_200_OK,
                            "success": False,
                            'message': 'No items found..'
                        }
                return Response(context, status=status.HTTP_200_OK)

          
            serializer = TechnicianUpdateInstallationStatusSerializer(order_item, data=request.data, partial=True)
            
            if serializer.is_valid():
                
                serializer.save()
                order_item.status=7
                order_item.save()

                context = {
                    'status': status.HTTP_200_OK,
                    'success': True,
                    'response': 'Items Installed Successfully .',
                }
                return Response(context, status=status.HTTP_200_OK)
                
            else:
                context = {
                    'status': status.HTTP_400_BAD_REQUEST,
                    'success': False,
                    'response': serializer.errors
                }
                return Response(context, status=status.HTTP_400_BAD_REQUEST)

        except Order_Item.DoesNotExist:
            return Response({'status': status.HTTP_200_OK, 'detail': 'Order item not found.'}, status=status.HTTP_200_OK)
        except PermissionDenied as e:
            return Response({'status': status.HTTP_403_FORBIDDEN, 'detail': str(e)}, status=status.HTTP_403_FORBIDDEN)
        except Exception as exception:
            return get_exception_context(exception) 
            
class NotificationListAPIView(APIView):
    authentication_classes = []

    def get(self, request, *args, **kwargs):

        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            notifications = Notification.objects.filter(technician=get_logged_in_user,viewed=False)
            serializer = NotificationSerializer(notifications, many=True)
            return get_context(serializer)
        
        except Order_Item.DoesNotExist:
            return Response({'status': status.HTTP_200_OK, 'detail': 'Order item not found.'}, status=status.HTTP_200_OK)
        except PermissionDenied as e:
            return Response({'status': status.HTTP_403_FORBIDDEN, 'detail': str(e)}, status=status.HTTP_403_FORBIDDEN)
        except Exception as exception:
            return get_exception_context(exception) 

    def put(self, request, id ):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            notification = Notification.objects.get(id=id, technician=get_logged_in_user)
            notification.viewed = True
            notification.save()
            serializer = NotificationSerializer(notification)
            return get_context(serializer)
        except Notification.DoesNotExist:
            return Response({'error': 'Notification not found'}, status=200)
        except Exception as exception:
            return get_exception_context(exception) 

class NotificationListAPIView(APIView):
    authentication_classes = []

    def get(self, request, *args, **kwargs):

        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            notifications = Notification.objects.filter(technician=get_logged_in_user,viewed=False)
            serializer = NotificationSerializer(notifications, many=True)
            return get_context(serializer)
        
        except Order_Item.DoesNotExist:
            return Response({'status': status.HTTP_200_OK, 'detail': 'Order item not found.'}, status=status.HTTP_200_OK)
        except PermissionDenied as e:
            return Response({'status': status.HTTP_403_FORBIDDEN, 'detail': str(e)}, status=status.HTTP_403_FORBIDDEN)
        except Exception as exception:
            return get_exception_context(exception) 

    def put(self, request, id ):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            notification = Notification.objects.get(id=id, technician=get_logged_in_user)
            notification.viewed = True
            notification.save()
            serializer = NotificationSerializer(notification)
            return get_context(serializer)
        except Notification.DoesNotExist:
            return Response({'error': 'Notification not found'}, status=404)
        except Exception as exception:
            return get_exception_context(exception) 
   
        
class CustomerOrderListAPI(APIView):
    authentication_classes = []
    pagination_class = CustomPagination
    def get(self, request, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            # customer=Customer.objects.get(id=get_logged_in_user)
            user=User.objects.get(id=get_logged_in_user)
            if  user.isprimary == 1:
                queryset = Order.objects.filter(invoice__customer__user__id = get_logged_in_user )
                print('primary customer')
                print(queryset)
            else:
                # additional contact
                cust_info=Customer_Info.objects.get(user__id = get_logged_in_user)
                if cust_info:
                    print('if not primary customer')
                    queryset = Order.objects.filter(invoice__customer__user__id = cust_info.customer.user.id)
                else:
                    queryset = []
                    print('else not primary customer')
                print(queryset)
        
            paginator = self.pagination_class()
            paginated_queryset = paginator.paginate_queryset(queryset, request)
            next_page = paginator.get_next_link() or ''
            previous_page = paginator.get_previous_link() or ''
            total_pages = paginator.page.paginator.num_pages or ''
            
            serializer_data = CustomerOrderSerializer(paginated_queryset, many=True)
            serializer = {
                'results': serializer_data.data,  # Use the serialized data here
                'next': next_page,
                'previous': previous_page,
                'total_pages': total_pages,
            }
            
            context ={
            "status": status.HTTP_200_OK,
            "success": True,
            "response": serializer
            }
            return Response(context,status=status.HTTP_200_OK)

        except Exception as exception:
            return get_exception_context(exception)
            
class CustomerOrderItemListAPI(APIView):
    authentication_classes = []
    pagination_class = CustomPagination
    def get(self, request,order_id, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token,verify=False)
            get_logged_in_user = valid_data['user_id']
            print(get_logged_in_user)
           
            
            
            user=User.objects.get(id=get_logged_in_user)
            if  user.isprimary == 1:
                queryset = Order_Item.objects.filter(order=order_id,order__invoice__customer__user__id = get_logged_in_user)
            else:
                cust_info=Customer_Info.objects.get(user__id = get_logged_in_user)
                queryset = Order_Item.objects.filter(order=order_id,order__invoice__customer__user__id = cust_info.customer.user.id)
              
            
            paginator = self.pagination_class()
            paginated_queryset = paginator.paginate_queryset(queryset, request)
            next_page = paginator.get_next_link() or ''
            previous_page = paginator.get_previous_link() or ''
            total_pages = paginator.page.paginator.num_pages or ''
            
            serializer_data = CustomerOrderItemSerializer(paginated_queryset, many=True)
            serializer = {
                'results': serializer_data.data,  # Use the serialized data here
                'next': next_page,
                'previous': previous_page,
                'total_pages': total_pages,
            }
            
            context ={
            "status": status.HTTP_200_OK,
            "success": True,
            "response": serializer
            }
            return Response(context,status=status.HTTP_200_OK)
            
        
        except Exception as exception:
            return get_exception_context(exception)           
         

class CustomerWarrantyOrderListAPI(APIView):
    authentication_classes = []
    def get(self, request, *args, **kwargs):
        
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token,verify=False)
            get_logged_in_user = valid_data['user_id']
            today = timezone.now().date()
            queryset = Order_Item.objects.filter(
              order__invoice__customer__user__id = get_logged_in_user,warranty_end_date__gte=today
                
            )
            serializer = CustomerWarrantyOrderSerializer(queryset, many=True)
            return get_context(serializer)
        except Exception as exception:
            return get_exception_context(exception) 


class CustomerServiceOrderListAPI(APIView):
    authentication_classes = []
    pagination_class = CustomPagination
    def get(self, request, *args, **kwargs):
        
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token,verify=False)
            get_logged_in_user = valid_data['user_id']
            today = timezone.now().date()
            # queryset = Order_Item.objects.filter(
            #   order__invoice__customer__user__id = get_logged_in_user #warranty_end_date__lt=today
            # )
            u=User.objects.filter(id=get_logged_in_user).first()
            if u.isprimary != 1:
                cust=Customer_Info.objects.filter(user_id=u.id).first()
                queryset = Technician_Assigned_Order_Item.objects.filter(order_item__order__invoice__customer=cust.customer.id,job_type=2)
            else:    
                queryset = Technician_Assigned_Order_Item.objects.filter(order_item__order__invoice__customer__user__id=get_logged_in_user,job_type=2)
            paginator = self.pagination_class()
            paginated_queryset = paginator.paginate_queryset(queryset, request)
            next_page = paginator.get_next_link() or ''
            previous_page = paginator.get_previous_link() or ''
            total_pages = paginator.page.paginator.num_pages or ''
            
            serializer_data = AssignedOrderItemDetailSerializer(paginated_queryset, many=True)
            # TechnicianAssignedOrderItemSerializer(paginated_queryset, many=True)
            #TechnicianServiceAssignedOrderItemSerializer(paginated_queryset, many=True)#
            serializer = {
                'results': serializer_data.data,  # Use the serialized data here
                'next': next_page,
                'previous': previous_page,
                'total_pages': total_pages,
            }
            
            context ={
            "status": status.HTTP_200_OK,
            "success": True,
            "response": serializer
            }
            return Response(context,status=status.HTTP_200_OK)
            # serializer = CustomerServiceOrderSerializer(queryset, many=True)
            # return get_context(serializer)
        except Exception as exception:
            return get_exception_context(exception) 
# class CustomerServiceOrderListAPI(APIView):
#     authentication_classes = []
#     pagination_class = CustomPagination
#     def get(self, request, *args, **kwargs):
        
#         try:
#             token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
#             valid_data = TokenBackend(algorithm='HS256').decode(token,verify=False)
#             get_logged_in_user = valid_data['user_id']
#             today = timezone.now().date()
#             queryset = Order_Item.objects.filter(
#               order__invoice__customer__user__id = get_logged_in_user #warranty_end_date__lt=today
                
#             )
#             paginator = self.pagination_class()
#             paginated_queryset = paginator.paginate_queryset(queryset, request)
#             next_page = paginator.get_next_link() or ''
#             previous_page = paginator.get_previous_link() or ''
#             total_pages = paginator.page.paginator.num_pages or ''
            
#             serializer_data = CustomerServiceOrderSerializer(paginated_queryset, many=True)
#             serializer = {
#                 'results': serializer_data.data,  # Use the serialized data here
#                 'next': next_page,
#                 'previous': previous_page,
#                 'total_pages': total_pages,
#             }
            
#             context ={
#             "status": status.HTTP_200_OK,
#             "success": True,
#             "response": serializer
#             }
#             return Response(context,status=status.HTTP_200_OK)
            
            
            
#             # serializer = CustomerServiceOrderSerializer(queryset, many=True)
#             # return get_context(serializer)
#         except Exception as exception:
#             return get_exception_context(exception) 


class ServiceRequestAPIView(APIView):
    authentication_classes = []

    def post(self, request, order_item_id, *args, **kwargs):
        
        token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
        valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
        get_logged_in_user = valid_data['user_id']
         
        order_item = Order_Item.objects.get(id=order_item_id)
       
       
        assigned_order_item=Technician_Assigned_Order_Item.objects.filter(order_item=order_item).first()
       
        title = request.data.get('title')
        is_selected_warranty = request.data.get('is_selected_warranty')
        description= request.data.get('description')
        # comment = request.data.get('comment')
        service_request_images = request.FILES.getlist('service_request_images')
        service_request_videos = request.FILES.getlist('service_request_videos')
        # service_request_date = request.data.get('service_request_date')
        # service_request_time = request.data.get('service_request_time')
        service_request_date=datetime.now().date()
        service_request_time=datetime.now().time()
         
        if not title:
            context = {
                "status": status.HTTP_200_OK,
                "success": False,
                'message': 'No title provided.'
            }
            return Response(context, status=status.HTTP_200_OK)
        if not is_selected_warranty:
            context = {
                "status": status.HTTP_200_OK,
                "success": False,
                'message': 'Please provide is it in warranty or in service.'
            }
            return Response(context, status=status.HTTP_200_OK)
            
            
            
        if not description:
            context = {
                "status": status.HTTP_200_OK,
                "success": False,
                'message': 'No description provided.'
            }
            return Response(context, status=status.HTTP_200_OK)
            
    

        # if not service_request_images:
        #     context = {
        #         "status": status.HTTP_200_OK,
        #         "success": False,
        #         'message': 'No service request images provided.'
        #     }
        #     return Response(context, status=status.HTTP_200_OK)

        service = Service.objects.create(order_item=order_item,title=title,description=description,is_selected_warranty=is_selected_warranty)
        
        order_item.status=8
        order_item.service_type = 2
        order_item.save()
        assignment=Technician_Assigned_Order_Item.objects.create(
                order_item=order_item,
                technician=assigned_order_item.technician,
                service_request_date=service_request_date,
                service_request_time=service_request_time,
                service=service,
                job_type=2
      
                
                )
        assignment.working_status= 4  #Request Service
        assignment.save()
        subject = f'EXCITECH Australia-Job Assigned Notification (Service)-{assignment.id}'
        # formatted_date = assignment.installation_date.strftime('%d-%m-%Y')
        # formatted_time = assignment.installation_time.strftime('%I:%M %p') 
        
        
        template_data = {'assignment': assignment}
        message = render_to_string('pages/quotation/job_assigned_email_temp.html', template_data)
        

        from_email = settings.FROM_EMAIL # Replace with your email
        recipient_email = assignment.technician.email
        email = EmailMessage(subject, message, from_email, [recipient_email])
        email.content_subtype = 'html'
        email.send()
        try:
            get_registration_token = FCMDevice.objects.filter(user_id=assignment.technician.id,active=True)
            for i in get_registration_token:
                print('notification send')
                sendPush('Job Assigned Notification (Service)',f'EXCITECH Australia-Job Assigned Notification (Service)-{assignment.id}',[i.registration_id])     
        except FCMDevice.DoesNotExist:
            
            print("FCMDevice not found for the specified conditions. Push notification not sent.")
        except Exception as e:
            print(f"Error sending push notification: {e}")
                
        print(service_request_images)

        for image_data, video_data in zip_longest(service_request_images, service_request_videos, fillvalue=None):
            
      
            data = {'service_request_image': image_data,
            'service_request_video':video_data
            }
            

            serializer = ServiceRequestImageSerializer(data=data)

            if serializer.is_valid():
                serializer.save(service=service)
                
                
            else:
               return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

      
        context = {
            "status": status.HTTP_201_CREATED,
            "success": True,
            'message': 'Customer service request successfully.'
        }
        return Response(context, status=status.HTTP_201_CREATED)



class CallDetailCreateView(APIView):
    authentication_classes = []

    def post(self, request, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            user = User.objects.get(id=get_logged_in_user)
            job_id = request.data.get('job_id')
            phone=request.data.get('phone')
            if not job_id:
                context = {
                    "status": status.HTTP_200_OK,
                    "success": False,
                    'message': 'Job id is required.'
                }
                return Response(context, status=status.HTTP_200_OK)
            if not phone:
                context = {
                    "status": status.HTTP_200_OK,
                    "success": False,
                    'message': 'Phone number is required.'
                }
                return Response(context, status=status.HTTP_200_OK)
        
            # if user.get_role == '3':
            if '3' in user.get_role:
                assigned_order_item = Technician_Assigned_Order_Item.objects.get(id=job_id, technician=user)
                call_details = CallDetail.objects.filter(assigned_order_item=assigned_order_item)
                caller_type=1
            elif user.get_role == '4':
                if Customer.objects.filter(email=user.email,is_primary=True):
                    customer = Customer.objects.get(email=user.email)
                    assigned_order_item = Technician_Assigned_Order_Item.objects.get(id=job_id, order_item__order__invoice__customer=customer)
                    call_details = CallDetail.objects.filter(assigned_order_item=assigned_order_item)
                    caller_type=2
                else:
                    cust = Customer_Info.objects.get(email=user.email)
                    assigned_order_item = Technician_Assigned_Order_Item.objects.get(id=job_id, order_item__order__invoice__customer__id=cust.customer.id)
                    call_details = CallDetail.objects.filter(assigned_order_item=assigned_order_item)
                    caller_type=2 

            else:
                return Response({'error': 'Invalid sender'}, status=200)
            call_details = request.data.get('call_details', [])
            print(call_details)
            if not call_details:
                context = {
                    "status": status.HTTP_200_OK,
                    "success": False,
                    'message': 'No call details provided.'
                }
                return Response(context, status=status.HTTP_200_OK)
            call_details = json.loads(call_details)
            created_call_details = []
            result=False
            
            for call_detail_data in call_details:
                call_time_str=call_detail_data.get('call_time')
                call_time = datetime.strptime(call_time_str, "%b %d, %Y %I:%M %p")
                print(caller_type)
                call_data = {
                            'assigned_order_item': assigned_order_item.id,
                            'call_time':call_time ,
                            'phone':phone ,
                            'call_duration': call_detail_data.get('call_duration'),
                            'caller_type':caller_type
                        }
                try:
                           
                    call_data_instance= CallDetail.objects.get(
                        assigned_order_item=assigned_order_item.id,
                        call_time=call_data.get('call_time'),
                        phone=phone,
                        caller_type=caller_type
                    )
                    serializer = CallDetailPostSerializer(call_data_instance, data=call_data, partial=True)
                    if serializer.is_valid():
                        serializer.save()
                        created_call_details.append(serializer.data)
                        context = {
                            "status": status.HTTP_200_OK,
                            "success": True,
                            'message': 'Call details created successfully.',
                            
                            }
                        result=True
                        
                except CallDetail.DoesNotExist:
                    # If the object doesn't exist, create a new one
                    serializer = CallDetailPostSerializer(data=call_data)
                    if serializer.is_valid():
                        serializer.save()
                        created_call_details.append(serializer.data)
                        
                        context = {
                            "status": status.HTTP_200_OK,
                            "success": True,
                            'message': 'Call details created successfully.',
                            }
                        result=True
            if result:
                return Response(context, status=status.HTTP_201_CREATED)
            else:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as exception:
             return get_exception_context(exception)
   
   
    def get(self, request, job_id, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            print(get_logged_in_user)
            print(job_id)
            
            user = User.objects.get(id=get_logged_in_user)
           
            # if user.get_role == '3':
            if '3' in user.get_role:
                assigned_order_item = Technician_Assigned_Order_Item.objects.get(id=job_id, technician=user)
                print('**123**')
                print(assigned_order_item)
                call_details = CallDetail.objects.filter(assigned_order_item=assigned_order_item,caller_type=1).order_by('-call_time')
                print('123')
                print(call_details)
                 
            elif user.get_role == '4':
                if Customer.objects.filter(email=user.email,is_primary=True):
                    customer = Customer.objects.get(email=user.email)
                    assigned_order_item = Technician_Assigned_Order_Item.objects.get(id=job_id, order_item__order__invoice__customer=customer)
                    call_details = CallDetail.objects.filter(assigned_order_item=assigned_order_item,caller_type=2).order_by('-call_time')
                else:
                    cust = Customer_Info.objects.get(email=user.email)
                    assigned_order_item = Technician_Assigned_Order_Item.objects.get(id=job_id, order_item__order__invoice__customer__id=cust.customer.id)
                    call_details = CallDetail.objects.filter(assigned_order_item=assigned_order_item,caller_type=2).order_by('-call_time')
            else:
                return Response({'error': 'Invalid sender'}, status=200)
                
            # serializer = CallDetailSerializer(call_details, many=True)
            activity_data = Technician_Comment.objects.filter(technician_assigend_order_item=assigned_order_item)
            call_detail_serializer = CallDetailSerializer(call_details, many=True)
            activity_serializer = ActivitySerializer(activity_data, many=True) 
            
            
            serializer = {
                    'call_details': call_detail_serializer.data,
                    'activity': activity_serializer.data,
                }
            
            # Adjust this based on your models
            context = {
                "status": status.HTTP_200_OK,
                "success": True,
                'message': 'Call details retrieved successfully.',
                'response': serializer
                
               
            }

            return Response(context, status=status.HTTP_200_OK)

        except Exception as exception:
            return get_exception_context(exception)

class QuestionAnswerListAPIView(APIView):
    authentication_classes = []
    def getold(self, request, *args,job_id, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            answers = Answer.objects.filter(
                technician_assigned_job__technician=get_logged_in_user, is_active=True,technician_assigned_job=job_id
            )

            grouped_data = {}
            for answer in answers:
                checklist_name = answer.question.checklist.checklist_name
                type = answer.question.checklist.get_type()
                is_part = answer.question.checklist.is_part
                heading = answer.question.heading.heading
                subheading = answer.question.subheading.subheading

                question_data = {
                    "job_id": answer.technician_assigned_job.id,
                    "question_id": answer.id,
                    "question": answer.question.question,
                    "answer": answer.get_answer_display(),
                    "comment": answer.comment,
                    "is_parts":answer.is_parts,
                }
                
                

                key = (checklist_name, type, is_part)
                if key not in grouped_data:
                    grouped_data[key] = {"headings": {}}

                if heading not in grouped_data[key]["headings"]:
                    grouped_data[key]["headings"][heading] = {"subheadings": {}}

                if subheading not in grouped_data[key]["headings"][heading]["subheadings"]:
                    grouped_data[key]["headings"][heading]["subheadings"][subheading] = {"questions": []}

                grouped_data[key]["headings"][heading]["subheadings"][subheading]["questions"].append(question_data)
                
                if answer.is_parts:
                    question_data["parts_detail"] = self.get_parts_detail(answer.technician_assigned_job.id)
                
                
                

            result = []
            for key, data in grouped_data.items():
                checklist_name, type, is_part = key
                checklist_data = {
                    "checklist_name": checklist_name,
                    "type": type,
                    "is_part": is_part,
                    "headings": [],
                }

                for heading, subheading_data in data["headings"].items():
                    heading_data = {
                        "heading": heading,
                        "subheadings": [],
                    }

                    for subheading, questions_data in subheading_data["subheadings"].items():
                        subheading_data = {
                            "subheading": subheading,
                            "questions": questions_data["questions"],
                        }

                        heading_data["subheadings"].append(subheading_data)

                    checklist_data["headings"].append(heading_data)

                result.append(checklist_data)

            context = {
                'status': status.HTTP_200_OK,
                'success': True,
                'response': result,
            }

            return Response(context, status=status.HTTP_200_OK)

        except ObjectDoesNotExist as e:
            return Response({'error': 'Object does not exist'}, status=status.HTTP_404_NOT_FOUND)

        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    def get(self, request, *args,job_id, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            answers = Answer.objects.filter(
                technician_assigned_job__technician=get_logged_in_user, is_active=True,technician_assigned_job=job_id,
                is_parts=0,is_warrenty=0,is_installation=1
            )

            grouped_data = {}
            for answer in answers:
                checklist_name = answer.question.checklist.checklist_name
                type = answer.question.checklist.get_type()
                is_part = answer.question.checklist.is_part
                heading = answer.question.heading.heading
                if answer.question.subheading:
                    subheading = answer.question.subheading.subheading
                else:
                    subheading = ''
                    

                question_data = {
                    "job_id": answer.technician_assigned_job.id,
                    "question_id": answer.id,
                    "question": answer.question.question,
                    "answer": answer.get_answer_display(),
                    "comment": answer.comment,
                    "is_parts":answer.is_parts,
                    "subheading":subheading
                }
                
                

                key = (checklist_name, type, is_part)
                if key not in grouped_data:
                    grouped_data[key] = {"headings": {}}

                if heading not in grouped_data[key]["headings"]:
                    grouped_data[key]["headings"][heading] ={"questions": []}

                # if subheading not in grouped_data[key]["headings"][heading]["subheadings"]:
                #     grouped_data[key]["headings"][heading]["subheadings"][subheading] = {"questions": []}

                grouped_data[key]["headings"][heading]["questions"].append(question_data)
                
                if answer.is_parts:
                    question_data["parts_detail"] = self.get_parts_detail(answer.technician_assigned_job.id)
                    
          
                    
                    
                
            answers = Answer.objects.filter(
                technician_assigned_job__technician=get_logged_in_user, is_active=True,technician_assigned_job=job_id,
            ).filter(Q(question__id=137) | Q(question__id=178))    
            for answer in answers:
                checklist_name = ''
                type = ' '
                is_part = True
                heading = 'Service Question'
                subheading = ''

                question_data = {
                    "job_id": answer.technician_assigned_job.id,
                    "question_id": answer.id,
                    "question": answer.question.question,
                    "answer": answer.get_answer_display(),
                    "comment": answer.comment,
                    "is_parts":answer.is_parts,
                    
                    "subheading":subheading
                }
                key = (checklist_name, type, is_part)
                if key not in grouped_data:
                    grouped_data[key] = {"headings": {}}

                if heading not in grouped_data[key]["headings"]:
                    grouped_data[key]["headings"][heading] ={"questions": []}

                grouped_data[key]["headings"][heading]["questions"].append(question_data)
                
                if answer.is_parts:
                    question_data["parts_detail"] = self.get_parts_detail(answer.technician_assigned_job.id)
                   

            result = []
            for key, data in grouped_data.items():
                checklist_name, type, is_part = key
                checklist_data = {
                    "checklist_name": checklist_name,
                    "type": type,
                    "is_part": is_part,
                    "headings": [],
                }

                for heading ,questions_data in data["headings"].items():
                    heading_data = {
                        "heading": heading,
                        "questions": questions_data["questions"],
                        # "subheadings": [],
                    }

                    # for questions_data in subheading_data["subheadings"].items():
                    #     subheading_data = {
                    #         "subheading": subheading,
                    #         "questions": questions_data["questions"],
                    #     }

                    # heading_data["headings"].append(heading_data)

                    checklist_data["headings"].append(heading_data)

                result.append(checklist_data)
           
            context = {
                'status': status.HTTP_200_OK,
                'success': True,
                'response': result,
            }

            return Response(context, status=status.HTTP_200_OK)

        except ObjectDoesNotExist as e:
            return Response({'error': 'Object does not exist'}, status=status.HTTP_404_NOT_FOUND)

        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
                    
            
    def get_parts_detail(self, job_id):
            try:
                   
                parts_details = Parts_Request.objects.filter(technician_assigned_job_id=job_id).values()
                return parts_details
            except Exception as e:
                print(f"Error in get_parts_detail: {e}")
                return None
    def change_signature_status(job_id):
        technician_assigned_job_row = Technician_Assigned_Order_Item.objects.get(id=job_id)
        questionsrow=Answer.objects.filter(technician_assigned_job=technician_assigned_job_row,answer__isnull=True).count()
        if questionsrow == 0 :
            technician_assigned_job_row.is_signature=True
            technician_assigned_job_row.save()
            
    def post(self, request, format=None):
        token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
        valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
        get_logged_in_user = valid_data['user_id']

        question_id = request.data.get('question_id')
        serviceJobPartsRequested = request.data.get('serviceJobPartsRequested')
        is_parts = request.data.get('is_parts', False)
        print(is_parts)
        
        job_id = request.data.get('job_id')
        if not job_id:
            context = {
                "status": status.HTTP_200_OK,
                "success": False,
                'message': 'Job id is required.'
            }
            return Response(context, status=status.HTTP_200_OK)
        if serviceJobPartsRequested == 0:   
            if not question_id:
                context = {
                    "status": status.HTTP_200_OK,
                    "success": False,
                    'message': 'Question id is required.'
                }
                return Response(context, status=status.HTTP_200_OK)

        
        
        technician_assigned_job = Technician_Assigned_Order_Item.objects.get(id=job_id)
        order_item=Order_Item.objects.get(id=technician_assigned_job.order_item.id)

        try:
            
            if is_parts == '1'  and serviceJobPartsRequested == '0':
            # if  Answer.objects.filter(id=question_id,technician_assigned_job=technician_assigned_job):
                try:
                    job_time=Job_Time.objects.get(assigned_order_item=technician_assigned_job,assigned_order_item__technician=get_logged_in_user,stop_time__isnull=True)
                except:
                    job_time = Job_Time.objects.create(assigned_order_item=technician_assigned_job)
                    job_time.start_time = timezone.now()  # Set the start time to the current time
                    job_time.save() 
                    technician_assigned_job.job_status=1
                    if technician_assigned_job.job_type==1:
                        technician_assigned_job.working_status=2
                    if technician_assigned_job.job_type==2:
                        technician_assigned_job.working_status=6
                    technician_assigned_job.save()
                    order_item.status=6
                    order_item.save()
                question=Answer.objects.get(id=question_id)
                answer = request.data.get('answer')
                if not answer:
                    context = {
                        "status": status.HTTP_200_OK,
                        "success": False,
                        'message': 'answer is required.'
                    }
                    return Response(context, status=status.HTTP_200_OK)
                if answer == '1':
                    comment = request.data.get('comment')
                    if not comment:
                        context = {
                            "status": status.HTTP_200_OK,
                            "success": False,
                            'message': 'comment is required.'
                        }
                        return Response(context, status=status.HTTP_200_OK)
                    parts_data = request.data.get('parts_data')
                    print(parts_data)
                    print("deepak")
                    if not parts_data:
                        context = {
                            "status": status.HTTP_200_OK,
                            "success": False,
                            'message': 'parts_data is required.'
                        }
                        return Response(context, status=status.HTTP_200_OK)
                    parts_data = json.loads(parts_data)
                    question.answer =answer
                    question.comment =comment
                    question.is_parts=is_parts
                    created_parts_requests = []
                    result=False
                    for part_data in parts_data:
                        part_id = part_data.get('id')
                        parts_request_data = {
                            'technician_assigned_job': technician_assigned_job.id,
                            'question': question.question.id,
                            'parts_name': part_data.get('parts_name'),
                            'qty': part_data.get('qty')
                        }
                        if part_id:
                            try:
                                parts_request_instance = Parts_Request.objects.get(id=part_id)
                                serializer = PartsRequestSerializer(parts_request_instance, data=parts_request_data, partial=True)
                                context = {
                                    "status": status.HTTP_200_OK,
                                    "success": True,
                                    'message': 'Technician parts request successfully.',
                                 }
                                result=True
                            except Parts_Request.DoesNotExist:
                                parts_request_instance = None
        
                        if not part_id or not parts_request_instance:
                            serializer = PartsRequestSerializer(data=parts_request_data)
        
                        if serializer.is_valid():
                            serializer.save()
                            technician_assigned_job.job_status = 2  # part_needed
                            
                            if technician_assigned_job.job_type==2:
                                 technician_assigned_job.working_status = 8 #Part Needed
                            
                            technician_assigned_job.save()
                            created_parts_requests.append(serializer.data)
                            context = {
                                "status": status.HTTP_200_OK,
                                "success": True,
                                'message': 'Technician parts request successfully.',
                            }
                            result=True
                        else:
                            context = {
                                "status": status.HTTP_400_BAD_REQUEST,
                                "success": False,
                                'message': 'Invalid data provided for parts request.',
                                'errors': serializer.errors
                            }
                            return Response(context, status=status.HTTP_400_BAD_REQUEST)

                    if result:
                        # question.is_active=False  
                        job_time.stop_time = timezone.now()
                        job_time.save()
                        question.save()
                        order_item.status=9
                        order_item.save()
                        technician_assigned_job_row = Technician_Assigned_Order_Item.objects.get(id=job_id)
                        questionsrow=Answer.objects.filter(technician_assigned_job=technician_assigned_job_row,answer__isnull=True).count()
                        if questionsrow == 0 :
                            technician_assigned_job_row.is_signature=True
                            technician_assigned_job_row.save()
                        return Response(context, status=status.HTTP_201_CREATED)
                    else:
                        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
                elif  answer == '2':
                     question.answer =answer
                     question.save()
                     technician_assigned_job.job_status=1
                     if technician_assigned_job.job_type==1:
                        technician_assigned_job.working_status=2
                     if technician_assigned_job.job_type==2:
                        technician_assigned_job.working_status=6
                     
                     technician_assigned_job.save()
                     order_item.status=6
                     order_item.save()
                     context = {
                            "status": status.HTTP_200_OK,
                            "success": True,
                            'message': 'Technician not applicable.'
                            }
                     technician_assigned_job_row = Technician_Assigned_Order_Item.objects.get(id=job_id)
                     questionsrow=Answer.objects.filter(technician_assigned_job=technician_assigned_job_row,answer__isnull=True).count()
                     if questionsrow == 0 :
                         technician_assigned_job_row.is_signature=True
                         technician_assigned_job_row.save()
                     return Response(context, status=status.HTTP_200_OK)
                else:
                    comment = request.data.get('comment')  
                    question.answer =answer
                    question.comment =comment
                    question.save()
                    technician_assigned_job.job_status=1
                    if technician_assigned_job.job_type==1:
                        technician_assigned_job.working_status=2
                    if technician_assigned_job.job_type==2:
                        technician_assigned_job.working_status=6
                    technician_assigned_job.save()
                    
                    order_item.status=6
                    order_item.save()
                    
                    
                    context = {
                            "status": status.HTTP_200_OK,
                            "success": True,
                            'message': 'Technician submit the answer successfully..'
                            }
                    technician_assigned_job_row = Technician_Assigned_Order_Item.objects.get(id=job_id)
                    questionsrow=Answer.objects.filter(technician_assigned_job=technician_assigned_job_row,answer__isnull=True).count()
                    if questionsrow == 0 :
                        technician_assigned_job_row.is_signature=True
                        technician_assigned_job_row.save()
                    return Response(context, status=status.HTTP_200_OK)
                # dd('out')
            elif is_parts == '1' and serviceJobPartsRequested == '1': 
                # dd('here')
                try:
                    job_time=Job_Time.objects.get(assigned_order_item=technician_assigned_job,assigned_order_item__technician=get_logged_in_user,stop_time__isnull=True)
                except:
                    job_time = Job_Time.objects.create(assigned_order_item=technician_assigned_job)
                    job_time.start_time = timezone.now()  # Set the start time to the current time
                    job_time.save() 
                    technician_assigned_job.job_status=1
                    if technician_assigned_job.job_type==1:
                        technician_assigned_job.working_status=2
                    if technician_assigned_job.job_type==2:
                        technician_assigned_job.working_status=6
                    technician_assigned_job.save()
                    order_item.status=6
                    order_item.save()
                question=Answer.objects.get(question_id=137,technician_assigned_job_id=technician_assigned_job.id)
                # if not question:
                #     question=Answer
                answer = request.data.get('answer')
                if not answer:
                    context = {
                        "status": status.HTTP_200_OK,
                        "success": False,
                        'message': 'answer is required.'
                    }
                    return Response(context, status=status.HTTP_200_OK)
                if answer == '1':
                    comment = request.data.get('comment')
                    if not comment:
                        context = {
                            "status": status.HTTP_200_OK,
                            "success": False,
                            'message': 'comment is required.'
                        }
                        return Response(context, status=status.HTTP_200_OK)
                    parts_data = request.data.get('parts_data')
                    print(parts_data)
                    print("deepak")
                    if not parts_data:
                        context = {
                            "status": status.HTTP_200_OK,
                            "success": False,
                            'message': 'parts_data is required.'
                        }
                        return Response(context, status=status.HTTP_200_OK)
                    parts_data = json.loads(parts_data)
                    question.answer =answer
                    question.comment =comment
                    question.is_parts=is_parts
                    created_parts_requests = []
                    result=False
                    for part_data in parts_data:
                        part_id = part_data.get('id')
                        parts_request_data = {
                            'technician_assigned_job': technician_assigned_job.id,
                            'question': question.question.id,
                            'parts_name': part_data.get('parts_name'),
                            'qty': part_data.get('qty')
                        }
                        if part_id:
                            try:
                                parts_request_instance = Parts_Request.objects.get(id=part_id)
                                serializer = PartsRequestSerializer(parts_request_instance, data=parts_request_data, partial=True)
                                context = {
                                    "status": status.HTTP_200_OK,
                                    "success": True,
                                    'message': 'Technician parts request successfully.',
                                 }
                                result=True
                            except Parts_Request.DoesNotExist:
                                parts_request_instance = None
        
                        if not part_id or not parts_request_instance:
                            serializer = PartsRequestSerializer(data=parts_request_data)
        
                        if serializer.is_valid():
                            serializer.save()
                            technician_assigned_job.job_status = 2  # part_needed
                            
                            if technician_assigned_job.job_type==2:
                                 technician_assigned_job.working_status = 8 #Part Needed
                            
                            technician_assigned_job.save()
                            created_parts_requests.append(serializer.data)
                            context = {
                                "status": status.HTTP_200_OK,
                                "success": True,
                                'message': 'Technician parts request successfully.',
                            }
                            result=True
                        else:
                            context = {
                                "status": status.HTTP_400_BAD_REQUEST,
                                "success": False,
                                'message': 'Invalid data provided for parts request.',
                                'errors': serializer.errors
                            }
                            return Response(context, status=status.HTTP_400_BAD_REQUEST)

                    if result:
                        # question.is_active=False  
                        job_time.stop_time = timezone.now()
                        job_time.save()
                        question.save()
                        order_item.status=9
                        order_item.save()
                        technician_assigned_job_row = Technician_Assigned_Order_Item.objects.get(id=job_id)
                        questionsrow=Answer.objects.filter(technician_assigned_job=technician_assigned_job_row,answer__isnull=True).count()
                        if questionsrow == 0 :
                            technician_assigned_job_row.is_signature=True
                            technician_assigned_job_row.save()
                        return Response(context, status=status.HTTP_201_CREATED)
                    else:
                        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
                elif  answer == '2':
                     question.answer =answer
                     question.save()
                     technician_assigned_job.job_status=1
                     if technician_assigned_job.job_type==1:
                        technician_assigned_job.working_status=2
                     if technician_assigned_job.job_type==2:
                        technician_assigned_job.working_status=6
                     
                     technician_assigned_job.save()
                     order_item.status=6
                     order_item.save()
                     context = {
                            "status": status.HTTP_200_OK,
                            "success": True,
                            'message': 'Technician not applicable.'
                            }
                     technician_assigned_job_row = Technician_Assigned_Order_Item.objects.get(id=job_id)
                     questionsrow=Answer.objects.filter(technician_assigned_job=technician_assigned_job_row,answer__isnull=True).count()
                     if questionsrow == 0 :
                         technician_assigned_job_row.is_signature=True
                         technician_assigned_job_row.save()
                     return Response(context, status=status.HTTP_200_OK)
                else:
                    comment = request.data.get('comment')  
                    question.answer =answer
                    question.comment =comment
                    question.save()
                    technician_assigned_job.job_status=1
                    if technician_assigned_job.job_type==1:
                        technician_assigned_job.working_status=2
                    if technician_assigned_job.job_type==2:
                        technician_assigned_job.working_status=6
                    technician_assigned_job.save()
                    
                    order_item.status=6
                    order_item.save()
                    
                    
                    context = {
                            "status": status.HTTP_200_OK,
                            "success": True,
                            'message': 'Technician submit the answer successfully..'
                            }
                    technician_assigned_job_row = Technician_Assigned_Order_Item.objects.get(id=job_id)
                    questionsrow=Answer.objects.filter(technician_assigned_job=technician_assigned_job_row,answer__isnull=True).count()
                    if questionsrow == 0 :
                        technician_assigned_job_row.is_signature=True
                        technician_assigned_job_row.save()
                    return Response(context, status=status.HTTP_200_OK)
            else:
                instance = Answer.objects.get(id=question_id,technician_assigned_job__technician=get_logged_in_user,technician_assigned_job=technician_assigned_job)
                serializer = AnswerSerializer(instance, data=request.data)
                if serializer.is_valid():
                    serializer.save()
                    context = {
                        "status": status.HTTP_200_OK,
                        "success": True,
                        'message': 'Technician submit the answer successfully.'
                    }
                    
                    technician_assigned_job_row = Technician_Assigned_Order_Item.objects.get(id=job_id)
                    questionsrow=Answer.objects.filter(technician_assigned_job=technician_assigned_job_row,answer__isnull=True).count()
                    if questionsrow == 0 :
                        technician_assigned_job_row.is_signature=True
                        technician_assigned_job_row.save()
                    return Response(context, status=status.HTTP_200_OK)
                else:
                    context = {
                        'status': status.HTTP_400_BAD_REQUEST,
                        'success': False,
                        'response': serializer.errors
                    }
                    return Response(context, status=status.HTTP_400_BAD_REQUEST)

        except Question.DoesNotExist:
            return Response({'error': 'Invalid question ID'}, status=status.HTTP_400_BAD_REQUEST)



class CreateChatAPIView(APIView):
    def post(self, request, *args, **kwargs):
        try:
      
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            
            user = User.objects.get(id=get_logged_in_user)
            # userinfo = UserInfo.objects.get(user=user).
            # print(userinfo.get_role)

            user_role_ids = user.role.values_list('id', flat=True)
             
            job_id = request.data.get('job_id')
            content = request.data.get('content')
            
            chat_images = request.FILES.getlist('chat_image')

            if not job_id:
                context = {
                    "status": status.HTTP_200_OK,
                    "success": False,
                    'message': 'Job id is required.'
                }
                return Response(context, status=status.HTTP_200_OK)

            job = Technician_Assigned_Order_Item.objects.get(id=job_id)
            
            is_visible = request.data.get('is_visible')
            
            # if user.get_role == '3':
            if '3' in user.get_role:
                recipient = job.order_item.order.invoice.customer.user.id
                sender=user
                if not is_visible:
                    context = {
                        "status": status.HTTP_400_BAD_REQUEST,
                        "success": False,
                        'message': 'Is visible required.'
                    }
                    return Response(context, status=status.HTTP_400_BAD_REQUEST)

            elif user.get_role == '4':
                recipient = job.technician.userinfo.user.id
                sender=job.order_item.order.invoice.customer.user
                
                if  user.isprimary == 1:
                    sender=job.order_item.order.invoice.customer.user
                    
                else:
                    cust_info=Customer_Info.objects.get(user__id = get_logged_in_user)
                    # user=cust_info.customer.user.id
                    sender=cust_info.user
             
            else:
                return Response({'error': 'Invalid sender'}, status=400)
                
            print(recipient)   
            recipient_user=User.objects.get(id=recipient)
            chat = Chat.objects.create(
                job=job,
                sender=sender,
                recipient=recipient_user,
                content=content,
                is_visible=is_visible
            )
            
            if chat_images:
                for chat_image_data in chat_images:
                    chat_image_data = {'chat_image': chat_image_data}
                    chat_image_serializer = ChatImageSerializer(data=chat_image_data)
    
                    if chat_image_serializer.is_valid():
                        chat_image_serializer.save(chat=chat)
                    else:
                        return Response(chat_image_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
                        
            try:
                get_registration_token = FCMDevice.objects.filter(user_id=recipient, active=True)
                for i in get_registration_token:
                    sendPush('Job Chat Notification',f'EXCITECH Australia-New Chat For Job Id-{job_id}',[i.registration_id])     
            except FCMDevice.DoesNotExist:
                print("FCMDevice not found for the specified conditions. Push notification not sent.")
            except Exception as e:
                print(f"Error sending push notification: {e}")

            context = {
                'status': status.HTTP_201_CREATED,
                'success': True,
                'response':'Chat message created successfully',
            }

            return Response(context,  status=status.HTTP_201_CREATED)  
        except Exception as exception:
            return get_exception_context(exception)  
            
            
    def get(self, request, job_id, *args, **kwargs):
        try:
            
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            user = User.objects.get(id=get_logged_in_user) 
          
            if '3' in user.get_role:
                sender=[]
                sender.append(user)
            else:
                sender=[]
                if  user.isprimary == 1:
                    sender.append(user)   #append
                    cust=Customer.objects.get(user__id=get_logged_in_user)
                    cust_info=Customer_Info.objects.filter(customer__id = cust.id)
                    if cust_info:
                        for u in cust_info:
                            sender.append(u.user)  #append
                        
                else:
                    cust_info=Customer_Info.objects.get(user__id = get_logged_in_user)
                    cust=Customer.objects.get(id=cust_info.customer.id)
                    sender.append(cust.user) #append
                    cust_info=Customer_Info.objects.filter(customer__id = cust.id)
                    if cust_info:
                        for u in cust_info:
                            sender.append(u.user)  #append
                   
            
            chats = Chat.objects.filter(
                Q(sender__in =sender, job__id=job_id) | Q(recipient__in=sender, job__id=job_id)
            )
            Chat.objects.filter( Q(recipient__in=sender) & Q(job__id=job_id) ).update(is_read=1)
            print(chats)
            serializer = ChatSerializer(chats, many=True)
            print(serializer)
            context = {
                'status': status.HTTP_200_OK,
                'success': True,
                'response':serializer.data,
            }
            
            return Response(context, status=status.HTTP_200_OK)

        except Exception as exception:
          
            return get_exception_context(exception)
            
class ServiceSignatureAPIView(APIView):
    def post(self, request, *args, **kwargs):
        
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']  
            
            job_id = request.data.get('job')
                    
            job = Technician_Assigned_Order_Item.objects.get(id=job_id)
            
            print(job)
           
            order_item=Order_Item.objects.get(id=job.order_item.id)
            print(order_item)
            job_time=Job_Time.objects.get(assigned_order_item=job,assigned_order_item__technician=get_logged_in_user,stop_time__isnull=True)
            print(job_time)
            
            serializer = ServiceSignatureSerializer(data=request.data)
            
            print(serializer)
            if serializer.is_valid():
                serializer.save()
                
                if job.job_type==1:
                    job.working_status = 3  #Completed Installation
                if job.job_type==2:
                    job.working_status = 7  #Completed Service  
                
                job.job_status=4
                job.job_completed=True
                job.is_signature=False
                job.save()
                
                if order_item.service_type == 1:
                    
                    order_item.installation_complete=True
                    order_item.status=10
                    p=Product.object.get(id=order_item.product.id)
                    p.is_product=0
                    p.save()
                    
                elif order_item.service_type == 2:   
                    order_item.installation_complete=True
                    order_item.status=11
                    p=Product.object.get(id=order_item.product.id)
                    p.is_product=0
                    p.save()
                 
                job_time.stop_time = timezone.now()
                job_time.save()
                
            
                order_item.save()
                
                print(order_item)
                try:
                    get_registration_token = FCMDevice.objects.filter(user_id=get_logged_in_user, active=True) 
                    for i in get_registration_token:
                        sendPush('Job Completed Notification',f'EXCITECH Australia-Signature Done By The Customer For Job Id-{job.id}',[i.registration_id])     
                except FCMDevice.DoesNotExist:
                    print("FCMDevice not found for the specified conditions. Push notification not sent.")
                except Exception as e:
                    print(f"Error sending push notification: {e}")
                
                try:
                    get_registration_token = FCMDevice.objects.filter(user_id=job.order_item.order.invoice.customer.user.id, active=True)
                    for i in get_registration_token:
                        sendPush('Job Completed Notification',f'EXCITECH Australia-Signature Done By The Customer For Job Id-{job.id}',[i.registration_id])     
                except FCMDevice.DoesNotExist:
                    print("FCMDevice not found for the specified conditions. Push notification not sent.")
                except Exception as e:
                    print(f"Error sending push notification: {e}")
                

                context = {
                    'status': status.HTTP_201_CREATED,
                    'success': True,
                    'response':'Submit signature successfully',
                }
                return Response(context,  status=status.HTTP_201_CREATED)  
                
            else:
                context = {
                    'status': status.HTTP_400_BAD_REQUEST,
                    'success': False,
                    'response': serializer.errors
                }
                return Response(context, status=status.HTTP_400_BAD_REQUEST)
                
        except Exception as exception:
            return get_exception_context(exception)
            
class ServiceSignatureAPIViewByCustomer(APIView):
    def post(self, request, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']  
           
            job_id = request.data.get('job')
         
            question_data = request.data.get('question_answer')
            
            
            if not job_id:
                context = {
                    "status": status.HTTP_200_OK,
                    "success": False,
                    'message': 'Job id is required.'
                }
                return Response(context, status=status.HTTP_200_OK)
                    
            if not question_data:
                context = {
                    "status": status.HTTP_200_OK,
                    "success": False,
                    'message': 'question and answer is required.'
                }
                return Response(context, status=status.HTTP_200_OK)
             
            question_data = json.loads(question_data)
            job = Technician_Assigned_Order_Item.objects.get(id=job_id)
           
            for item in question_data:
                
                question_id = item.get('question_id')
                answer_text = item.get('answer')
                

                ans=Answer.objects.get(id=question_id,technician_assigned_job=job_id)
                ans.answer=answer_text
                ans.save()
                
            
            order_item=Order_Item.objects.get(id=job.order_item.id)
            
            job_time=Job_Time.objects.get(assigned_order_item=job,stop_time__isnull=True)
            technician_assigned_job = Technician_Assigned_Order_Item.objects.get(order_item=order_item, is_signature=False)
            
            
            accepted_images = request.FILES.getlist('accepted_images')
            serializer = ServiceSignatureSerializer(data=request.data)
            if serializer.is_valid():
                service_signature=serializer.save()
                service_signature_id = service_signature
               
                if job.job_type==1:
                    job.working_status = 3  #Completed Installation
                if job.job_type==2:
                    job.working_status = 7  #Completed Service  
                
                job.job_status=4
                job.job_complete_datetime=timezone.now()
                job.job_completed=True
                job.is_signature=True

                job.save()
                
                if order_item.service_type == 1:
                    
                    order_item.installation_complete=True
                    order_item.status=10
                    
                elif order_item.service_type == 2:   
                    order_item.installation_complete=True
                    order_item.status=11
                # if order_item.product.is_trade == 1:
                #     Product.objects.filter(id=order_item.product.id).update(is_product=0)
                job_time.stop_time = timezone.now()
                job_time.save()
            
                order_item.save()

                
                try:
                    get_registration_token = FCMDevice.objects.filter(user_id=get_logged_in_user, active=True) 
                    for i in get_registration_token:
                        sendPush('Job Completed Notification',f'EXCITECH Australia-Signature Done By The Customer For Job Id-{job.id}',[i.registration_id])     
                except FCMDevice.DoesNotExist:
                    print("FCMDevice not found for the specified conditions. Push notification not sent.")
                except Exception as e:
                    print(f"Error sending push notification: {e}")
                
                try:
                    get_registration_token = FCMDevice.objects.filter(user_id=job.technician.id, active=True)
                    for i in get_registration_token:
                        sendPush('Job Completed Notification',f'EXCITECH Australia-Signature Done By The Customer For Job Id-{job.id}',[i.registration_id])     
                except FCMDevice.DoesNotExist:
                    print("FCMDevice not found for the specified conditions. Push notification not sent.")
                except Exception as e:
                    print(f"Error sending push notification: {e}")

             
                if accepted_images:
                    print(accepted_images)
                    
                    for image_data in accepted_images:
                        
                        data = {'accepted_image': image_data}
                        serializer = Accepted_ImageSerializer(data=data)
                        if serializer.is_valid():
                            serializer.save(service_signature=service_signature_id)
                        else:
                           return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
                           
                           
                           
                answer = Answer.objects.filter(technician_assigned_job=job,answer__isnull = False) 
                signature=Service_Signature.objects.get(job=job)
                accepted_images = Accepted_Image.objects.filter(service_signature=signature)
            
                
                if answer:
                    pdf_data = generate_pdf(job, answer,signature,accepted_images)
                    if pdf_data:
                        job.pdf_file.save(f'job_{job.id}.pdf', pdf_data, save=True)
                        
                        subject = f'EXCITECH Australia -Job Checklist Details For Job Id: {job.id}'
                        message = f"Hi {job.order_item.order.invoice.customer},<br>"
                        message += "Please find technician attached checklist."
                        from_email = settings.FROM_EMAIL #job.technician.email # Replace with your email address
                        recipient_email =job.order_item.order.invoice.customer.email  # Use the customer's email address
                        email = EmailMessage(subject, message, from_email, [recipient_email])
                        
                        
                        pdf_file_path = job.pdf_file.path 
                        email.attach_file(pdf_file_path, 'application/pdf')
                        email.content_subtype = 'html'
                        email.send()
                        
                        ci = Customer_Info.objects.filter(customer__id = job.order_item.order.invoice.customer.id,user__is_communication = 1)
                        if ci:
                            for additional_email in  ci:
                                email = EmailMessage(subject, message, from_email, [additional_email.user.email])
                                email.attach_file(pdf_file_path, 'application/pdf')
                                email.content_subtype = 'html'
                                email.send()

                context = {
                    'status': status.HTTP_201_CREATED,
                    'success': True,
                    'response':'Submit signature successfully',
                }
                return Response(context,  status=status.HTTP_201_CREATED)   
                           
                           
                           
                           
            else:
                context = {
                        'status': status.HTTP_400_BAD_REQUEST,
                        'success': False,
                        'response': serializer.errors
                }
                return Response(context, status=status.HTTP_400_BAD_REQUEST)
                
        except Exception as exception:
            return get_exception_context(exception)            
            


class PDFAPIView(APIView):
    def get(self, request, job_id, *args, **kwargs):
        job = get_object_or_404(Technician_Assigned_Order_Item, id=job_id)
        # Assuming job.pdf is the PDF file associated with the job
        # Replace 'pdf' with the actual field name in your model if needed
        pdf_file = job.pdf_file
        if pdf_file:
            response = FileResponse(pdf_file, as_attachment=True, filename=f'job_{job_id}.pdf')
            return response
        else:
            return Response({'error': 'PDF not found'}, status=status.HTTP_404_NOT_FOUND)


def generate_pdf(job, answer,signature,accepted_images):

    template = get_template('pages/check_list/checklist_pdf.html')
    context = {
        'job': job,
        'answer': answer,
        'signature':signature,
        'accepted_images':accepted_images,
    }
    html_content = template.render(context)

    pdf_buffer = BytesIO()
    result = pisa.CreatePDF(html_content, dest=pdf_buffer)

    if result.err:
       
        return None

    pdf_buffer.seek(0)
    return pdf_buffer
    
    
class SignatureUpdateAPIView(APIView):
    def put(self, request, pk):
        try:
            order_item = Technician_Assigned_Order_Item.objects.get(pk=pk)
            serializer = TechnicianAssignedOrderItemSerializer(order_item, data=request.data)

            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=status.HTTP_200_OK)
            else:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        except Technician_Assigned_Order_Item.DoesNotExist:
            return Response({'error': 'Technician_Assigned_Order_Item not found.'}, status=status.HTTP_404_NOT_FOUND)
    
    
class CustomerQuestionAnswerListAPIView(APIView):
    authentication_classes = []
    def getold(self, request,order_item_id, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            
            order_item=Order_Item.objects.get(id=order_item_id)
            print(order_item)
            technician_assigned_job = Technician_Assigned_Order_Item.objects.filter(order_item=order_item,is_signature=True).first()

            answers = Answer.objects.filter(
                technician_assigned_job__order_item__order__invoice__customer__user__id=get_logged_in_user,technician_assigned_job=technician_assigned_job)
          

            grouped_data = {}
            for answer in answers:
                
                
                checklist_name = answer.question.checklist.checklist_name if answer.question and answer.question.checklist else ''
                type = answer.question.checklist.get_type() if answer.question and answer.question.checklist and hasattr(answer.question.checklist, 'get_type') else ''
                is_part = answer.question.checklist.is_part if answer.question and answer.question.checklist else ''

                heading = answer.question.heading.heading if answer.question.heading else ''
                subheading = answer.question.subheading.subheading if answer.question.subheading else ''

                question_data = {
                    "job_id": answer.technician_assigned_job.id,
                    "question_id": answer.id,
                    "question": answer.question.question,
                    "answer": answer.get_answer_display(),
                    "comment": answer.comment,
                    "is_parts":answer.is_parts,
                }
                
                

                key = (checklist_name, type, is_part)
                if key not in grouped_data:
                    grouped_data[key] = {"headings": {}}

                if heading not in grouped_data[key]["headings"]:
                    grouped_data[key]["headings"][heading] = {"subheadings": {}}

                if subheading not in grouped_data[key]["headings"][heading]["subheadings"]:
                    grouped_data[key]["headings"][heading]["subheadings"][subheading] = {"questions": []}

                grouped_data[key]["headings"][heading]["subheadings"][subheading]["questions"].append(question_data)
                
                if answer.is_parts:
                    question_data["parts_detail"] = self.get_parts_detail(answer.technician_assigned_job.id)
                
                
                

            result = []
            for key, data in grouped_data.items():
                checklist_name, type, is_part = key
                checklist_data = {
                    "checklist_name": checklist_name ,
                    "type": type,
                    "is_part": is_part,
                    "headings": [],
                }

                for heading, subheading_data in data["headings"].items():
                    heading_data = {
                        "heading": heading,
                        "subheadings": [],
                    }

                    for subheading, questions_data in subheading_data["subheadings"].items():
                        subheading_data = {
                            "subheading": subheading,
                            "questions": questions_data["questions"],
                        }

                        heading_data["subheadings"].append(subheading_data)

                    checklist_data["headings"].append(heading_data)

                result.append(checklist_data)

            context = {
                'status': status.HTTP_200_OK,
                'success': True,
                'response': result,
            }

            return Response(context, status=status.HTTP_200_OK)

        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            
            
    def get_parts_detail(self, job_id):
            try:
                   
                parts_details = Parts_Request.objects.filter(technician_assigned_job_id=job_id).values()
                return parts_details
            except Exception as e:
                print(f"Error in get_parts_detail: {e}")
                return None
    
    def get(self, request, *args,job_id, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            answers = Answer.objects.filter(
                technician_assigned_job__order_item__order__invoice__customer__user__id=get_logged_in_user,technician_assigned_job=job_id,
                is_parts=0,is_warrenty=0
            )
            print(answers)
            grouped_data = {}
            for answer in answers:
                checklist_name = answer.question.checklist.checklist_name
                type = answer.question.checklist.get_type()
                is_part = answer.question.checklist.is_part
                heading = answer.question.heading.heading
                if answer.question.subheading:
                    subheading = answer.question.subheading.subheading
                else:
                    subheading = ''
                    

                question_data = {
                    "job_id": answer.technician_assigned_job.id,
                    "question_id": answer.id,
                    "question": answer.question.question,
                    "answer": answer.get_answer_display(),
                    "comment": answer.comment,
                    "is_parts":answer.is_parts,
                    "subheading":subheading
                }
                
                

                key = (checklist_name, type, is_part)
                if key not in grouped_data:
                    grouped_data[key] = {"headings": {}}

                if heading not in grouped_data[key]["headings"]:
                    grouped_data[key]["headings"][heading] ={"questions": []}

                # if subheading not in grouped_data[key]["headings"][heading]["subheadings"]:
                #     grouped_data[key]["headings"][heading]["subheadings"][subheading] = {"questions": []}

                grouped_data[key]["headings"][heading]["questions"].append(question_data)
                
                if answer.is_parts:
                    question_data["parts_detail"] = self.get_parts_detail(answer.technician_assigned_job.id)
                    
          
                    
                    
                
            answers = Answer.objects.filter(
                technician_assigned_job__order_item__order__invoice__customer__user__id=get_logged_in_user,technician_assigned_job=job_id,
            ).filter(Q(question__id=137) | Q(question__id=178))
            
            print("deepak",answers)
            for answer in answers:
                checklist_name = ''
                type = ' '
                is_part = True
                heading = 'Service Question'
                subheading = ''

                question_data = {
                    "job_id": answer.technician_assigned_job.id,
                    "question_id": answer.id,
                    "question": answer.question.question,
                    "answer": answer.get_answer_display(),
                    "comment": answer.comment,
                    "is_parts":answer.is_parts,
                    "subheading":subheading
                }
                key = (checklist_name, type, is_part)
                if key not in grouped_data:
                    grouped_data[key] = {"headings": {}}

                if heading not in grouped_data[key]["headings"]:
                    grouped_data[key]["headings"][heading] ={"questions": []}

                grouped_data[key]["headings"][heading]["questions"].append(question_data)
                
                if answer.is_parts:
                    question_data["parts_detail"] = self.get_parts_detail(answer.technician_assigned_job.id)
                   

            result = []
            for key, data in grouped_data.items():
                checklist_name, type, is_part = key
                checklist_data = {
                    "checklist_name": checklist_name,
                    "type": type,
                    "is_part": is_part,
                    "headings": [],
                }

                for heading ,questions_data in data["headings"].items():
                    heading_data = {
                        "heading": heading,
                        "questions": questions_data["questions"],
                        # "subheadings": [],
                    }

                    # for questions_data in subheading_data["subheadings"].items():
                    #     subheading_data = {
                    #         "subheading": subheading,
                    #         "questions": questions_data["questions"],
                    #     }

                    # heading_data["headings"].append(heading_data)

                    checklist_data["headings"].append(heading_data)

                result.append(checklist_data)
           
            context = {
                'status': status.HTTP_200_OK,
                'success': True,
                'response': result,
            }

            return Response(context, status=status.HTTP_200_OK)

        except ObjectDoesNotExist as e:
            return Response({'error': 'Object does not exist'}, status=status.HTTP_404_NOT_FOUND)

        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    # def get(self, request, *args,order_item_id, **kwargs):
    #     try:
    #         token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
    #         valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
    #         get_logged_in_user = valid_data['user_id']
            
    #         order_item=Order_Item.objects.get(id=order_item_id)
           
    #         technician_assigned_job = Technician_Assigned_Order_Item.objects.filter(order_item=order_item,is_signature=True).first()


    #         answers = Answer.objects.filter(
    #           technician_assigned_job__order_item__order__invoice__customer__id=get_logged_in_user,technician_assigned_job=technician_assigned_job,
                
    #         )
            

    #         grouped_data = {}
    #         for answer in answers:
    #             checklist_name = answer.question.checklist.checklist_name
    #             type = answer.question.checklist.get_type()
    #             is_part = answer.question.checklist.is_part
    #             heading = answer.question.heading.heading
    #             if answer.question.subheading:
    #                 subheading = answer.question.subheading.subheading
    #             else:
    #                 subheading = ''
                    

    #             question_data = {
    #                 "job_id": answer.technician_assigned_job.id,
    #                 "question_id": answer.id,
    #                 "question": answer.question.question,
    #                 "answer": answer.get_answer_display(),
    #                 "comment": answer.comment,
    #                 "is_parts":answer.is_parts,
    #                 "subheading":subheading
    #             }
                
                

    #             key = (checklist_name, type, is_part)
    #             if key not in grouped_data:
    #                 grouped_data[key] = {"headings": {}}

    #             if heading not in grouped_data[key]["headings"]:
    #                 grouped_data[key]["headings"][heading] ={"questions": []}

    #             # if subheading not in grouped_data[key]["headings"][heading]["subheadings"]:
    #             #     grouped_data[key]["headings"][heading]["subheadings"][subheading] = {"questions": []}

    #             grouped_data[key]["headings"][heading]["questions"].append(question_data)
                
    #             if answer.is_parts:
    #                 question_data["parts_detail"] = self.get_parts_detail(answer.technician_assigned_job.id)
                
    #         answers = Answer.objects.filter(
                
    #             technician_assigned_job__order_item__order__invoice__customer__user__id=get_logged_in_user,technician_assigned_job=technician_assigned_job,question__id=137
    #             )    
    #         for answer in answers:
    #             checklist_name = ''
    #             type = ' '
    #             is_part = True
    #             heading = ''
    #             subheading = ''

    #             question_data = {
    #                 "job_id": answer.technician_assigned_job.id,
    #                 "question_id": answer.id,
    #                 "question": answer.question.question,
    #                 "answer": answer.get_answer_display(),
    #                 "comment": answer.comment,
    #                 "is_parts":answer.is_parts,
    #                 "subheading":subheading
    #             }
    #             key = (checklist_name, type, is_part)
    #             if key not in grouped_data:
    #                 grouped_data[key] = {"headings": {}}

    #             if heading not in grouped_data[key]["headings"]:
    #                 grouped_data[key]["headings"][heading] ={"questions": []}

    #             grouped_data[key]["headings"][heading]["questions"].append(question_data)
                
    #             if answer.is_parts:
    #                 question_data["parts_detail"] = self.get_parts_detail(answer.technician_assigned_job.id)
                   

    #         result = []
    #         for key, data in grouped_data.items():
    #             checklist_name, type, is_part = key
    #             checklist_data = {
    #                 "checklist_name": checklist_name,
    #                 "type": type,
    #                 "is_part": is_part,
    #                 "headings": [],
    #             }

    #             for heading ,questions_data in data["headings"].items():
    #                 heading_data = {
    #                     "heading": heading,
    #                     "questions": questions_data["questions"],
    #                     # "subheadings": [],
    #                 }

    #                 # for questions_data in subheading_data["subheadings"].items():
    #                 #     subheading_data = {
    #                 #         "subheading": subheading,
    #                 #         "questions": questions_data["questions"],
    #                 #     }

    #                 # heading_data["headings"].append(heading_data)

    #                 checklist_data["headings"].append(heading_data)

    #             result.append(checklist_data)
           
    #         context = {
    #             'status': status.HTTP_200_OK,
    #             'success': True,
    #             'response': result,
    #         }

    #         return Response(context, status=status.HTTP_200_OK)

    #     except ObjectDoesNotExist as e:
    #         return Response({'error': 'Object does not exist'}, status=status.HTTP_404_NOT_FOUND)

    #     except Exception as e:
    #         return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
                    
            
    def get_parts_detail(self, job_id):
            try:
                   
                parts_details = Parts_Request.objects.filter(technician_assigned_job_id=job_id).values()
                return parts_details
            except Exception as e:
                print(f"Error in get_parts_detail: {e}")
                return None  
  





class PartDetailListAPIView(APIView):
    authentication_classes = []
    def get(self, request, *args,job_id, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            part_request = Parts_Request.objects.filter(
                technician_assigned_job__technician=get_logged_in_user,technician_assigned_job_id=job_id
            )
            serializer=PartsRequestSerializer(part_request,many=True)
            context = {
                'status': status.HTTP_200_OK,
                'success': True,
                'response': serializer.data,
            }
            return Response(context, status=status.HTTP_200_OK)

        except Exception as exception:
          
            return get_exception_context(exception)
            
            
     
    def post(self, request, *args,job_id, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']

            part_delete_id = request.data.get('part_delete_id')

            if not part_delete_id:
                context = {
                    "status": status.HTTP_200_OK,
                    "success": False,
                    'message': 'part delete id  is required.'
                }
                return Response(context, status=status.HTTP_200_OK)
     
            # parts_data = json.loads(parts_data)

            if part_delete_id:
        
                    part_request = Parts_Request.objects.filter(id=part_delete_id,
                            technician_assigned_job__technician=get_logged_in_user,technician_assigned_job_id=job_id
                        ).delete()
                    context = {
                        'status': status.HTTP_200_OK,
                        'success': True,
                        'response': 'successfully',
                    }

            return Response(context, status=status.HTTP_200_OK)

        except Exception as exception:
          
            return get_exception_context(exception)
            

class CustomerInvoiceListAPI(APIView):
    authentication_classes = []
    pagination_class = CustomPagination
    def get(self, request, *args, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            # customer=Customer.objects.get(id=get_logged_in_user)
            queryset = Invoice.objects.filter(customer__user__id= get_logged_in_user )
            print(queryset)
            
        
            paginator = self.pagination_class()
            paginated_queryset = paginator.paginate_queryset(queryset, request)
            next_page = paginator.get_next_link() or ''
            previous_page = paginator.get_previous_link() or ''
            total_pages = paginator.page.paginator.num_pages or ''
            
            serializer_data = CustomerInvoiceSerializer(paginated_queryset, many=True)
            serializer = {
                'results': serializer_data.data,  # Use the serialized data here
                'next': next_page,
                'previous': previous_page,
                'total_pages': total_pages,
            }
            
            context ={
            "status": status.HTTP_200_OK,
            "success": True,
            "response": serializer
            }
            return Response(context,status=status.HTTP_200_OK)
            
        except Exception as exception:
            return get_exception_context(exception)
           
class ViewChecklist(APIView):
    def get(self, request, *args, job_id, **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', "").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            logged_in_user_id = valid_data['user_id']
            
            technician_assigned_job = Technician_Assigned_Order_Item.objects.get(
                id=job_id, is_signature=False
            )
            print(technician_assigned_job)
            answers = Answer.objects.filter(
                Q(technician_assigned_job=technician_assigned_job),
                Q(is_parts=0),
                Q(question__checklist__type=3)
            )
            question_data = []
            for answer in answers:
                question_data.append({
                    "job_id": answer.technician_assigned_job.id,
                    "question_id": answer.id,
                    "question": answer.question.question,
                    "answer": answer.get_answer_display(),
                })
        
            if technician_assigned_job.order_item.product.is_product :
                context = {
                    'status': status.HTTP_200_OK,
                    'success': True,
                    'response': [],
                }
            else:
                context = {
                    'status': status.HTTP_200_OK,
                    'success': True,
                    'response': question_data,
                }

            return Response(context, status=status.HTTP_200_OK)

        except ObjectDoesNotExist as e:
            return Response({'error': 'Object does not exist'}, status=status.HTTP_404_NOT_FOUND)

        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    
   
                    
            
# class JobTimerAPIView(APIView):
  
#     authentication_classes = []
#     def post(self, request, job_id):
#         # return HttpResponse('hello')
#         try:
#             token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
#             valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
#             get_logged_in_user = valid_data['user_id']
#             assigned_order_item=Technician_Assigned_Order_Item.objects.get(id=job_id,technician=get_logged_in_user)
            
            
            
#             serializer = JobTimerSerializer(assigned_order_item,data=request.data)
            
#             if serializer.is_valid():
#                 serializer.save()
                
#                 context = {
#                         "status": status.HTTP_201_CREATED,
#                         "success": True,
#                         'message': 'Successfully Submit Timer Time.'
                    
#                 }
          
#                 return Response(context, status=status.HTTP_201_CREATED)
                
#             else:
#                 context = {
#                         'status': status.HTTP_400_BAD_REQUEST,
#                         'success': False,
#                         'response': serializer.errors
#                 }
#                 return Response(context, status=status.HTTP_400_BAD_REQUEST)           
            
#         except Exception as e:
#             return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)    
            
            
      

 
class JobIntervalStartStopAPIView(APIView):
    authentication_classes = []
    def post(self, request):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            # assigned_order_item=Technician_Assigned_Order_Item.objects.get(id=job_id,technician=get_logged_in_user)
           
            serializer = JobIntervalTimeSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                        
                context = {
                    'status': status.HTTP_201_CREATED,
                    'success': True,
                    'response': 'Successfully Submit Timer Time.',
                }
                return Response(context, status=status.HTTP_201_CREATED)
            else:
                context = {
                    'status': status.HTTP_400_BAD_REQUEST,
                    'success': False,
                    'response': serializer.errors
                }
                return Response(context, status=status.HTTP_400_BAD_REQUEST)      
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)        


class AssignedLeadListAPI(APIView):    
    pagination_class = CustomPagination
    def get(self, request, *args,  **kwargs):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', "").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            logged_in_user_id = valid_data['user_id']
            # search_key = request.GET.get('search_key', '').strip()
            leads = Lead.objects.filter(deleted_at__isnull=True)
            
            # serializer = LeadSerializer(leads, many=True)
            # if search_key:
            #     leads = leads.filter(
            #         Q(first_name__icontains=search_key) |
            #         Q(last_name__icontains=search_key) |
            #         Q(company_name__icontains=search_key) |
            #         Q(work_phone__icontains=search_key) |
            #         Q(mobile__icontains=search_key) |
            #         Q(email__icontains=search_key)
            #     )
            # leads = leads.order_by('-id')
            search_fields = ['lead_id','first_name', 'last_name', 'company_name', 'work_phone', 'mobile', 'email','lead_source','business_type','address','products']

            # Dynamically build Q object based on provided params
            search_filters = Q()
            for field in search_fields:
                print(field)
                value = request.GET.get(field)
                # if value:
                #     kwargs = {f"{field}__icontains": value.strip()}
                #     search_filters &= Q(**kwargs)
                if value:
                    print(value)
                    value = value.strip()
                    
                    if field == 'products':
                        product_list = [p.strip() for p in value.split(',')]  # assume comma-separated product names or IDs
                        search_filters &= Q(products__in=product_list)
                    elif field == 'lead_id':
                        if value.isdigit():  # extra safety check
                            search_filters &= Q(id=int(value))
                    
                    elif field == 'address':
                        # Check multiple address subfields using OR logic
                        address_filter = (
                            Q(post_code__icontains=value) |
                            Q(street__icontains=value) |
                            Q(city__icontains=value) |
                            Q(country__icontains=value)
                        )
                        search_filters &= address_filter
                    
                    else:
                        # Default to icontains
                        kwargs = {f"{field}__icontains": value}
                        search_filters &= Q(**kwargs)
            print(search_filters)
            if search_filters:
                leads = leads.filter(search_filters)
            paginator = self.pagination_class()
            paginated_queryset = paginator.paginate_queryset(leads, request)
            next_page = paginator.get_next_link() or ''
            previous_page = paginator.get_previous_link() or ''
            total_pages = paginator.page.paginator.num_pages or ''
            
            serializer_data = LeadSerializer(paginated_queryset, many=True)
            
            if not leads :
                context = {
                    'status': status.HTTP_200_OK,
                    'success': True,
                    'response':  {
                        'results': [],
                        'next': None,
                        'previous': None,
                        'total_pages': 0,
                    },
                }
            else:
                serializer = {
                'results': serializer_data.data,  # Use the serialized data here
                'next': next_page,
                'previous': previous_page,
                'total_pages': total_pages,
            }
                context = {
                    'status': status.HTTP_200_OK,
                    'success': True,
                    'response': serializer,
                }

            return Response(context, status=status.HTTP_200_OK)

        except ObjectDoesNotExist as e:
            return Response({'error': 'Object does not exist'}, status=status.HTTP_404_NOT_FOUND)

        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        
    def post(self, request):
        # print(request.body)
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            get_logged_in_user = valid_data['user_id']
            assigned_user = get_object_or_404(User, id=get_logged_in_user) if get_logged_in_user else None
            raw_products = request.data.getlist('products[]') or request.data.getlist('products')
            cleaned_products = [int(p) for p in raw_products if p and p.isdigit()]
            data = request.data.copy()
            data.setlist('products', cleaned_products)
            data['assigned_to'] = assigned_user.id 
            print(assigned_user)
            serializer = LeadSerializer(data=data)
            if serializer.is_valid():
                serializer.save()
                context = {
                    'status': status.HTTP_201_CREATED,
                    'success': True,
                    'response': 'Lead Created By Successfully.',
                }
                return Response(context, status=status.HTTP_201_CREATED)
            else:
                context = {
                    'status': status.HTTP_400_BAD_REQUEST,
                    'success': False,
                    'response': serializer.errors
                }
                return Response(context, status=status.HTTP_400_BAD_REQUEST)      
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
                    
class LeadDetailAPI(APIView):
    def put(self, request, lead_id):
        try:
            lead = get_object_or_404(Lead, id=lead_id)
            raw_products = request.data.getlist('products[]') or request.data.getlist('products')
            cleaned_products = [int(p) for p in raw_products if p and p.isdigit()]
            data = request.data.copy()
            # data.setlist('products', request.data.getlist('products'))
            data.setlist('products', cleaned_products)
            # data['assigned_to_id'] = assigned_user.id
            serializer = LeadSerializer(lead, data=data, partial=True)
            if serializer.is_valid():
                serializer.save()
                return Response({'success': True, 'message': 'Lead updated'}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# class listCustomerNoteAPI(APIView):
#     pagination_class = CustomPagination
#     def get(self, request, *args,  **kwargs):
#         try:
#             auth_header = request.META.get('HTTP_AUTHORIZATION', '')
#             parts = auth_header.split(' ')
#             if len(parts) != 2 or parts[0] != 'Bearer':
#                 return Response({'error': 'Invalid or missing token'}, status=status.HTTP_401_UNAUTHORIZED)
            
#             token = parts[1]
#             valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
#             logged_in_user_id = valid_data['user_id']
#             today = date.today()
#             leads = Leadnote.objects.filter(deleted_at__isnull=True,assigned_to__id=logged_in_user_id,reminder_date=today)
#             # print(technician_assigned_job)
            
#             # serializer = LeadNoteCreateSerializer(leads, many=True)
#             paginator = self.pagination_class()
#             paginated_queryset = paginator.paginate_queryset(leads, request)
#             next_page = paginator.get_next_link() or ''
#             previous_page = paginator.get_previous_link() or ''
#             total_pages = paginator.page.paginator.num_pages or ''
            
#             serializer_data = LeadNoteCreateSerializer(paginated_queryset, many=True)
            
#             if not leads :
#                 context = {
#                     'status': status.HTTP_200_OK,
#                     'success': True,
#                     'response': [],
#                 }
#             else:
#                 serializer = {
#                 'results': serializer_data.data,  # Use the serialized data here
#                 'next': next_page,
#                 'previous': previous_page,
#                 'total_pages': total_pages,
#             }
#                 context = {
#                     'status': status.HTTP_200_OK,
#                     'success': True,
#                     'response': serializer,
#                 }

#             return Response(context, status=status.HTTP_200_OK)

#         except ObjectDoesNotExist as e:
#             return Response({'error': 'Object does not exist'}, status=status.HTTP_404_NOT_FOUND)

#         except Exception as e:
#             return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class listCustomerNoteAPI(APIView):
    pagination_class = CustomPagination

    def get_note_history(self, lead_id):
        # Get latest created_at for each groupid for this lead
        latest_notes = (
            Leadnote.objects.filter(
                groupid=lead_id,
                deleted_at__isnull=True
            )
            .values('groupid')
            .annotate(latest_created=Max('created_at'))
        )

        # Build filters for groupid and created_at
        filters = Q()
        for item in latest_notes:
            filters |= Q(groupid=item['groupid'], created_at=item['latest_created'])

        return Leadnote.objects.filter(
            groupid=lead_id,
            deleted_at__isnull=True
        ).order_by('-created_at')

    def get(self, request, *args, **kwargs):
        try:
            # Get JWT token and decode
            auth_header = request.META.get('HTTP_AUTHORIZATION', '')
            parts = auth_header.split(' ')
            if len(parts) != 2 or parts[0] != 'Bearer':
                return Response({'error': 'Invalid or missing token'}, status=status.HTTP_401_UNAUTHORIZED)

            token = parts[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            logged_in_user_id = valid_data['user_id']

            # Get today's notes assigned to user
            today = date.today()
            leads = Leadnote.objects.filter(
                deleted_at__isnull=True,
                assigned_to__id=logged_in_user_id,
                # reminder_date=today
                reminder_date__isnull=False,
                reminder_date__lte=today,
                is_read=0,
            )

            # Paginate
            paginator = self.pagination_class()
            paginated_queryset = paginator.paginate_queryset(leads, request)
            next_page = paginator.get_next_link() or ''
            previous_page = paginator.get_previous_link() or ''
            total_pages = paginator.page.paginator.num_pages or ''

            # Serialize main notes
            serializer_data = LeadNoteCreateSerializer(paginated_queryset, many=True)

            # Add note history for each note's lead
            full_response = []
            for note_data in serializer_data.data:
                lead_id = note_data.get('lead')
                history_qs = self.get_note_history(note_data.get('groupid'))
                history_serialized = LeadNoteCreateSerializer(history_qs, many=True).data

                note_data['note_history'] = history_serialized
                full_response.append(note_data)

            context = {
                'status': status.HTTP_200_OK,
                'success': True,
                'response': {
                    'results': full_response,
                    'next': next_page,
                    'previous': previous_page,
                    'total_pages': total_pages,
                }
            }
            return Response(context, status=status.HTTP_200_OK)

        except ObjectDoesNotExist:
            return Response({'error': 'Object does not exist'}, status=status.HTTP_404_NOT_FOUND)

        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class LeadNoteAPI(APIView):
    def get_note_history(self, lead_id):
        # Get latest created_at for each groupid for this lead
        latest_notes = (
            Leadnote.objects.filter(
                groupid=lead_id,
                deleted_at__isnull=True
            )
            .values('groupid')
            .annotate(latest_created=Max('created_at'))
        )

        # Build filters for groupid and created_at
        filters = Q()
        for item in latest_notes:
            filters |= Q(groupid=item['groupid'], created_at=item['latest_created'])

        return Leadnote.objects.filter(
            groupid=lead_id,
            deleted_at__isnull=True
        ).order_by('-created_at')
    def get(self, request, *args,  **kwargs):
        try:
            lead_id = kwargs.get('lead_id')
            auth_header = request.META.get('HTTP_AUTHORIZATION', '')
            parts = auth_header.split(' ')
            if len(parts) != 2 or parts[0] != 'Bearer':
                return Response({'error': 'Invalid or missing token'}, status=status.HTTP_401_UNAUTHORIZED)
            
            token = parts[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            logged_in_user_id = valid_data['user_id']
            
            # leads = Leadnote.objects.filter(deleted_at__isnull=True,lead__id=lead_id)
            latest_notes = (
                Leadnote.objects.filter(
                    lead_id=lead_id,
                    deleted_at__isnull=True
                )
                .values('groupid')
                .annotate(latest_created=Max('created_at'))
            )

            filters = Q()
            for item in latest_notes:
                filters |= Q(groupid=item['groupid'], created_at=item['latest_created'])

            # STEP 2: Get the latest notes only (per group)
            latest_notes_qs = Leadnote.objects.filter(
                deleted_at__isnull=True,
                lead_id=lead_id
            ).filter(filters).order_by('-created_at')

            # STEP 3: Serialize latest notes
            serializer = LeadNoteCreateSerializer(latest_notes_qs, many=True)
            # print(technician_assigned_job)
            # serializer = LeadNoteCreateSerializer(leads, many=True)
            full_response = []
            for note_data in serializer.data:
                lead_id = note_data.get('lead')
                history_qs = self.get_note_history(note_data.get('groupid'))
                history_serialized = LeadNoteCreateSerializer(history_qs, many=True).data

                note_data['note_history'] = history_serialized
                full_response.append(note_data)
            if not latest_notes_qs :
                context = {
                    'status': status.HTTP_200_OK,
                    'success': True,
                    'response': [],
                }
            else:
                context = {
                    'status': status.HTTP_200_OK,
                    'success': True,
                    'response': full_response, #serializer.data,
                }

            return Response(context, status=status.HTTP_200_OK)

        except ObjectDoesNotExist as e:
            return Response({'error': 'Object does not exist'}, status=status.HTTP_404_NOT_FOUND)

        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class AddCustomerNoteAPI(APIView):
    def post(self, request, lead_id):
        token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
        valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
        get_logged_in_user = valid_data['user_id']
        lead = get_object_or_404(Lead, id=lead_id)

        data = request.data.copy()
        # userid = data.get('userid')
        assigned_user = get_object_or_404(User, id=get_logged_in_user) if get_logged_in_user else None

        last_group = Leadnote.objects.order_by('-groupid').first()
        next_group_id = (last_group.groupid + 1) if last_group else 1
        # userid = request.POST.get("assigned_to") or None
        meeting_time =request.data.get('meeting_time') or None
        input_date = data.get('reminder_date')  # e.g., "30-05-2025"
        reminder_date = None
        
        if input_date:
            try:
                parsed_date = datetime.strptime(input_date, "%d-%m-%Y")
                reminder_date = parsed_date.strftime("%Y-%m-%d")
            except ValueError:
                return Response({'error': 'Invalid date format. Use DD-MM-YYYY.'}, status=400)
        
        # if not userid == None:
        #     assigned_user = get_object_or_404(User, id=userid)
        note_instance = Leadnote(
            lead=lead,
            note=data.get('note'),
            reminder_date= reminder_date,
            created_by_id=1, #request.user,
            assigned_to=assigned_user,
            groupid=next_group_id,
            meeting_invitation=int(data.get('meeting_invitation', 0)),
            meeting_time =meeting_time ,
            meet_link=data.get('meet_link'),
        )
        note_instance.save()

        return Response({'message': 'Note added successfully'}, status=status.HTTP_201_CREATED)
class updateCustomerNoteAPI(APIView):
    def put(self, request, lead_id, note_id):
        return self._handle_note_save(request, lead_id, note_id)

    def _handle_note_save(self, request, lead_id, note_id=None):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            logged_in_user_id = valid_data['user_id']

            lead = get_object_or_404(Lead, id=lead_id)
            data = request.data.copy()

            assigned_user = get_object_or_404(User, id=logged_in_user_id) if logged_in_user_id else None
            if data.get("assigned_to"):
                assigned_user = get_object_or_404(User, id=data.get("assigned_to"))

            input_date = data.get('reminder_date')  # e.g., "30-05-2025"
            reminder_date = None
            meeting_time =request.data.get('meeting_time') or None
            if input_date:
                try:
                    parsed_date = datetime.strptime(input_date, "%d-%m-%Y")
                    reminder_date = parsed_date.strftime("%Y-%m-%d")
                except ValueError:
                    return Response({'error': 'Invalid date format. Use DD-MM-YYYY.'}, status=400)

            if note_id:
                note_instance = get_object_or_404(Leadnote, id=note_id, lead_id=lead_id)
            else:
                last_group = Leadnote.objects.order_by('-groupid').first()
                next_group_id = (last_group.groupid + 1) if last_group else 1
                note_instance = Leadnote(groupid=next_group_id)

            note_instance.lead = lead
            note_instance.note = data.get('note')
            note_instance.reminder_date = reminder_date
            note_instance.created_by_id = 1  # or use `logged_in_user_id`
            note_instance.assigned_to = assigned_user
            note_instance.meeting_invitation = int(data.get('meeting_invitation', 0))
            note_instance.meeting_time =meeting_time ,
            note_instance.meet_link = data.get('meet_link')
            note_instance.save()

            return Response({'message': 'Note saved successfully'}, status=status.HTTP_200_OK if note_id else status.HTTP_201_CREATED)

        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    def delete(self, request, lead_id, note_id):
        try:
            # Optional: verify token
            token = request.META.get('HTTP_AUTHORIZATION', ' ').split(' ')[1]
            TokenBackend(algorithm='HS256').decode(token, verify=False)

            note = get_object_or_404(Leadnote, id=note_id, lead_id=lead_id)

            # Soft delete if using `deleted_at`
            note.deleted_at = timezone.now()
            note.save()

            # Hard delete (optional):
            # note.delete()

            return Response({'message': 'Note deleted successfully'}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class LeadDeleteAPI(APIView):
    def delete(self, request, lead_id):
        try:
            lead = get_object_or_404(Lead, id=lead_id)
            lead.delete()
            return Response({'message': 'Lead deleted successfully.'}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class UpdatereadNoteAPI(APIView):
    def post(self, request, note_id):
        try:
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            logged_in_user_id = valid_data['user_id']
            data = request.data.copy()
            if note_id:
                note_instance = get_object_or_404(Leadnote, id=note_id)
                note_instance.is_read = 1
                note_instance.save()
    
            return Response({'message': 'Note Read successfully'}, status=status.HTTP_200_OK if note_id else status.HTTP_201_CREATED)
    
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class ProductListAPI(APIView):
    def get(self, request):
        products = Product.objects.filter(deleted_at__isnull=True ,is_active=1)
        serializer = ProductSerializer(products, many=True)
        return Response(serializer.data)
class SalesUserListAPI(APIView):
    def get(self, request):
        # excluded_role_ids = [1, 3, 4, 5]
        # users = User.objects.filter(deleted_at__isnull=True, is_superuser=0).exclude(role__id__in=excluded_role_ids)
        users = User.objects.filter( deleted_at__isnull=True, is_superuser=0, role__id=2 ).distinct()
        serializer = UserSerializer(users, many=True)
        return Response(serializer.data)
class CreateLeadQuotationAPI(APIView):
    
    def post(self, request):
        try:
            auth_header = request.META.get('HTTP_AUTHORIZATION', '')
            parts = auth_header.split(' ')
            if len(parts) != 2 or parts[0] != 'Bearer':
                return Response({'error': 'Invalid or missing token'}, status=status.HTTP_401_UNAUTHORIZED)
            
            token = parts[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
        
            get_logged_in_user = valid_data['user_id']
            lead_id = request.data.get('lead')
            lead = get_object_or_404(Lead, id=lead_id)
            attachment = request.FILES.get('attachment')
            existing_quotes_count = Lead_Quote.objects.filter(lead=lead).count()
            version_number = existing_quotes_count + 1
            assigned_user = get_object_or_404(User, id=get_logged_in_user) if get_logged_in_user else None
            
            leadquote = Lead_Quote.objects.create(
                lead=lead,
                mailstatus=0,
                version=version_number,
                created_by=assigned_user,
            )
    
            if attachment:
                filename = f'Excitech-Australia-Quotation-{leadquote.id}-{leadquote.version}.pdf'
                leadquote.attachment.save(filename, attachment)
                # leadquote.attachment.save(f'{leadquote.id}-attachment.pdf', attachment)
    
            return Response({'message': 'Lead Quote Added Successfully'}, status=status.HTTP_201_CREATED)
        except ObjectDoesNotExist as e:
            return Response({'error': 'Object does not exist'}, status=status.HTTP_404_NOT_FOUND)

        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    def get(self, request):
        try:
            leadquotes = Lead_Quote.objects.filter(deleted_at__isnull=True) #.order_by('-id')
            serializer = LeadQuoteListSerializer(leadquotes, many=True)
            return Response({
                'status': status.HTTP_200_OK,
                'success': True,
                'data': serializer.data
            }, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class AllLeadQuotationAPI(APIView):
    def get(self, request,lead_id, *args,  **kwargs):
        try:
            # lead_id = kwargs.get('lead_id')
            auth_header = request.META.get('HTTP_AUTHORIZATION', '')
            parts = auth_header.split(' ')
            if len(parts) != 2 or parts[0] != 'Bearer':
                return Response({'error': 'Invalid or missing token'}, status=status.HTTP_401_UNAUTHORIZED)
            
            token = parts[1]
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
            logged_in_user_id = valid_data['user_id']
            
            leads = Lead_Quote.objects.filter(deleted_at__isnull=True,lead__id=lead_id)
            # print(technician_assigned_job)
            serializer = LeadQuoteListSerializer(leads, many=True)
            if not leads :
                context = {
                    'status': status.HTTP_200_OK,
                    'success': True,
                    'response': [],
                }
            else:
                context = {
                    'status': status.HTTP_200_OK,
                    'success': True,
                    'response': serializer.data,
                }

            return Response(context, status=status.HTTP_200_OK)

        except ObjectDoesNotExist as e:
            return Response({'error': 'Object does not exist'}, status=status.HTTP_404_NOT_FOUND)

        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class LeadAttachmentPhotosListCreateAPIView(generics.GenericAPIView):
    serializer_class = LeadAttachmentPhotosSerializer

    # def get(self, request, lead_id):
    #     attachments = LeadAttachmentPhotos.objects.filter(lead_id=lead_id)
    #     serializer = self.get_serializer(attachments, many=True)
    #     return Response(serializer.data)
    def get(self, request, lead_id):
        photos = LeadAttachmentPhotos.objects.filter(lead_id=lead_id)
        files = LeadAttachmentFiles.objects.filter(lead_id=lead_id)
    
        photos_serializer = LeadAttachmentPhotosSerializer(photos, many=True)
        files_serializer = LeadAttachmentFilesSerializer(files, many=True)
    
        return Response({
            'photos': photos_serializer.data,
            'files': files_serializer.data,
        }, status=status.HTTP_200_OK)

    def post(self, request, lead_id):
        auth_header = request.META.get('HTTP_AUTHORIZATION', '')
        parts = auth_header.split(' ')
        if len(parts) != 2 or parts[0] != 'Bearer':
            return Response({'error': 'Invalid or missing token'}, status=status.HTTP_401_UNAUTHORIZED)
        
        token = parts[1]
        valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
        token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
    
        get_logged_in_user = valid_data['user_id']
        assigned_user = get_object_or_404(User, id=get_logged_in_user) if get_logged_in_user else None
        lead = get_object_or_404(Lead, id=lead_id)

        images = request.FILES.getlist('images')
        files = request.FILES.getlist('files')
        created_attachments=[]
        for img in images:
            photo_serializer = LeadAttachmentPhotosSerializer(data={
                'lead': lead.id,
                'attachment': img,
            })
            photo_serializer.is_valid(raise_exception=True)
            photo_serializer.save(created_by=assigned_user, updated_by=assigned_user)
            created_attachments.append(photo_serializer.data)

        # Handle file uploads
        for file in files:
            file_serializer = LeadAttachmentFilesSerializer(data={
                'lead': lead.id,
                'attachment': file,
            })
            file_serializer.is_valid(raise_exception=True)
            file_serializer.save(created_by=assigned_user, updated_by=assigned_user)
            created_attachments.append(file_serializer.data)

        return Response(created_attachments, status=status.HTTP_201_CREATED)
class SendLeadQuotationEmailAPI(APIView):
    def post(self, request, id):
        auth_header = request.META.get('HTTP_AUTHORIZATION', '')
        parts = auth_header.split(' ')
        if len(parts) != 2 or parts[0] != 'Bearer':
            return Response({'error': 'Invalid or missing token'}, status=status.HTTP_401_UNAUTHORIZED)
        
        token = parts[1]
        valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
        token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
    
        get_logged_in_user = valid_data['user_id']
        try:
            leadquote = get_object_or_404(Lead_Quote, id=id)
            lead = get_object_or_404(Lead, id=leadquote.lead.id)

            subject = f'EXCITECH Australia - Quote Confirmation Required for Quote ID {leadquote.id}'
            from_email = settings.FROM_EMAIL
            recipient_email = lead.email

            template_data = {'quotation': leadquote}
            message = render_to_string('pages/leads/quote_email_temp.html', template_data)

            email = EmailMessage(subject, message, from_email, [recipient_email])

            if leadquote.attachment:
                pdf_file_path = leadquote.attachment.path
                email.attach_file(pdf_file_path, 'application/pdf')

            email.content_subtype = 'html'
            email.send()

            leadquote.mailstatus = 1
            leadquote.save()

            return Response({'message': 'Mail sent successfully'}, status=status.HTTP_200_OK)

        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class SendLeadNoteEmailAPI(APIView):
    def post(self, request, lead_id, note_id):
        auth_header = request.META.get('HTTP_AUTHORIZATION', '')
        parts = auth_header.split(' ')
        if len(parts) != 2 or parts[0] != 'Bearer':
            return Response({'error': 'Invalid or missing token'}, status=status.HTTP_401_UNAUTHORIZED)
        
        token = parts[1]
        valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
        token = request.META.get('HTTP_AUTHORIZATION', " ").split(' ')[1]
    
        get_logged_in_user = valid_data['user_id']
        try:
            lead = get_object_or_404(Lead, id=lead_id)
            note = get_object_or_404(Leadnote, id=note_id, lead=lead)

            subject = f'EXCITECH Australia - Meeting Scheduled for {lead.first_name } {lead.last_name}'
            context = {
                'lead': lead,
                'note': note,
            }
            message = render_to_string('pages/leads/lead_note_email.html', context)

            recipient_email = lead.email
            from_email = settings.FROM_EMAIL

            email = EmailMessage(subject, message, from_email, [recipient_email,'kiran@beedev.co.in'])
            email.content_subtype = 'html'
            email.send()
            note.mail_status=1
            note.save()
            return Response({'message': 'Note email sent successfully'}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class ProcessNoteActionAPI(APIView):
    # permission_classes = [IsAuthenticated]

    def post(self, request, note_id):
        serializer = NoteActionSerializer(data=request.data)
        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        # Get JWT user manually (if needed), otherwise use request.user
        auth_header = request.META.get('HTTP_AUTHORIZATION', '')
        parts = auth_header.split(' ')
        if len(parts) != 2 or parts[0] != 'Bearer':
            return Response({'error': 'Invalid or missing token'}, status=status.HTTP_401_UNAUTHORIZED)

        token = parts[1]
        try:
            valid_data = TokenBackend(algorithm='HS256').decode(token, verify=False)
        except Exception as e:
            return Response({'error': 'Invalid token'}, status=status.HTTP_401_UNAUTHORIZED)

        user_id = valid_data.get("user_id")

        # Use request.user instead of manually fetching user
        note = get_object_or_404(Leadnote, id=note_id)
        data = serializer.validated_data
        action_type = data["action_type"]

        if action_type == "mark_read":
            note.is_read = True
            note.updated_by_id = user_id
            note.save()
            return Response({"message": "Note marked as read."}, status=status.HTTP_200_OK)

        elif action_type == "update_log":
            log_note = data.get("log_note")
            groupid = data.get("groupid")

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

            note.is_read = True
            note.updated_by_id = user_id
            note.save()
            reschedule_date = data.get("reschedule_date")
            # Leadnote.objects.create(
            #     lead=note.lead,
            #     groupid=groupid,
            #     note=log_note,
            #     reminder_date = data.get("reminder_date"),
            #     created_by_id=user_id,
            #     assigned_to_id=user_id,
            #     # created_at=now(),
            # )
            create_data = {
                "lead": note.lead,
                "groupid": groupid,
                "note": log_note,
                "created_by_id": user_id,
                "assigned_to_id": user_id,
            }
            
            if reschedule_date:
                create_data["reminder_date"] = reschedule_date
            
            Leadnote.objects.create(**create_data)
            return Response({"message": "New log added successfully."}, status=status.HTTP_201_CREATED)

        elif action_type == "reschedule":
            reschedule_date = data.get("reschedule_date")
            groupid = data.get("groupid")
            formatted_date = None
            # if reschedule_date:
            #     try:
            #         # Parse the input (d-m-Y)
            #         parsed_date = datetime.strptime(reschedule_date, "%d-%m-%Y")
            #         # Convert to ISO 8601 string
            #         iso_datetime_str = parsed_date.isoformat()  # Gives '2025-06-05T00:00:00'
            #         formatted_date = iso_datetime_str
            #     except ValueError:
            #         return Response({"error": "Invalid date format. Use DD-MM-YYYY."}, status=400)
            create_data = {
                "lead": note.lead,
                "groupid": groupid,
                "note": 'Rescheduled',
                "created_by_id": user_id,
                "assigned_to_id": user_id,
                "reminder_date" : reschedule_date,
            }
            Leadnote.objects.create(**create_data)
            return Response({"message": "Rescheduled successfully."}, status=status.HTTP_200_OK)

        return Response({"error": "Unknown action type."}, status=status.HTTP_400_BAD_REQUEST)