from django.conf import settings
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Profiles,Otp,Product, Notification,Booking, Client, Loan, Collection, Student, Attendance, Fees, FeesHistory
from django.core.exceptions import ObjectDoesNotExist
from rest_framework.exceptions import NotFound
from django.contrib.auth import authenticate, login
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth.hashers import make_password
from django.contrib.auth.models import User
from django.utils import timezone as djtz
from django.utils import timezone
from datetime import date, datetime, timedelta
import requests
from django.db.models import Sum, Count
from django.utils import timezone
from django.http import HttpResponse
import base64
from rest_framework.parsers import MultiPartParser, FormParser
from django.db.models import Q
from rest_framework.generics import RetrieveAPIView, ListAPIView
from .serializers import UserSerializer
from rest_framework.permissions import IsAuthenticated
from datetime import datetime, time
import json
from django.core.mail import EmailMessage
from school.settings import BASE_DIR
import pdfkit
from django.core.exceptions import ObjectDoesNotExist
# import openai
import re
from django.conf import settings
import threading
# import pywhatkit
from django.core.mail import send_mail
from django.utils.crypto import get_random_string
from django.db.models import Sum




from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView
from django.core.exceptions import ObjectDoesNotExist
from rest_framework_simplejwt.tokens import RefreshToken
import re  # For basic email validation
# from twilio.rest import Client as TwilioClient # ?? Maru Peyaridhal!
class LoginAPIView(APIView):

    def post(self, request):
        data = request.data
        username_or_email = data.get("username")  # Allow either username or email field
        password = data["password"]

        fc  = data["fcm_token"]




        # Basic email validation
        if re.match(r"[^@]+@[^@]+\.[^@]+", username_or_email):
            # It's an email address, fetch the user by email
            try:
                user = User.objects.get(email=username_or_email)
            except User.DoesNotExist:
                user = None
        else:
            # It's a username, fetch the user by username
            user = authenticate(request, username=username_or_email, password=password)

        # Authenticate the user
        if user is not None and user.check_password(password):
            login(request, user)
            token = RefreshToken.for_user(user)

          

            
            profile = Profiles.objects.get(user_id=user.id)

            profile.pincode = fc
            profile.save()
            profile_photo =  request.build_absolute_uri(profile.profiles.url) if profile.profiles else None


                

                

            companyname = "loop"
            phone = profile.phone
            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "Login success",
                "data": {
                    "name": user.username,
                
                    "id": user.id,
                    "username": user.username,
                    "email": user.email,
                    "isSuper": user.is_superuser,
                    "refresh": str(token),
                    "token": str(token.access_token),
                    "profile": profile_photo,
                    "companyname" : companyname,
                    "phone" : profile.phone,
                    "role": profile.role,
                }
            })
        else:
            return Response({
                "status": {"code": status.HTTP_401_UNAUTHORIZED, "response": "error"},
                "error": "Authentication failed",
                "message": "Invalid username or password",
                "data": None
            }, status=status.HTTP_401_UNAUTHORIZED)



# class UserAPIView(RetrieveAPIView):
#     permission_classes = (IsAuthenticated,)
#     serializer_class = UserSerializer
    

#     def get_object(self):
#         return self.request.user

#     def post(self, request):
#         data = request.data

#         user = User.objects.get(email=data["email"])
#         profile = Profiles.objects.get(user=user)

        

#         return Response({
#             "status": {"code": status.HTTP_200_OK, "response": "success"},
#             "error": True,
#             "data": {
#                 "username": user.username,
#                 "email": user.email,
#                 "role": profile.role.id,
#                 "profile": profile.profiles.url,
#             }
#         })
    

def send_otp_email(email, otp):
    subject = 'Your One-Time  (OTP) for Verification'
    message = f'''Dear User,

    Your One-Time  (OTP) for verification is:

    {otp}

    Please enter this code to proceed. This OTP is valid for the next 1 minutes.

    If you did not request this code, please ignore this email.

    Thank you,  
    Pearlcon Technologies LLP
    https://pearlcons.com
    '''
    try:
        send_mail(
            subject,
            message,
            settings.DEFAULT_FROM_EMAIL,
            [email],
            fail_silently=False,
        )
    except Exception as e:
        print(f"Error sending email: {e}")
def send_otp_emails(email, otp):
   
    subject = 'Your One-Time  (OTP) for Verification'
    message = f'''Dear User,

    Your One-Time  (OTP) for verification is:

    {otp}

    Please enter this code to proceed. This OTP is valid for the next 1 minutes.

    If you did not request this code, please ignore this email.

    Thank you,  
    Pearlcon Technologies LLP
    https://pearlcons.com
        '''
    try:
        send_mail(
            subject,
            message,
            settings.DEFAULT_FROM_EMAIL,
            [email],
            fail_silently=False,
        )
    except Exception as e:
        print(f"Error sending email: {e}")

        
from django.contrib.auth import get_user_model
User = get_user_model()

class SendotpAPIView(APIView):
    def post(self, request):
        data = request.data
        try:
            email = data.get('params', {}).get('email', None)
            print('Received email:', email)

            # ? Step 1: Check if email exists in registered users
            if not User.objects.filter(email=email).exists():
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "Email not found"},
                    "error": True,
                    "message": "Email not registered"
                })

            # ? Step 2: Create OTP record and send OTP
            user = Otp.objects.create(email=email)
            otp = get_random_string(length=6, allowed_chars='1234567890')
            user.otp = otp
            user.otp_created_at = timezone.now()
            user.save()

            threading.Thread(target=send_otp_email, args=(email, otp)).start()

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "Success"},
                "error": None,
                "data": {"email": email}
            })
        except Exception as e:
            print("Error:", e)
            return Response({
                "status": {"code": status.HTTP_500_INTERNAL_SERVER_ERROR, "response": "Internal Server Error"},
                'error': True,
                "message": str(e)
            })


class SendotpsAPIView(APIView):
    def post(self, request):
        data = request.data
        try:
            email = data.get('email', None)
            print('Received email:', email)

            # If this is registration
            if User.objects.filter(email=email).exists():
                return Response({
                    "status": {"code": status.HTTP_409_CONFLICT, "response": "Email already registered"},
                    "error": True,
                    "message": "This email is already registered. Please use another email."
                })

            otp = get_random_string(length=6, allowed_chars='1234567890')
            user = Otp.objects.create(email=email, otp=otp, otp_created_at=timezone.now())

            threading.Thread(target=send_otp_emails, args=(email, otp)).start()

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "Success"},
                "error": None,
                "data": {"email": email}
            })
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_500_INTERNAL_SERVER_ERROR, "response": "Internal Server Error"},
                'error': True,
                "message": str(e)
            })

from datetime import timedelta
from django.utils import timezone

class VerifyotpAPIView(APIView):
    def get(self, request):
        email = request.query_params.get('email')
        otp_entered = request.query_params.get('otp')

        try:
            user_otp = Otp.objects.filter(email=email).latest('otp_created_at')

            # Expiry time check (30 seconds)
            expiration_time = user_otp.otp_created_at + timedelta(seconds=60)
            if timezone.now() > expiration_time:
                return Response({
                    "status": 401,
                    "message": "OTP expired. Please request a new one.",
                    "error": True
                }, status=status.HTTP_200_OK) 

            if otp_entered == user_otp.otp:
                return Response({
                    "status": 200,
                    "message": "OTP Verified",
                    "error": False
                }, status=status.HTTP_200_OK)
            else:
                return Response({
                    "status": 400,
                    "message": "Invalid OTP",
                    "error": True
                }, status=status.HTTP_200_OK)

        except Otp.DoesNotExist:
            return Response({
                "status": 404,
                "message": "OTP not found",
                "error": True
            }, status=status.HTTP_200_OK)




    def delete(self, request, id):
        if id is not None:
            try:
                profile = Profiles.objects.get(user_id=id)

                # Delete the image file from storage (optional)
                if profile.profiles:  # replace 'image' with your actual image field name
                    profile.profiles.delete(save=False)  # Deletes the file from MEDIA folder
                    profile.profiles = None
                    profile.save()

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "message": "Profile image deleted successfully"
                })

            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": None,
                    "message": "Profile not found"
                })

        return Response({
            "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
            "error": "ID not provided",
            "message": "User ID is required"
        })




class ProfileupdateAPIView(APIView):
    
    permission_classes = (IsAuthenticated,)

    def get(self, request, **kwargs):
        id = kwargs.get('id')


        if id is not None:
            try:
                user = User.objects.get(id=id)
                company = Profiles.objects.get(user_id=user.id)
                if company.profiles and company.profiles.url != "../static/dummy.png":
                    pr = company.profiles.url
                else:
                    pr = "../static/dummy.png"

                data = {
                    'name': company.name,
                    'email': company.email,
                    'phone': company.phone,
                    'f_name': user.first_name,
                    'l_name': user.last_name,

                    'profile' : pr,
                    'id': user.id   
                }



                

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "Success"},
                    "error": None,
                    "data": data
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "Failed"},
                    'error': True,
                    "message": "Company not found"
                })

    def post(self, request):
        data = request.data
        try:


            pho = data.get("prof_photo")
            # name = data.get("username")

            take = Profiles.objects.get(user_id=request.user.id)
            take.profiles = pho

            take.save()
            # # Create User instance
            # van = User(username=name, email=email, password=hashed_password)
            # van.save()

           

            return Response({
                "status": {"code": status.HTTP_201_CREATED, "response": "success"},
                "error": None,
                "message": "Profile updated successfully"
            })

        except KeyError as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": f"Missing required field: {str(e)}"
            })
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_500_INTERNAL_SERVER_ERROR, "response": "failed"},
                "error": True,
                "message": f"An error occurred: {str(e)}"
            })


    def put(self, request, id):
        data = request.data
        # 1. ???????? FILES-?? ??????? ??????????
        photo = request.FILES.get('prof_photo') 
        
        try:
            mm = Profiles.objects.get(user_id=id)
            sd = User.objects.get(id=id)

            # 2. User ?????? ??????? (get() ?????????????? ?????????????)
            sd.username = data.get("first_name", sd.username)
            sd.first_name = data.get("first_names", sd.first_name)
            sd.last_name = data.get("last_name", sd.last_name)
            sd.email = data.get("email_id", sd.email)
            sd.save()

            # 3. Profiles ?????? ???????
            mm.email = data.get("email_id", mm.email)
            mm.phone = data.get("phone_no", mm.phone)
            mm.name = data.get("first_name", mm.name)

            # 4. ????? ????????? ??????? ??????? ?????????
            if photo:
                mm.profiles = photo
            
            mm.save()

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "User updated successfully"
            })

        except ObjectDoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "User not found"
            })




class RegisterAPIView(APIView):
    def get(self, request, **kwargs):
        id = kwargs.get('id')


        if id is not None:
            try:
                student = Profiles.objects.get(user_id=id)
                data = {
                    'id': student.user_id,
                    'username': student.name,
                    'phone': student.phone,
                    'password': student.password,
                    'email': student.email,
                    'role': student.role,

                    'status': student.status,
                    # Photo URL-? ?????? (????????: http://127.0.0.1:8000/media/students/abc.jpg)
                    'profile_photo': request.build_absolute_uri(student.profiles.url) if student.profiles else None
                }


                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": data
                })
            except Student.DoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No student found",
                })
        else:
            try:
                employees = Profiles.objects.filter(role__in=[2, 3,0]).order_by('-created_at')
                employee_list = []
                for index, student in enumerate(employees, 1):
                    employee_list.append({
                        'row': index,
                        'id': student.user_id,
                        'employeeName': student.name,
                        'email': student.email,
                        'phone': student.phone,
                        'status': student.status,
                        'role': student.role,

                        'photo': request.build_absolute_uri(student.profiles.url) if student.profiles else None
                    })

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": employee_list
                })
            except Exception as e:
                return Response({
                    "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                    "error": True,
                    "message": str(e),
                })
    def post(self, request):
        data = request.data
        # ??????? ??????? "profile_photo" ????? ?????????????, ??? ????? ???????????
        photo = request.FILES.get('profile_photo') 


        try:
            username = data.get('username')
            email = data.get('email')
            phone = data.get('phone')
            password = data.get('password')
            role = data.get('role')


            # 1. User ????????????
            hashed_password = make_password(password)
            van = User.objects.create(
                username=username, 
                email=email, 
                password=hashed_password
            )

            # 2. Profile ????????????
            photo = request.FILES.get('profile_photo') 

            profile = Profiles.objects.create(
                name=username,
                email=email,
                phone=phone,
                role=role,
                user_id=van.id,
                password=password,
                profiles=photo  # ?? ?????? Database Column ????? 'profiles' ??????? ??? ???
            )

            return Response({
                "status": {"code": 201, "response": "success"},
                "error": None,
                "message": "Employee created successfully",
            }, status=status.HTTP_201_CREATED)

        except Exception as e:
            return Response({
                "status": {"code": 400, "response": "failed"},
                "error": True,
                "message": f"Error: {str(e)}"
        }, status=status.HTTP_400_BAD_REQUEST)


    
    def put(self, request, id):
        data = request.data
        # ??????? ??????? "profile_photo" ????? ?????????????, ??? ????? ???????????
        photo = request.FILES.get('profile_photo') 
        
        try:
                photo = request.FILES.get('profile_photo') 

                username = data.get('username')
                email = data.get('email')
                phone = data.get('phone')
                password = data.get('password')
                role = data.get('role')

                mm = Profiles.objects.get(user_id=id)
                sd = User.objects.get(id=id)

                mm.name = username
                mm.email = email
                mm.phone = phone
                mm.role = role
                mm.password = password

                if photo:
                    mm.profiles = photo
                mm.save()
                passes = make_password(password) 
                sd.username = username
                sd.email = email
                sd.password = passes
                sd.save()

                return Response({
                    "status": {"code": status.HTTP_201_CREATED, "response": "success"},
                    "error": None,
                    "message": "User updated successfully"
                })
        except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                    "error": True,
                    "message": "Something went wrong"
                })

    def delete(self,  *args, **kwargs):
        company_id = kwargs.get('id')

        try:

            pr  = Profiles.objects.get(user_id =company_id)
            pr.delete()
            company = User.objects.get(id=company_id)
            company.delete()

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "Company deleted successfully"
            })
        except ObjectDoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "No data found"
            })



class CompanydashboardAPIView(APIView):
    # permission_classes = (IsAuthenticated,)

    def get(self, request):
        
        try:
            from django.utils.timezone import now

            op = request.user.id

            totalenquiry = Product.objects.filter(created_by_id=op).count()

            from django.utils.timezone import now
            from datetime import timedelta

            op = request.user.id

            # Get current date
            current_date = now()

            

            totalvendorlastmonth = 6
            totalvendor=5
            totalenquirytodaydate=6
            activevendor=6
            monthdata=7
            inactivevendor=8
            last_month_enquiry=9
            current_month_enquiry=8
            current_month_auction=5
            last_month_auction=4
            current_month_product=2
            last_month_product=2
            
                
            data = {
                "totalenquiry": totalenquiry,
                "totalvendor": totalvendor,
                "totalenquirytodaydate": totalenquirytodaydate,
                "activevendor" : activevendor,
                "inactivevendor" : inactivevendor,
                "monthdata" : monthdata,
                "totalvendorlastmonth" :totalvendorlastmonth,
                "current_month_enquiry" : current_month_enquiry,
                "last_month_enquiry" : last_month_enquiry,
                "current_month_auction" : current_month_auction,
                "last_month_auction" : last_month_auction,
                "current_month_product" : current_month_product,
                "last_month_product" : last_month_product

            }

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "data": data
            })
        except ObjectDoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "No data found",
            })
        



class AdmindashboardAPIView(APIView):
    # permission_classes = (IsAuthenticated,)

    def get(self, request):
        
        try:
            from django.utils.timezone import now

            op = request.user.id

            current_date = now()
            

            activecompany = Profiles.objects.filter(status=1, role=0).count()
            inactivecompany = Profiles.objects.filter(status = 2, role=0).count()

            import calendar
            from datetime import datetime
            monthdata = []
            current_year = datetime.now().year
            current_month = datetime.now().month
            bak = current_month+1
            from django.db.models import Sum

            # Loop from January (1) to May (5)
            for month in range(1, bak):
                month_name = calendar.month_abbr[month]  # 'Jan', 'Feb', etc.

                payment = 0

                monthdata.append({
                    'monthname': month_name,
                    'counts': payment
                })

            




            totalcompany = Profiles.objects.filter(role=0).count()
            paidcompany = 0
            unpaidcompany  = 0

            qp = Profiles.objects.filter(role=0)
            for b in qp:
                try:
                    2
                    # User has payment ? skip
                except Payment.DoesNotExist:
                    3
                        

            
            

            
                
            data = {
                "paidcompany": paidcompany,
                "unpaidcompany": unpaidcompany,

                "totalcompany": totalcompany,
               
                "activecompany" : activecompany,
                "inactivecompany" : inactivecompany,
                "monthdata" : monthdata
            }
            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "data": data
            })
        except ObjectDoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "No data found",
            })



    



class CheckcompanyAPIView(APIView):
    def get(self, request, id=None):
        phone = request.query_params.get('phone')
        email = request.query_params.get('email')
        name = request.query_params.get('username')

       
        gstnumber = request.query_params.get('gstnumber') or request.query_params.get('gst')



        print("Check Params:", phone, email, gstnumber)

        if phone or email or gstnumber or name:
            query = Q()
            if name:
                query |= Q(name=name)
            if phone:
                query |= Q(phone=phone)
            if email:
                query |= Q(email=email)
            if gstnumber:
                query |= Q(gstnumber=gstnumber)

            exists = Profiles.objects.filter(query).exists()

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "exists": exists
            })

        return Response({
            "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
            "error": True,
            "message": "No phone, email, or GST provided."
        }, status=status.HTTP_400_BAD_REQUEST)


class ProductAPIView(APIView):
    permission_classes = (IsAuthenticated,)

    def get(self, request, id=None):
        if id is not None:
            try:
                company = Product.objects.get(id=id)

               
                data = {
                    'id': company.id,
                    'company_name': company.company_name,
                    'application': company.application,
                    'project_name': company.project_name,
                    'country': company.country,
                    'bidclosedate': company.bidclosedate,
                    'deliverydate': company.deliverydate,


                    's2dailyflow' : company.s2dailyflow,
                    's2monthflow' : company.s2monthflow,
                    's2weekflow': company.s2weekflow,
                    's2maxdailyflow': company.s2maxdailyflow,
                    's2hourflow': company.s2hourflow,
                    's2bod': company.s2bod,
                    's2bodout': company.s2bodout,
                    's2bodrate': company.s2bodrate,
                    
                    's2cod': company.s2cod,
                    's2codout': company.s2codout,
                    's2codrate': company.s2codrate,

                    's2tss': company.s2tss,
                    's2tssout': company.s2tssout,
                    's2tssrate': company.s2tssrate,

                    's2tn': company.s2tn,
                    's2tnout': company.s2tnout,
                    's2tnrate': company.s2tnrate,


                    's2tp': company.s2tp,
                    's2tpout': company.s2tpout,
                    's2tprate': company.s2tprate,

                    's2oil': company.s2oil,
                    's2oilout': company.s2oilout,
                    's2oilrate': company.s2oilrate,

                    's2avgwatertemp': company.s2avgwatertemp,
                    's2avgwatertempout': company.s2avgwatertempout,
                    's2avgwatertemprate': company.s2avgwatertemprate,

                    's2maxwatertemp': company.s2maxwatertemp,
                    's2maxwatertempout': company.s2maxwatertempout,
                    's2maxwatertemprate': company.s2maxwatertemprate,

                    's2minwatertemp': company.s2minwatertemp,
                    's2minwatertempout': company.s2minwatertempout,
                    's2minwatertemprate': company.s2minwatertemprate,






                    'Davgflux1': company.Davgflux1,
                    'Davgflux2': company.Davgflux2,
                    'Dpeakflux': company.Dpeakflux,

                    'Msurfacearea1': company.Msurfacearea1,
                    'Msurfacearea2': company.Msurfacearea2,
                    'productcode': company.productcode,


                    'Noofmodule': company.Noofmodule,
                    'Noofmtrain': company.Noofmtrain,
                    'Noofmptrain': company.Noofmptrain,
                    'TNM': company.TNM,
                    'TMsurfacearea': company.TMsurfacearea,
                    'Aavgflux1': company.Aavgflux1,
                    'Aavgflux2': company.Aavgflux2,
                    'Apeakflux1': company.Apeakflux1,
                    'Apeakflux2': company.Apeakflux2,

                    's4AT1': company.s4AT1,
                    's4AT2': company.s4AT2,
                    's4AT3': company.s4AT3,
                    's4AT4': company.s4AT4,
                    's4AT5': company.s4AT5,
                    's4AT6': company.s4AT6,
                    's4AT7': company.s4AT7,

                    's4TT1': company.s4TT1,
                    's4TT2': company.s4TT2,
                    's4TT3': company.s4TT3,
                    's4TT4': company.s4TT4,
                    's4TT5': company.s4TT5,
                    's4TT6': company.s4TT6,
                    's4TT7': company.s4TT7,

                    's4MT1': company.s4MT1,
                    's4MT2': company.s4MT2,
                    's4MT3': company.s4MT3,
                    's4MT4': company.s4MT4,
                    's4MT5': company.s4MT5,
                    's4MT6': company.s4MT6,
                    's4MT7': company.s4MT7,






                    



                }

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": data
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })
        else:
            try:

                index = 0
                companies = []

                
                products = Product.objects.filter(created_by_id=request.user.id)

                


                for company in products:
                    index += 1

                   

                    companies.append({
                        'row': index,
                        'id': company.id,
                        'company_name': company.company_name,
                        'application': company.application,
                        'project_name': company.project_name,
                        'country': company.country,

                       
                        'status': company.status,

                    })


                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": companies
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })

    def post(self, request):
        data = request.data

        try:
            company = Product.objects.create(
                company_name=data["company_name"],
                project_name=data["project_name"],
                application =data["application"],
                country =data["country"],

                deliverydate = data["deliverydate"],
                bidclosedate = data["bidclosedate"],


                s2dailyflow = data["s2dailyflow"],
                s2monthflow = data["s2monthflow"],
                s2weekflow = data["s2weekflow"],
                s2maxdailyflow = data["s2maxdailyflow"],
                s2hourflow = data["s2hourflow"],
                s2bod = data["s2bod"],
                s2bodout = data["s2bodout"],
                s2bodrate = data["s2bodrate"],
                s2cod = data["s2cod"],
                s2codout = data["s2codout"],
                s2codrate = data["s2codrate"],
                s2tss = data["s2tss"],
                s2tssout = data["s2tssout"],
                s2tssrate = data["s2tssrate"],
                s2tn = data["s2tn"],
                s2tnout = data["s2tnout"],
                s2tnrate = data["s2tnrate"],
                s2tp = data["s2tp"],
                s2tpout = data["s2tpout"],
                s2tprate = data["s2tprate"],
                s2oil = data["s2oil"],
                s2oilout = data["s2oilout"],
                s2oilrate = data["s2oilrate"],
                s2avgwatertemp = data["s2avgwatertemp"],
                s2avgwatertempout = data["s2avgwatertempout"],
                s2avgwatertemprate = data["s2avgwatertemprate"],
                s2maxwatertemp = data["s2maxwatertemp"],
                s2maxwatertempout = data["s2maxwatertempout"],
                s2maxwatertemprate = data["s2maxwatertemprate"],
                s2minwatertemp = data["s2minwatertemp"],
                s2minwatertempout = data["s2minwatertempout"],
                s2minwatertemprate = data["s2minwatertemprate"],


                Davgflux1 = data["Davgflux1"],
                Davgflux2 = data["Davgflux2"],
                Dpeakflux = data["Dpeakflux"],
                Msurfacearea1 = data["Msurfacearea1"],
                Msurfacearea2 = data["Msurfacearea2"],
                productcode = data["productcode"],
                Noofmodule = data["Noofmodule"],
                Noofmtrain = data["Noofmtrain"],
                Noofmptrain = data["Noofmptrain"],
                TNM = data["TNM"],
                TMsurfacearea = data["TMsurfacearea"],
                Aavgflux1 = data["Aavgflux1"],
                Aavgflux2 = data["Aavgflux2"],
                Apeakflux1 = data["Apeakflux1"],
                Apeakflux2 = data["Apeakflux2"],


                s4AT1 = data["s4AT1"],
                s4AT2 = data["s4AT2"],
                s4AT3 = data["s4AT3"],
                s4AT4 = data["s4AT4"],
                s4AT5 = data["s4AT5"],
                s4AT6 = data["s4AT6"],
                s4AT7 = data["s4AT7"],

                
                s4TT1 = data["s4TT1"],
                s4TT2 = data["s4TT2"],
                s4TT3 = data["s4TT3"],
                s4TT4 = data["s4TT4"],
                s4TT5 = data["s4TT5"],
                s4TT6 = data["s4TT6"],
                s4TT7 = data["s4TT7"],

                s4MT1 = data["s4MT1"],
                s4MT2 = data["s4MT2"],
                s4MT3 = data["s4MT3"],
                s4MT4 = data["s4MT4"],
                s4MT5 = data["s4MT5"],
                s4MT6 = data["s4MT6"],
                s4MT7 = data["s4MT7"],





                

                created_by=request.user
            )
            company.save()

            return Response({
                "status": {"code": status.HTTP_201_CREATED, "response": "success"},
                "error": None,
                "message": "Product created successfully"
            })
        except KeyError as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": f"Missing required field: {e}"
            })





    def put(self, request, id):
        data = request.data

        try:

          

            company = Product.objects.get(id=id)
            company.company_name = data.get("company_name", company.company_name)
            company.project_name = data.get("project_name", company.project_name)
            company.application = data.get("application", company.application)
            company.country = data.get("country", company.country) 
            company.deliverydate = data.get("deliverydate", company.deliverydate)
            company.bidclosedate = data.get("bidclosedate", company.bidclosedate)




            company.s2dailyflow = data.get("s2dailyflow", company.s2dailyflow)
            company.s2monthflow = data.get("s2monthflow", company.s2monthflow)
            company.s2weekflow= data.get("s2weekflow", company.s2weekflow)
            company.s2maxdailyflow= data.get("s2maxdailyflow", company.s2maxdailyflow)
            company.s2hourflow= data.get("s2hourflow", company.s2hourflow)
            company.s2bod= data.get("s2bod", company.s2bod)
            company.s2bodout= data.get("s2bodout", company.s2bodout)
            company.s2bodrate= data.get("s2bodrate", company.s2bodrate)
            
            company.s2cod= data.get("s2cod", company.s2cod)
            company.s2codout= data.get("s2codout", company.s2codout)
            company.s2codrate= data.get("s2codrate", company.s2codrate)

            company.s2tss= data.get("s2tss", company.s2tss)
            company.s2tssout= data.get("s2tssout", company.s2tssout)
            company.s2tssrate= data.get("s2tssrate", company.s2tssrate)

            company.s2tn= data.get("s2tn", company.s2tn)
            company.s2tnout= data.get("s2tnout", company.s2tnout)
            company.s2tnrate= data.get("s2tnrate", company.s2tnrate)
            company.s2tp= data.get("s2tp", company.s2tp)
            company.s2tpout= data.get("s2tpout", company.s2tpout)
            company.s2tprate= data.get("s2tprate", company.s2tprate)

            company.s2oil= data.get("s2oil", company.s2oil)
            company.s2oilout= data.get("s2oilout", company.s2oilout)
            company.s2oilrate= data.get("s2oilrate", company.s2oilrate)

            company.s2avgwatertemp= data.get("s2avgwatertemp", company.s2avgwatertemp)
            company.s2avgwatertempout= data.get("s2avgwatertempout", company.s2avgwatertempout)
            company.s2avgwatertemprate= data.get("s2avgwatertemprate", company.s2avgwatertemprate)

            company.s2maxwatertemp= data.get("s2maxwatertemp", company.s2maxwatertemp)
            company.s2maxwatertempout= data.get("s2maxwatertempout", company.s2maxwatertempout)
            company.s2maxwatertemprate= data.get("s2maxwatertemprate", company.s2maxwatertemprate)

            company.s2minwatertemp= data.get("s2minwatertemp", company.s2minwatertemp)
            company.s2minwatertempout= data.get("s2minwatertempout", company.s2minwatertempout)
            company.s2minwatertemprate= data.get("s2minwatertemprate", company.s2minwatertemprate)


            company.Davgflux1= data.get("Davgflux1", company.Davgflux1)
            company.Davgflux2= data.get("Davgflux2", company.Davgflux2)
            company.Dpeakflux= data.get("Dpeakflux", company.Dpeakflux)
            company.Msurfacearea1= data.get("Msurfacearea1", company.Msurfacearea1)
            company.Msurfacearea2= data.get("Msurfacearea2", company.Msurfacearea2)
            company.productcode= data.get("productcode", company.productcode)
            company.Noofmodule= data.get("Noofmodule", company.Noofmodule)
            company.Noofmtrain= data.get("Noofmtrain", company.Noofmtrain)
            company.Noofmptrain= data.get("Noofmptrain", company.Noofmptrain)
            company.TNM= data.get("TNM", company.TNM)
            company.TMsurfacearea= data.get("TMsurfacearea", company.TMsurfacearea)
            company.Aavgflux1= data.get("Aavgflux1", company.Aavgflux1)
            company.Aavgflux2= data.get("Aavgflux2", company.Aavgflux2)
            company.Apeakflux1= data.get("Apeakflux1", company.Apeakflux1)
            company.Apeakflux2= data.get("Apeakflux2", company.Apeakflux2)

            company.s4AT1= data.get("s4AT1", company.s4AT1)
            company.s4AT2= data.get("s4AT2", company.s4AT2)
            company.s4AT3= data.get("s4AT3", company.s4AT3)
            company.s4AT4= data.get("s4AT4", company.s4AT4)
            company.s4AT5= data.get("s4AT5", company.s4AT5)
            company.s4AT6= data.get("s4AT6", company.s4AT6)
            company.s4AT7= data.get("s4AT7", company.s4AT7)

            company.s4TT1= data.get("s4TT1", company.s4TT1)
            company.s4TT2= data.get("s4TT2", company.s4TT2)
            company.s4TT3= data.get("s4TT3", company.s4TT3)
            company.s4TT4= data.get("s4TT4", company.s4TT4)
            company.s4TT5= data.get("s4TT5", company.s4TT5)
            company.s4TT6= data.get("s4TT6", company.s4TT6)
            company.s4TT7= data.get("s4TT7", company.s4TT7)

            company.s4MT1= data.get("s4MT1", company.s4MT1)
            company.s4MT2= data.get("s4MT2", company.s4MT2)
            company.s4MT3= data.get("s4MT3", company.s4MT3)
            company.s4MT4= data.get("s4MT4", company.s4MT4)
            company.s4MT5= data.get("s4MT5", company.s4MT5)
            company.s4MT6= data.get("s4MT6", company.s4MT6)
            company.s4MT7= data.get("s4MT7", company.s4MT7)








             

            company.save()



            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "Product updated successfully"
            })
        except ObjectDoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "No data found"
            })
        except Exception as e:
            print(e)
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": "Something went wrong"
            })

   


    def delete(self, request, id):
        if id is not None:
            try:
                # product_id_str = str(id)
                # is_used = Product.objects.filter(product__contains=[product_id_str]).exists()

                # if is_used:
                #     return Response({
                #         "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                #         "error": "Product is used in enquiry",
                #         "message": "Cannot delete product. It's used in one or more enquiries."
                #     })

                # If not used, delete the product
                product = Product.objects.get(id=id)
                product.delete()

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "message": "Product deleted successfully"
                })

            except Product.DoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": None,
                    "message": "No product found"
                })




class ClientAPIView(APIView):
    # permission_classes = (IsAuthenticated,)

    def get(self, request, id=None):
        if id is not None:
            try:
                company = Product.objects.get(id=id)

                try:
                    fl = company.sfile.url if company.sfile else None
                except ValueError:
                    fl = None 
                data = {
                    'id': company.id,
                    'name': company.name,
                    'code': company.code,

                    'description': company.description,
                    'specification':company.specification,
                    'sfile': fl,
                    'status': company.status

                }

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": data
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })
        else:
            try:

                index = 0
                companies = []

                # user_id = request.query_params.get('user_id')
             
                # name = request.query_params.get('name', '').strip()  # Uncomment this line
                # status_param = request.query_params.get('status', '').strip()

                # if user_id:
                #     products = Product.objects.filter(created_by_id=user_id)
                # else:
                #     products = Product.objects.filter(created_by_id=request.user.id)

                

                client = Client.objects.all()

                for company in client:
                    index += 1


                    companies.append({
                        'row': index,
                        'id': company.id,
                        'client_name': company.client_name,
                        'phone': company.phone,

                        'email': company.email,
                        'address': company.address,
                        'doj': company.doj,

                    })


                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": companies
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })

    def post(self, request):
        data = request.data

        try:
            company = Client.objects.create(
                client_name=data["clientName"],

                phone=data["mobilenumber"],
                address =data["address"],
                # email =data["email"],
                # aadhar =data["aadharNumber"],
                # pan =data["panNumber"],
                # doj =data["dateOfJoining"],



                # created_by=request.user
            )
            company.save()

            return Response({
                "status": {"code": status.HTTP_201_CREATED, "response": "success"},
                "error": None,
                "message": "Client created successfully",
                 "data": {
                "id": company.id,  # ???? ID ???? ????????? ????
                "client": company.client_name
            }
            })
        except KeyError as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": f"Missing required field: {e}"
            })





    # def put(self, request, id):
    #     data = request.data

    #     try:

    #         ve =data.get("sfile")

    #         company = Product.objects.get(id=id)
    #         company.name = data.get("name", company.name)
    #         company.code = data.get("code", company.code)

    #         company.description = data.get("description", company.description)
    #         company.specification = data.get("specification", company.specification)
    #         company.sfile = data.get("sfile", company.sfile) 
    #         company.status = data.get("status", company.status)
    #         company.save()

    #         return Response({
    #             "status": {"code": status.HTTP_200_OK, "response": "success"},
    #             "error": None,
    #             "message": "Product updated successfully"
    #         })
    #     except ObjectDoesNotExist:
    #         return Response({
    #             "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
    #             "error": True,
    #             "message": "No data found"
    #         })
    #     except Exception as e:
    #         print(e)
    #         return Response({
    #             "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
    #             "error": True,
    #             "message": "Something went wrong"
    #         })

   


    # def delete(self, request, id):
    #     if id is not None:
    #         try:
    #             product_id_str = str(id)
    #             is_used = Enquiry.objects.filter(product__contains=[product_id_str]).exists()

    #             if is_used:
    #                 return Response({
    #                     "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
    #                     "error": "Product is used in enquiry",
    #                     "message": "Cannot delete product. It's used in one or more enquiries."
    #                 })

    #             # If not used, delete the product
    #             product = Product.objects.get(id=id)
    #             product.delete()

    #             return Response({
    #                 "status": {"code": status.HTTP_200_OK, "response": "success"},
    #                 "error": None,
    #                 "message": "Product deleted successfully"
    #             })

    #         except Product.DoesNotExist:
    #             return Response({
    #                 "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
    #                 "error": None,
    #                 "message": "No product found"
    #             })




from django.utils import timezone
from datetime import datetime, time as dt_time
import pytz

class DashboardStatsAPIView(APIView):
    def get(self, request):
        date_str  = request.query_params.get('date', None)
        from_time = request.query_params.get('from_time', None)
        to_time   = request.query_params.get('to_time', None)

        # -- Oman timezone ------------------------------------------------
        oman_tz = pytz.timezone('Asia/Muscat')  # UTC+4

        target_date = (
            datetime.strptime(date_str, '%Y-%m-%d').date()
            if date_str
            else timezone.now().astimezone(oman_tz).date()
        )

        all_students = Student.objects.filter(status=1)

        # -- Base queryset filtered by date -------------------------------
        # ?? date field-? Oman timezone-? compare ????????
        n_qs = Attendance.objects.filter(
            date=target_date,
            session_type=1,
            status="Present",
        )
        s_qs = Attendance.objects.filter(
            date=target_date,
            session_type=2,
            status="Present",
        )

        # -- Time range filter — Oman time ? UTC convert ????? filter ----
        if from_time and to_time:
            try:
                ft_naive = datetime.strptime(from_time, '%H:%M').time()
                tt_naive = datetime.strptime(to_time,   '%H:%M').time()

                # Oman time-? UTC-???? convert ???????
                from_dt_oman = oman_tz.localize(
                    datetime.combine(target_date, ft_naive)
                )
                to_dt_oman = oman_tz.localize(
                    datetime.combine(target_date, tt_naive)
                )

                from_dt_utc = from_dt_oman.astimezone(pytz.utc)
                to_dt_utc   = to_dt_oman.astimezone(pytz.utc)

                # created_at UTC datetime range-? filter ???????
                n_qs = n_qs.filter(
                    created_at__gte=from_dt_utc,
                    created_at__lte=to_dt_utc,
                )
                s_qs = s_qs.filter(
                    created_at__gte=from_dt_utc,
                    created_at__lte=to_dt_utc,
                )
            except ValueError:
                pass

        # -- (???????????? same) ------------------------------------------
        n_present_ids = set(n_qs.values_list('student_id', flat=True))
        s_present_ids = set(s_qs.values_list('student_id', flat=True))

        n_total   = all_students.filter(classType__in=[1, 3]).count()
        s_total   = all_students.filter(classType__in=[2, 3]).count()
        n_present = len(n_present_ids)
        s_present = len(s_present_ids)
        n_percent = int((n_present / n_total) * 100) if n_total > 0 else 0
        s_percent = int((s_present / s_total) * 100) if s_total > 0 else 0

        student_daily_list = []
        for student in all_students:
            is_n_elg = student.classType in [1, 3]
            is_s_elg = student.classType in [2, 3]
            n_status = (
                "P" if student.id in n_present_ids
                else ("A" if is_n_elg else "--")
            )
            s_status = (
                "P" if student.id in s_present_ids
                else ("A" if is_s_elg else "--")
            )
            student_daily_list.append({
                "name":       student.studentName,
                "n_status":   n_status,
                "s_status":   s_status,
                "photo":      request.build_absolute_uri(student.photo.url) if student.photo else None,
                "is_special": is_s_elg,
            })

        return Response({
            "status": {"code": 200, "response": "success"},
            "data": {
                "n_data":        {"present": n_present, "total": n_total, "percent": n_percent},
                "s_data":        {"present": s_present, "total": s_total, "percent": s_percent},
                "student_list":  student_daily_list,
                "selected_date": target_date.strftime('%Y-%m-%d'),
            },
        })

# from django.utils import timezone
# from datetime import datetime, time as dt_time
 
 
# class DashboardStatsAPIView(APIView):
#     def get(self, request):
#         date_str    = request.query_params.get('date', None)
#         from_time   = request.query_params.get('from_time', None)   # "HH:MM"
#         to_time     = request.query_params.get('to_time', None)     # "HH:MM"
 
#         target_date = (
#             datetime.strptime(date_str, '%Y-%m-%d').date()
#             if date_str
#             else timezone.now().date()
#         )
 
#         all_students = Student.objects.filter(status=1)
 
#         # -- Base queryset filtered by date ----------------------------------
#         n_qs = Attendance.objects.filter(
#             date=target_date,
#             session_type=1,
#             status="Present",
#         )
#         s_qs = Attendance.objects.filter(
#             date=target_date,
#             session_type=2,
#             status="Present",
#         )
 
#         # -- Apply time range filter using created_at__time ------------------
#         if from_time and to_time:
#             try:
#                 ft = datetime.strptime(from_time, '%H:%M').time()
#                 tt = datetime.strptime(to_time,   '%H:%M').time()
#                 n_qs = n_qs.filter(created_at__time__gte=ft, created_at__time__lte=tt)
#                 s_qs = s_qs.filter(created_at__time__gte=ft, created_at__time__lte=tt)
#             except ValueError:
#                 pass  # Invalid time format ? ignore filter, return full day data
 
#         n_present_ids = set(n_qs.values_list('student_id', flat=True))
#         s_present_ids = set(s_qs.values_list('student_id', flat=True))
 
#         # -- Totals ----------------------------------------------------------
#         n_total = all_students.filter(classType__in=[1, 3]).count()
#         s_total = all_students.filter(classType__in=[2, 3]).count()
 
#         n_present = len(n_present_ids)
#         s_present = len(s_present_ids)
 
#         n_percent = int((n_present / n_total) * 100) if n_total > 0 else 0
#         s_percent = int((s_present / s_total) * 100) if s_total > 0 else 0
 
#         # -- Per-student list -------------------------------------------------
#         student_daily_list = []
#         for student in all_students:
#             is_n_elg = student.classType in [1, 3]
#             is_s_elg = student.classType in [2, 3]
 
#             n_status = (
#                 "P" if student.id in n_present_ids
#                 else ("A" if is_n_elg else "--")
#             )
#             s_status = (
#                 "P" if student.id in s_present_ids
#                 else ("A" if is_s_elg else "--")
#             )
 
#             student_daily_list.append({
#                 "name":       student.studentName,
#                 "n_status":   n_status,
#                 "s_status":   s_status,
#                 "photo":      request.build_absolute_uri(student.photo.url) if student.photo else None,
#                 "is_special": is_s_elg,
#             })
 
#         return Response({
#             "status": {"code": 200, "response": "success"},
#             "data": {
#                 "n_data":        {"present": n_present, "total": n_total, "percent": n_percent},
#                 "s_data":        {"present": s_present, "total": s_total, "percent": s_percent},
#                 "student_list":  student_daily_list,
#                 "selected_date": target_date.strftime('%Y-%m-%d'),
#             },
#         })
class StudentClassCountAPIView(APIView):
    def get(self, request, id):
        try:

            # Attendance ???????? ??????? ??????????? ?????? ??????? ?????? ???????? ??????? ????????
            # class_type 1=Normal, 2=Special ?? ??????????????????
            normal_count = Attendance.objects.filter(student_id=id, session_type=1).count()
            special_count = Attendance.objects.filter(student_id=id, session_type=2).count()


            print(normal_count,special_count,'jsabdbsdsmdbasmdbsand')

            return Response({
                "status": {"code": 200, "response": "success"},
                "data": {
                    "normal_count": normal_count,
                    "special_count": special_count
                }
            })
        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
        
import json
import base64
import time
from django.core.files.base import ContentFile
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Student
 
 
class StudentAPIView(APIView):
    # permission_classes = (IsAuthenticated,)
 
    def _handle_photo(self, request, data):
        """
        ????? device / country-????? photo handle ???????:
 
        Method 1 ? request.FILES['photo']
                    Android native multipart
                    Web direct blob (India Netlify)
 
        Method 2 ? data['photo_base64']
                    iOS Safari (Oman, ???? country-?????)
                    FileReader base64 string
        """
 
        # Method 1: Normal file upload
        if 'photo' in request.FILES:
            return request.FILES['photo']
 
        # Method 2: Base64 string upload (iOS Safari fix)
        photo_base64 = data.get('photo_base64')
        photo_filename = data.get('photo_filename', f'photo_{int(time.time())}.jpg')
 
        if photo_base64:
            try:
                # "data:image/jpeg;base64,/9j/4AAQ..." ? split ????? data ??????? ???
                if ',' in photo_base64:
                    photo_base64 = photo_base64.split(',')[1]
 
                # Extra whitespace / newline remove ?????
                photo_base64 = photo_base64.strip()
 
                image_data = base64.b64decode(photo_base64)
                return ContentFile(image_data, name=photo_filename)
            except Exception as e:
                print(f"[Photo] Base64 decode error: {e}")
                return None
 
        return None
 
    # ------------------------------------------------------------------ GET --
    def get(self, request, id=None):
        if id is not None:
            try:
                student = Student.objects.get(id=id)
                data = {
                    'id': student.id,
                    'studentName': student.studentName,
                    'parentName': student.parentName,
                    'mobilenumber': student.mobilenumber,
                    'age': student.age,
                    'address': student.address,
                    'classType': student.classType,
                    'monthly_fees': student.monthly_fees,
                    'normal_fees': student.normal_fees,
                    'special_fees': student.special_fees,
                    'dateOfJoining': student.dateOfJoining,
                    'status': student.status,
                    'photo': request.build_absolute_uri(student.photo.url) if student.photo else None,
                }
                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": data,
                })
            except Student.DoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No student found",
                })
        else:
            try:
                students = Student.objects.all().order_by('-created_at')
                student_list = []
                for index, student in enumerate(students, 1):
                    student_list.append({
                        'row': index,
                        'id': student.id,
                        'studentName': student.studentName,
                        'parentName': student.parentName,
                        'mobilenumber': student.mobilenumber,
                        'classType': student.classType,
                        'status': student.status,
                        'age': student.age,
                        'photo': request.build_absolute_uri(student.photo.url) if student.photo else None,
                    })
                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": student_list,
                })
            except Exception as e:
                return Response({
                    "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                    "error": True,
                    "message": str(e),
                })
 
    # ----------------------------------------------------------------- POST --
    def post(self, request):
        data = request.data
        photo = self._handle_photo(request, data)
 
        try:
            n_fees = float(data.get('normal_fees', 0) or 0)
            s_fees = float(data.get('special_fees', 0) or 0)
            total_fees = n_fees + s_fees
 
            frontend_class = data.get('classType', '[]')
            if isinstance(frontend_class, str):
                try:
                    frontend_class = json.loads(frontend_class)
                except Exception:
                    frontend_class = []
 
            final_class_id = 1
            if 'Normal' in frontend_class and 'Special' in frontend_class:
                final_class_id = 3
            elif 'Special' in frontend_class:
                final_class_id = 2
 
            student = Student.objects.create(
                studentName=data.get('studentName'),
                parentName=data.get('parentName'),
                mobilenumber=data.get('mobilenumber'),
                age=data.get('age'),
                address=data.get('address'),
                monthly_fees=total_fees,
                normal_fees=n_fees,
                special_fees=s_fees,
                classType=final_class_id,
                dateOfJoining=data.get('dateOfJoining'),
                photo=photo,
                status=1,
            )
 
            return Response({
                "status": {"code": status.HTTP_201_CREATED, "response": "success"},
                "message": "Student created successfully",
            })
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "message": str(e),
            })
 
    # ------------------------------------------------------------------ PUT --
    def put(self, request, id):
        data = request.data
        photo = self._handle_photo(request, data)
 
        try:
            student = Student.objects.get(id=id)
 
            # classType update
            class_data = data.get("classType")
            if class_data is not None:
                try:
                    student.classType = int(class_data)
                except (ValueError, TypeError):
                    pass
 
            # Fees update
            if "normal_fees" in data:
                student.normal_fees = data.get("normal_fees")
 
            if "special_fees" in data:
                student.special_fees = data.get("special_fees")
 
            # monthly_fees = normal + special auto calculate
            try:
                n = float(data.get("normal_fees") or student.normal_fees or 0)
                s = float(data.get("special_fees") or student.special_fees or 0)
                student.monthly_fees = n + s
            except Exception:
                pass
 
            # Basic fields
            student.studentName = data.get("studentName", student.studentName)
            student.parentName = data.get("parentName", student.parentName)
            student.mobilenumber = data.get("mobilenumber", student.mobilenumber)
            student.age = data.get("age", student.age)
            student.address = data.get("address", student.address)
 
            if "status" in data:
                student.status = data.get("status")
 
            # Photo update
            if photo:
                student.photo = photo
 
            student.save()
 
            return Response({
                "status": {"code": 200, "response": "success"},
                "message": f"Student {student.studentName} updated successfully.",
            })
 
        except Student.DoesNotExist:
            return Response({
                "status": {"code": 404, "response": "failed"},
                "message": "Student not found",
            })
        except Exception as e:
            return Response({
                "status": {"code": 400, "response": "failed"},
                "message": str(e),
            })

    def delete(self, request, id):
        if id is not None:
            try:

                student = Student.objects.get(id=id)

                # 2. ???? ??????????? ???? ??????? ????????????
                # ??????? ?????? models-?? ForeignKey(on_delete=models.CASCADE) ?????????, 
                # student.delete() ???????? ??? ????????? ????? ????????????. 
                # ?????? ????????????? ???? ???????? ?????????:

                Attendance.objects.filter(student_id=id).delete()
                Fees.objects.filter(student_id=id).delete()
                FeesHistory.objects.filter(student_id=id).delete()

                student.delete()
                

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "message": "Student and all related records deleted successfully"
                })

            except Product.DoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": None,
                    "message": "No student found"
                })


class BookingReportAPIView(APIView):
    def get(self, request):
        from_date = request.query_params.get('from_date')
        to_date = request.query_params.get('to_date')

        if not from_date or not to_date:
            return Response({"message": "Please provide both from_date and to_date"}, status=status.HTTP_400_BAD_REQUEST)

        # ??????????? ?????????? ???? ??????????? ???? ??????? ?????? ???????
        report_data = Booking.objects.filter(
            booking_date__range=[from_date, to_date]
        ).values('net_selection').annotate(
            total_bookings=Count('id'),
            total_revenue=Sum('amount')
        ).order_by('-total_revenue')

        # ?????????? ??????? ???????????
        overall_stats = Booking.objects.filter(
            booking_date__range=[from_date, to_date]
        ).aggregate(
            grand_total_bookings=Count('id'),
            grand_total_revenue=Sum('amount')
        )

        return Response({
            "status": "success",
            "date_range": {"from": from_date, "to": to_date},
            "detailed_report": report_data,
            "overall": overall_stats
        }, status=status.HTTP_200_OK)


class BookingAPIView(APIView):
    # permission_classes = (IsAuthenticated,)


    def get(self, request, id=None):
        if id is not None:
            try:
                booking = Booking.objects.get(id=id)
                data = {
                    'id': booking.id,
                    'customer_name': booking.customer_name,
                    'phone': booking.phone,
                    'email': booking.email,
                    'net_selection': booking.net_selection,
                    'booking_type': booking.booking_type, # ??????? ??????? ????????
                    'booking_date': booking.booking_date.strftime('%Y-%m-%d'),
                    'end_date': booking.end_date.strftime('%Y-%m-%d') if booking.end_date else None, # ??????? ??????? ????????
                    'start_time': booking.start_time,
                    'end_time': booking.end_time,
                    'amount': booking.amount,
                    'payment_status': booking.payment_status
                }
                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "data": data
                })
            except Booking.DoesNotExist:
                return Response({"status": {"code": 404}, "message": "Booking not found"}, status=status.HTTP_404_NOT_FOUND)

        else:
            
            try:
                # 1. ??????? ??????? ????? ???????? ???????
                target_date_str = request.query_params.get('date')
                
                if target_date_str:
                    target_date = datetime.strptime(target_date_str, '%Y-%m-%d').date()
                else:
                    target_date = timezone.now().date()

                # 2. ???????: ??????????? ???????? ?????? ??????? ?????? ???? ?????? (Upcoming)
                # __gte = Greater than or equal to
                bookings = Booking.objects.filter(booking_date__gte=target_date).order_by('booking_date', 'start_time')

                booking_list = []
                for index, b in enumerate(bookings, 1):
                    booking_list.append({
                        'row': index,
                        'id': b.id,
                        'customer_name': b.customer_name,
                        'phone': b.phone,
                        'email': b.email,
                        'net_selection': b.net_selection,
                        'booking_type': b.booking_type, # Day/Month ??????
                        'booking_date': b.booking_date.strftime('%Y-%m-%d'), 
                        'end_date': b.end_date.strftime('%Y-%m-%d') if b.end_date else None,
                        'start_time': b.start_time,
                        'end_time': b.end_time,
                        'amount': b.amount,
                        'payment_status': b.payment_status
                    })

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "data": booking_list
                })
            except Exception as e:
                return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
    from django.db.models import Q

    

    def post(self, request):
        data = request.data
        try:
            b_type = data.get('booking_type', 'Day')
            start_date = datetime.strptime(data.get('booking_date'), '%Y-%m-%d').date()
            raw_start = data.get('start_time')
            raw_end = data.get('end_time')
            net = data.get('net_selection')
            
            # ???????? ?????? ?????? ???????
            end_date = None
            if b_type == 'Month':
                end_date = datetime.strptime(data.get('end_date'), '%Y-%m-%d').date()
            else:
                end_date = start_date

            # 1. Conflict Check (??? ??? ????? ????? ???? ???????)
            # ???? ?????? 'Day' ??????? 'Month' ???????????? ???? ????????
            overlap = Booking.objects.filter(
                net_selection=net,
                start_time__lt=raw_end,
                end_time__gt=raw_start
            ).filter(
                # ??????? ????? ?????????? ????? ?????????
                Q(booking_date__range=(start_date, end_date)) | 
                Q(end_date__range=(start_date, end_date)) |
                Q(booking_date__lte=start_date, end_date__gte=end_date)
            ).exists()

            if overlap:
                return Response({
                    "message": "Slot already booked! Selected dates or times conflict with an existing booking."
                }, status=status.HTTP_409_CONFLICT)

            # 2. Save Booking (??? ??? ???? ??????? ???????? ???????)
            booking = Booking.objects.create(
                customer_name=data.get('customer_name'),
                phone=data.get('phone'),
                email=data.get('email'),
                net_selection=net,
                booking_type=b_type,
                booking_date=start_date,
                end_date=end_date if b_type == 'Month' else None,
                start_time=raw_start,
                end_time=raw_end,
                amount=data.get('amount'),
                payment_status=data.get('payment_status')
            )

            return Response({
                "message": "Booking confirmed successfully!",
                "id": booking.id
            }, status=status.HTTP_201_CREATED)

        except Exception as e:
            return Response({"message": str(e)}, status=status.HTTP_400_BAD_REQUEST)
    
    # PUT: ???????? ????????? ??????? ???????
    def put(self, request, id):
        data = request.data
        try:
            booking = Booking.objects.get(id=id)
            
            # ?????????? ???????
            b_type = data.get('booking_type', booking.booking_type)
            start_date_str = data.get('booking_date')
            start_date = datetime.strptime(start_date_str, '%Y-%m-%d').date() if start_date_str else booking.booking_date
            
            raw_start = data.get('start_time', booking.start_time)
            raw_end = data.get('end_time', booking.end_time)
            net = data.get('net_selection', booking.net_selection)

            # End Date ?????? ???????
            if b_type == 'Month' and data.get('end_date'):
                end_date = datetime.strptime(data.get('end_date'), '%Y-%m-%d').date()
            elif b_type == 'Day':
                end_date = start_date
            else:
                end_date = booking.end_date

            # 1. Conflict Check (??????? ???? ???? ?????????????? ???? ???????)
            overlap = Booking.objects.filter(
                net_selection=net,
                start_time__lt=raw_end,
                end_time__gt=raw_start
            ).filter(
                Q(booking_date__range=(start_date, end_date)) | 
                Q(end_date__range=(start_date, end_date)) |
                Q(booking_date__lte=start_date, end_date__gte=end_date)
            ).exclude(id=id).exists() # ?? ??? ?????????: ??? ???????????? ?????

            if overlap:
                return Response({
                    "message": "Update failed! Slot conflicts with another booking."
                }, status=status.HTTP_409_CONFLICT)

            # 2. ????????? ??????? ???????
            booking.customer_name = data.get('customer_name', booking.customer_name)
            booking.phone = data.get('phone', booking.phone)
            booking.email = data.get('email', booking.email)
            booking.net_selection = net
            booking.booking_type = b_type
            booking.booking_date = start_date
            booking.end_date = end_date if b_type == 'Month' else None
            booking.start_time = raw_start
            booking.end_time = raw_end
            booking.amount = data.get('amount', booking.amount)
            booking.payment_status = data.get('payment_status', booking.payment_status)
            
            booking.save()

            return Response({
                "status": "success",
                "message": "Booking updated successfully!"
            }, status=status.HTTP_200_OK)

        except Booking.DoesNotExist:
            return Response({"message": "Booking not found"}, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            return Response({"message": str(e)}, status=status.HTTP_400_BAD_REQUEST)
    def delete(self, request, id):
        if id is not None:
            try:
                booking = Booking.objects.get(id=id)
                booking.delete()

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "message": "Booking slot deleted successfully"
                })

            except Booking.DoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "message": "No booking found"
                })


import random
import string
def generate_receipt_no():
    return 'REC' + ''.join(random.choices(string.digits, k=6))
from datetime import datetime
from django.db.models import Sum as DSum
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Student, Fees, FeesHistory


class FeesAPIView(APIView):
    def get(self, request, id=None):
        current_month = datetime.now().month
        current_year = datetime.now().year

        if id:
            try:
                student = Student.objects.get(id=id)
                fee_record = Fees.objects.filter(student=student).first()

                # ???? ????? ?????? ????????? ???? (History-????????)
                n_paid_this_month = float(FeesHistory.objects.filter(
                    student=student, fee_type='NORMAL',
                    payment_date__month=current_month, payment_date__year=current_year
                ).aggregate(total=DSum('amount_paid'))['total'] or 0)

                s_paid_this_month = float(FeesHistory.objects.filter(
                    student=student, fee_type='SPECIAL',
                    payment_date__month=current_month, payment_date__year=current_year
                ).aggregate(total=DSum('amount_paid'))['total'] or 0)

                # --- 1. Normal Fees ???????? ---
                n_fees = float(student.normal_fees or 0)
                if fee_record:
                    # ??????: ???? ????? ??????? ?????????? ??????? ???? ?????? ??? ???? ??? ??????? ????????? ??????
                    if n_paid_this_month == 0 and float(fee_record.normal_balance) < n_fees:
                        n_balance = float(fee_record.normal_balance) + n_fees
                    else:
                        n_balance = float(fee_record.normal_balance)
                else:
                    n_balance = n_fees

                # --- 2. Special Fees ???????? ---
                s_fees = float(student.special_fees or 0)
                if fee_record:
                    # ??????: ???? ?????? (20.000) + ????? ??? ???? (70.000) = 90.000
                    if s_paid_this_month == 0 and float(fee_record.special_balance) < s_fees:
                        s_balance = float(fee_record.special_balance) + s_fees
                    else:
                        s_balance = float(fee_record.special_balance)
                else:
                    s_balance = s_fees

                data = {
                    'studentName': student.studentName,
                    'classType': student.classType,
                    'normal_fees': n_fees,
                    'normal_paid': n_paid_this_month,
                    'normal_balance': n_balance,
                    'special_fees': s_fees,
                    'special_paid': s_paid_this_month,
                    'special_balance': s_balance,
                }
                return Response({"status": {"code": 200}, "data": data})

            except Student.DoesNotExist:
                return Response({"status": {"code": 404}, "message": "Student not found"})
        
        else:
            # ?????? ???? (Fees Management Screen-?????)
            students = Student.objects.filter(status=1)
            data_list = []
            
            for student in students:
                fee_record = Fees.objects.filter(student=student).first()
                
                # ???? ????? ?????? ???? ????????????????? ????? ????????????
                n_paid_this_month = float(FeesHistory.objects.filter(
                    student=student, fee_type='NORMAL',
                    payment_date__month=current_month, payment_date__year=current_year
                ).aggregate(total=DSum('amount_paid'))['total'] or 0)

                s_paid_this_month = float(FeesHistory.objects.filter(
                    student=student, fee_type='SPECIAL',
                    payment_date__month=current_month, payment_date__year=current_year
                ).aggregate(total=DSum('amount_paid'))['total'] or 0)

                # --- 1. Normal Class Balance ???????? ---
                n_fees = float(student.normal_fees or 0)
                if fee_record:
                    # ?????? ???? ????? ???? ?????????? ???????: ???? ?????? + ???? ??? ????
                    if n_paid_this_month == 0 and float(fee_record.normal_balance) < n_fees:
                        n_balance = float(fee_record.normal_balance) + n_fees
                    else:
                        n_balance = float(fee_record.normal_balance)
                else:
                    n_balance = n_fees

                # --- 2. Special Class Balance ???????? ---
                s_fees = float(student.special_fees or 0)
                if fee_record:
                    # ??????: ???? ????? ???? ?????????? ??????? (70.000) + ???? ?????? (20.000) = 90.000
                    if s_paid_this_month == 0 and float(fee_record.special_balance) < s_fees:
                        s_balance = float(fee_record.special_balance) + s_fees
                    else:
                        s_balance = float(fee_record.special_balance)
                else:
                    s_balance = s_fees

                data_list.append({
                    'id': student.id,
                    'photo': request.build_absolute_uri(student.photo.url) if student.photo else None,

                    'studentName': student.studentName,
                    'classType': student.classType,
                    'normal_fees': n_fees,
                    'normal_paid': n_paid_this_month,
                    'normal_balance': n_balance,
                    'special_fees': s_fees,
                    'special_paid': s_paid_this_month,
                    'special_balance': s_balance,
                })
            return Response({"status": {"code": 200}, "data": data_list})

    def put(self, request, id):
        try:
            student_obj = Student.objects.get(id=id)
            d = request.data
            paid_now = float(d.get('paid_amount', 0))
            new_balance = float(d.get('balance_amount', 0))
            fee_type = d.get('fee_type') # 'NORMAL' ?????? 'SPECIAL'
            
            # 1. ??????? ?????????? ????????? ?????????, ????????????? ???????????
            fee, created = Fees.objects.get_or_create(student=student_obj)
            
            # 2. ????? ???? ??????????????? (Initial values)
            if created:
                fee.normal_fees = float(student_obj.normal_fees or 0)
                fee.special_fees = float(student_obj.special_fees or 0)
                fee.payment_date = datetime.now().date()

            # 3. ???? ??? ???? ??????????? ???? ???????? ??????? ??????? ????????
            if fee_type == 'NORMAL':
                fee.normal_paid = float(fee.normal_paid or 0) + paid_now
                fee.normal_balance = new_balance
            elif fee_type == 'SPECIAL':
                fee.special_paid = float(fee.special_paid or 0) + paid_now
                fee.special_balance = new_balance
            
            fee.save()

            # 4. ???????? ??????????? ??? ????? ????????????
            FeesHistory.objects.create(
                student=student_obj, 
                amount_paid=paid_now, 
                fee_type=fee_type,
                payment_date=datetime.now().date()
            )

            return Response({"status": {"code": 200}, "message": "Payment Recorded Successfully"})
        except Exception as e:
            return Response({"status": {"code": 400}, "message": str(e)})


class FeesHistoryAPIView(APIView):
    def get(self, request, student_id):
        # try:
        #     # ???????? ??????? ???????? ????????????? ???????? ???????????? ???????????
        #     history = FeesHistory.objects.filter(student_id=student_id).order_by('-payment_date')
            
        #     data = []
        #     for h in history:
        #         data.append({
        #             'id': h.id,
        #             'amount_paid': float(h.amount_paid),
        #             'payment_date': h.payment_date.strftime('%d-%m-%Y'), # ?????? ???? ??????
        #             'payment_mode': h.payment_mode,
        #             # ????????????: ??????? ???????? ????? ???? fee_type ???????
        #             'fee_type': h.fee_type if h.fee_type else "NORMAL" 
        #         })

        from dateutil.relativedelta import relativedelta
        try:
            # 1. ?????? ????? ??????????? (???? ??????? ?????????)
            student = Student.objects.get(id=student_id)
            join_date = student.created_at.date() # ?????? ??????? ????
            current_date = datetime.now().date() # ?????? ????

            # 2. ???????? ????? ???????? ???????????
            history_records = FeesHistory.objects.filter(student_id=student_id)
            
            # ???????? ??????????, ??????? ????????? ???????? ??? ????-?? (Set) ????????????
            # Format: "MM-YYYY-TYPE" (e.g., "05-2026-NORMAL")
            paid_months = set()
            for h in history_records:
                key = f"{h.payment_date.strftime('%m-%Y')}-{h.fee_type}"
                paid_months.add(key)

            final_data = []
            
            # 3. ??????? ?????????????? ????? ??? ??????? ?????? ???? ??????????
            temp_date = join_date.replace(day=1) # ??????? ????????? ????? ?????????????? ????????????
            
            while temp_date <= current_date:
                month_year = temp_date.strftime('%m-%Y')
                
                # NORMAL ??????? SPECIAL ???????????? ???????????????
                for f_type in ["NORMAL", "SPECIAL"]:
                    check_key = f"{month_year}-{f_type}"
                    
                    if check_key in paid_months:
                        # ??????? ??????????????????, ???? ?????????? ????????????
                        record = history_records.get(
                            payment_date__month=temp_date.month, 
                            payment_date__year=temp_date.year,
                            fee_type=f_type
                        )
                        final_data.append({
                            'id': record.id,
                            'month_name': temp_date.strftime('%B %Y'),
                            'amount_paid': float(record.amount_paid),
                            'payment_date': record.payment_date.strftime('%d-%m-%Y'),
                            'fee_type': record.fee_type,
                            'status': 'PAID'
                        })
                   

                    else:
                        # id-???? ?????? ??? ??????????? ????????
                        final_data.append({
                            'id': f"unpaid-{temp_date.strftime('%m-%Y')}-{f_type}", 
                            'month_name': temp_date.strftime('%B %Y'),
                            'amount_paid': 0,
                            'payment_date': None,
                            'fee_type': f_type,
                            'status': 'NOT_PAID'
                        })
                
                # ?????? ????????????? ??????????
                temp_date += relativedelta(months=1)

            # ????????? ????????? ??????? ?? ????????????????????
            final_data.reverse()
            
            return Response({"status": {"code": 200}, "data": final_data})
        except Exception as e:
            return Response({"status": {"code": 400}, "message": str(e)})
   
class StudentStatusAPIView(APIView):
    def patch(self, request, id):
        try:
            student = Student.objects.get(id=id)
            # 1-?? ????????? 2-???? ?????????, ????????????? 1-???? ?????????
            if student.status == 1:
                student.status = 2
            else:
                student.status = 1
            
            student.save()
            return Response({
                "status": {"code": 200, "response": "success"},
                "new_status": student.status,
                "message": "Status updated successfully"
            })
        except Student.DoesNotExist:
            return Response({"error": "Student not found"}, status=404)
        
class EmployeeStatusAPIView(APIView):
    def patch(self, request, id):
        try:
            student = Profiles.objects.get(user_id=id)
            # 1-?? ????????? 2-???? ?????????, ????????????? 1-???? ?????????
            if student.status == 1:
                student.status = 2
            else:
                student.status = 1
            
            student.save()
            return Response({
                "status": {"code": 200, "response": "success"},
                "new_status": student.status,
                "message": "Status updated successfully"
            })
        except Student.DoesNotExist:
            return Response({"error": "Student not found"}, status=404)
import calendar
from datetime import datetime

class MonthlyAttendanceAPIView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        month = int(request.query_params.get('month', datetime.now().month))
        year = int(request.query_params.get('year', datetime.now().year))
        student_id_param = request.query_params.get('student_id')

        num_days = calendar.monthrange(year, month)[1]
        month_name = calendar.month_name[month][:3]
        
        # ??????? ????????
        days_list = []
        for d in range(1, num_days + 1):
            days_list.append({
                "day_num": d,
                "display": f"{month_name} {d:02d}"
            })

        # ?????? ???????
        if student_id_param and student_id_param != "all":
            students = Student.objects.filter(id=student_id_param)
        else:
            students = Student.objects.all()

        # ???? ????????? ??????? ????????????
        attendance_records = Attendance.objects.filter(date__month=month, date__year=year)

        report_data = []
        for student in students:
            student_att = {}
            total_n_p = 0  # Normal Present
            total_n_a = 0  # Normal Absent
            total_s_p = 0  # Special Present
            total_s_a = 0  # Special Absent
            
            for day_obj in days_list:
                d = day_obj["day_num"]
                n_rec = attendance_records.filter(student_id=student.id, date__day=d, session_type=1).first()
                s_rec = attendance_records.filter(student_id=student.id, date__day=d, session_type=2).first()
                
                n_status = "P" if n_rec and n_rec.status == "Present" else ("A" if n_rec else "-")
                s_status = "P" if s_rec and s_rec.status == "Present" else ("A" if s_rec else "-")
                
                student_att[f"day_{d}_n"] = n_status
                student_att[f"day_{d}_s"] = s_status
                
                # ????????
                if n_status == "P": total_n_p += 1
                elif n_status == "A": total_n_a += 1
                
                if s_status == "P": total_s_p += 1
                elif s_status == "A": total_s_a += 1

            report_data.append({
                "name": student.studentName,
                'photo': request.build_absolute_uri(student.photo.url) if student.photo else None,
                'classType' : student.classType,
                "attendance": student_att,
                "total_n_p": total_n_p,
                "total_n_a": total_n_a,
                "total_s_p": total_s_p,
                "total_s_a": total_s_a,
            })


        print(report_data)

        return Response({
            "days": days_list,
            "report": report_data
        })
class AttendanceAPIView(APIView):
    # permission_classes = (IsAuthenticated,)

    def get(self, request):
        try:
            # Query Params ????? ???? ??????? ??????? ???????
            query_date = request.query_params.get('date', date.today().isoformat())
            session_type = request.query_params.get('session_type') # 1: Normal, 2: Special

            attendances = Attendance.objects.filter(date=query_date).order_by('-created_at')
            
            if session_type:
                attendances = attendances.filter(session_type=session_type)

            attendance_list = []
            for index, att in enumerate(attendances, 1):
                attendance_list.append({
                    'row': index,
                    'id': att.id,
                    'studentId': att.student.id,
                    'studentName': att.student.studentName,
                    'status': att.status, # Present / Absent
                    'session_type': att.session_type,
                    'date': att.date,
                })

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "data": attendance_list
            })
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": str(e),
            })

    def post(self, request):
        data = request.data
        try:
            student_id = data.get('studentId')
            att_date = data.get('date', date.today().isoformat())
            session = data.get('session_type') # 1 or 2
            att_status = data.get('status') # Present or Absent

            # ??????? ??? ??????, ??? ????????? ???????????? ?????????? ???? ????????????
            attendance_obj = Attendance.objects.filter(
                student_id=student_id, 
                date=att_date, 
                session_type=session
            ).first()

            if attendance_obj:
                # ????????? ?????? Update ???????
                attendance_obj.status = att_status
                # ?????? ????? ????? ????? ??????????????: attendance_obj.user = request.user
                attendance_obj.save()
                message = "Attendance updated successfully"
            else:
                # ????????????? ???????? ????????????
                attendance_obj = Attendance.objects.create(
                    student_id=student_id,
                    date=att_date,
                    session_type=session,
                    status=att_status,
                    # user=request.user # Login ????? ?????????
                )
                message = "Attendance marked successfully"

            return Response({
                "status": {"code": status.HTTP_201_CREATED, "response": "success"},
                "error": None,
                "message": message,
                "data": {
                    "id": attendance_obj.id,
                    "studentName": attendance_obj.student.studentName,
                    "status": attendance_obj.status
                }
            })

        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": f"Error: {str(e)}"
            })

    def delete(self, request):
        try:
            student_id = request.query_params.get('studentId')
            date = request.query_params.get('date')
            session_type = request.query_params.get('session_type')

            if not student_id or not date or not session_type:
                return Response({
                    "status": {"code": 400},
                    "message": "studentId, date, session_type required"
                })

            deleted_count, _ = Attendance.objects.filter(
                student_id=student_id,
                date=date,
                session_type=session_type
            ).delete()

            if deleted_count > 0:
                return Response({
                    "status": {"code": 200, "response": "success"},
                    "message": "Attendance deleted successfully"
                })
            else:
                return Response({
                    "status": {"code": 404},
                    "message": "Attendance record not found"
                })

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

class LoanAPIView(APIView):
    # permission_classes = (IsAuthenticated,)

    def get(self, request, id=None):
        if id is not None:
            try:
                company = Product.objects.get(id=id)

                try:
                    fl = company.sfile.url if company.sfile else None
                except ValueError:
                    fl = None 
                data = {
                    'id': company.id,
                    'name': company.name,
                    'code': company.code,

                    'description': company.description,
                    'specification':company.specification,
                    'sfile': fl,
                    'status': company.status

                }

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": data
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })
        else:
            try:

                activeloan = []

                loa = Loan.objects.filter(loan_status='Active')


                for i in loa:


                    clients=Client.objects.get(id=i.client_id)


                    activeloan.append({
                        'loan_id' : i.id,
                        'name' : clients.client_name,
                        'phone' : clients.phone
                    })

                index = 0
                companies = []



                

                loan = Loan.objects.all()

                for company in loan:
                    index += 1





                    client=Client.objects.get(id=company.client_id)

                    collectedamount = Collection.objects.filter(loan_id=company.id).aggregate(
                        total=Sum('collectedamonut')
                    )['total'] or 0

                    companies.append({
                        'row': index,
                        'id': company.id,
                        'loan_id':'L00'+str(company.id),
                        'paid': collectedamount,
                        'client_name' : client.client_name,
                        'client_phone': client.phone,
                        'loan_amount': company.loan_amount,
                        'loan_tenure_months': company.loan_tenure_months,

                        'collection_type': company.collection_type,
                        'collection_day': company.collection_day,
                        'loan_status': company.loan_status,

                    })


                


                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": companies,
                    "activeloan" : activeloan
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })

    def post(self, request):
        data = request.data

        try:
            rate  = 0
            company = Loan.objects.create(

               




                client_id=data["clientId"],
                loan_amount=data["loanAmount"],
                loan_date=data["loanDate"], # ??? EMI End Date
                interest_rate=rate,
                loan_tenure_months=data["loanTenure"],
                emi_start_date=data["emiStartDate"],
                # ?????????? ??????? ?????: 
                # ??????? 'collectionType' ???????????? ???????, ??? ???????? ??????? ???????????
                collection_type=data.get("collectionType", "Daily"), 
                collection_day=data["avgRate"],
                loan_status=data["loanStatus"],
                remarks=data.get("remarks", "")






                # created_by=request.user
            )
            company.save()

            # from twilio.rest import Client as TwilioClient

            # client = TwilioClient(settings.TWILIO_ACCOUNT_SID, settings.TWILIO_AUTH_TOKEN)

            # recipient_number = '+918220432097'
            # message_body = "Hi, This is a Django test message!"

            # message = client.messages.create(
            #     to=recipient_number,
            #     messaging_service_sid=settings.TWILIO_MESSAGING_SERVICE_SID,
            #     body=message_body
            # )



            return Response({
                "status": {"code": status.HTTP_201_CREATED, "response": "success"},
                "error": None,
                "message": "Loan created successfully",
               
            })
        except KeyError as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": f"Missing required field: {e}"
            })





    # def put(self, request, id):
    #     data = request.data

    #     try:

    #         ve =data.get("sfile")

    #         company = Product.objects.get(id=id)
    #         company.name = data.get("name", company.name)
    #         company.code = data.get("code", company.code)

    #         company.description = data.get("description", company.description)
    #         company.specification = data.get("specification", company.specification)
    #         company.sfile = data.get("sfile", company.sfile) 
    #         company.status = data.get("status", company.status)
    #         company.save()

    #         return Response({
    #             "status": {"code": status.HTTP_200_OK, "response": "success"},
    #             "error": None,
    #             "message": "Product updated successfully"
    #         })
    #     except ObjectDoesNotExist:
    #         return Response({
    #             "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
    #             "error": True,
    #             "message": "No data found"
    #         })
    #     except Exception as e:
    #         print(e)
    #         return Response({
    #             "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
    #             "error": True,
    #             "message": "Something went wrong"
    #         })

   


    # def delete(self, request, id):
    #     if id is not None:
    #         try:
    #             product_id_str = str(id)
    #             is_used = Enquiry.objects.filter(product__contains=[product_id_str]).exists()

    #             if is_used:
    #                 return Response({
    #                     "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
    #                     "error": "Product is used in enquiry",
    #                     "message": "Cannot delete product. It's used in one or more enquiries."
    #                 })

    #             # If not used, delete the product
    #             product = Product.objects.get(id=id)
    #             product.delete()

    #             return Response({
    #                 "status": {"code": status.HTTP_200_OK, "response": "success"},
    #                 "error": None,
    #                 "message": "Product deleted successfully"
    #             })

    #         except Product.DoesNotExist:
    #             return Response({
    #                 "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
    #                 "error": None,
    #                 "message": "No product found"
    #             })
            


class DashboardAPIView(APIView):
    # permission_classes = (IsAuthenticated,)

    def get(self, request, id=None):
        if id is not None:
            try:

                dogo = []
                collection = Collection.objects.filter(loan_id=id)

                for m in collection:


                    dogo.append({
                        'id' : m.id,
                        'collectedamonut' : m.collectedamonut,
                        'method' : m.method,
                        'loan_id' : m.loan_id,
                        'date' : m.created_at
                    

                    })

                collectedamount = Collection.objects.filter(loan_id=id).aggregate(
                        total=Sum('collectedamonut')
                    )['total'] or 0

                loa = Loan.objects.get(id=id)

                cli = Client.objects.get(id=loa.client_id)
                data = {
                'client_name' : cli.client_name,
                'phone' : cli.phone,
                'loan_amount' : loa.loan_amount,
                'tenure' : loa.loan_tenure_months,
                'loan_status' : loa.loan_status,
                'paid' : collectedamount
                 }
               

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": dogo,
                    "datas" : data
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })
        else:
            try:

                index = 0
                companies = []

                from django.utils import timezone # ????? ???? ???? ????? ???????
                

                active = Loan.objects.filter(loan_status='Active').count()
                inactive = Loan.objects.filter(loan_status='Closed').count()
                total_disbursed = Loan.objects.aggregate(Sum('loan_amount'))['loan_amount__sum'] or 0

                total_collected = Collection.objects.aggregate(Sum('collectedamonut'))['collectedamonut__sum'] or 0

                total_outstanding = float(total_disbursed) - float(total_collected)

                expected_daily = Loan.objects.filter(loan_status='Active').aggregate(Sum('collection_day'))['collection_day__sum'] or 0

              

                

                today = timezone.now().date()
                actual_daily = Collection.objects.filter(created_at__date=today).aggregate(Sum('collectedamonut'))['collectedamonut__sum'] or 0

                datas = {
                    'active' : active,
                    'inactive' : inactive,
                    'total_disbursed': total_disbursed,
                    'total_collected': total_collected,
                    'total_outstanding': total_outstanding,
                    'expected_daily': expected_daily, # ??????
                    'actual_daily': actual_daily      # ??????
                }


                print(datas,'fdddgdgfdgdfgdfgfdgfdgfd')
                

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": datas
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })
            
from django.db.models import Sum
from django.utils import timezone
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Loan, Collection

class MonthlyReportAPIView(APIView):
    def get(self, request):
        # Front-end ???????? start_date ??????? end_date ?????
        start_date = request.query_params.get('start_date')
        end_date = request.query_params.get('end_date')

        # ???? ???????? ??????? ????? ??? ?????? ???????????? ????????
        if not start_date or not end_date:
            today = timezone.now().date()
            start_date = today
            end_date = today

        try:
            # 1. ??????????? ??? ??????????? ??????????? ????? ????
            disbursed = Loan.objects.filter(
                created_at__date__range=[start_date, end_date]
            ).aggregate(Sum('loan_amount'))['loan_amount__sum'] or 0

            # 2. ??????????? ??? ??????????? ?????? ??????? ????
            collected = Collection.objects.filter(
                created_at__date__range=[start_date, end_date]
            ).aggregate(Sum('collectedamonut'))['collectedamonut__sum'] or 0

            # 3. ????? ??????? ?????????
            new_loans_count = Loan.objects.filter(
                created_at__date__range=[start_date, end_date]
            ).count()

            return Response({
                "status": "success",
                "data": {
                    "total_disbursed": disbursed,
                    "total_collected": collected,
                    "net_flow": float(collected) - float(disbursed),
                    "new_loans_count": new_loans_count,
                    "period": f"{start_date} to {end_date}"
                }
            }, status=status.HTTP_200_OK)

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

class CollectionAPIView(APIView):
    # permission_classes = (IsAuthenticated,)

    def get(self, request, id=None):
        if id is not None:
            try:

                dogo = []
                collection = Collection.objects.filter(loan_id=id)

                for m in collection:


                    dogo.append({
                        'id' : m.id,
                        'collectedamonut' : m.collectedamonut,
                        'method' : m.method,
                        'loan_id' : m.loan_id,
                        'date' : m.created_at
                    

                    })

                collectedamount = Collection.objects.filter(loan_id=id).aggregate(
                        total=Sum('collectedamonut')
                    )['total'] or 0

                loa = Loan.objects.get(id=id)

                cli = Client.objects.get(id=loa.client_id)
                data = {
                'client_name' : cli.client_name,
                'phone' : cli.phone,
                'loan_amount' : loa.loan_amount,
                'tenure' : loa.loan_tenure_months,
                'loan_status' : loa.loan_status,
                'paid' : collectedamount
                 }
               

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": dogo,
                    "datas" : data
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })
        else:
            try:

                index = 0
                companies = []


                

                loan = Loan.objects.all()

                for company in loan:
                    index += 1


                    client=Client.objects.get(id=company.client_id)


                    companies.append({
                        'row': index,
                        'id': company.id,
                        'loan_id':'L00'+str(company.id),



                        'client_name' : client.client_name,
                        'loan_amount': company.loan_amount,
                        'loan_tenure_months': company.loan_tenure_months,

                        'collection_type': company.collection_type,
                        'collection_day': company.collection_day,
                        'loan_status': company.loan_status,

                    })


                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": companies
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })

    def post(self, request):
        data = request.data

        try:
            loan_id = data["loanId"]
            amount_collected = data["amountCollected"]
            payment_mode = data["paymentMode"]
            remarks = data.get("remarks", "")

            # ? Create a new collection entry
            collection = Collection.objects.create(
                loan_id=loan_id,
                collectedamonut=amount_collected,
                method=payment_mode,
                remarks=remarks,
                # created_by=request.user  # uncomment if you have user tracking
            )

            # ? Calculate total collected so far
            collected_total = Collection.objects.filter(loan_id=loan_id).aggregate(
                total=Sum('collectedamonut')
            )['total'] or 0

            # ? Get the loan record
            loan = Loan.objects.get(id=loan_id)

            # ? Check if the loan is fully paid
            if loan.loan_amount <= collected_total:  # use <= for safety
                loan.loan_status = "Closed"
                loan.save()



            return Response({
                "status": {"code": status.HTTP_201_CREATED, "response": "success"},
                "error": None,
                "message": "Loan created successfully"
            })
        except KeyError as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": f"Missing required field: {e}"
            })


            


class GetclientAPIView(APIView):
    # permission_classes = (IsAuthenticated,)

    def get(self, request, id=None):
        if id is not None:
            try:
                company = Client.objects.filter(id=id)
                data = {
                    'id': company.id,
                    'vendorname': company.vendorname,
                    'phone': company.phone,
                    'email': company.email,
                    'address': company.address
                }

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": data
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })
        else:
            try:



                index = 0
                companies = []

                for company in Client.objects.all():
                    index += 1

                    companies.append({
                        'row': index,
                        'id': company.id,
                        'client': company.client_name,
                        'phone' :company.phone


                    })



                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": companies
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })

class OldloanAPIView(APIView):
    # permission_classes = (IsAuthenticated,)

    def get(self, request, id=None):
        if id is not None:
            try:

                dogo = []
                collection = Loan.objects.filter(client_id=id)

                for m in collection:


                    dogo.append({
                        'tenure' : m.loan_tenure_months,
                        'loan_amount' : m.loan_amount,
                        'loan_id' : m.id,
                        'emisdate' : m.emi_start_date,
                        'emildate' : m.loan_date,
                        'loan_status' : m.loan_status
                    

                    })

             
               

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": dogo,
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })
        else:
            try:

                index = 0
                companies = []


                

                loan = Loan.objects.all()

                for company in loan:
                    index += 1


                    client=Client.objects.get(id=company.client_id)


                    companies.append({
                        'row': index,
                        'id': company.id,
                        'loan_id':'L00'+str(company.id),



                        'client_name' : client.client_name,
                        'loan_amount': company.loan_amount,
                        'loan_tenure_months': company.loan_tenure_months,

                        'collection_type': company.collection_type,
                        'collection_day': company.collection_day,
                        'loan_status': company.loan_status,

                    })


                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": companies
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })


class FpAPIView(APIView):

    

    def post(self, request):
        data = request.data

        try:
            
            params = data.get('params', {})

            # Now retrieve 'email' and 'password' from the 'params' dictionary
            email = params.get('email')  # Access the 'email' field
            password = params.get('password')  # Access the 'password' field


            # Hash the password
            hashed_password = make_password(password)

            man = User.objects.get(email=email)

            man.password = hashed_password

            man.save()



            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "Password reset successfully"
            })
        except KeyError as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": f"Missing required field: {e}"
            })



class NotificationAPIView(APIView):
    permission_classes = (IsAuthenticated,)

    def get(self, request, id=None):
        if id is not None:
            # Fetch a specific vendor by ID
            try:
                company = Vendor.objects.get(id=id)
                data = {
                    'id': company.id,
                    'vendorname': company.vendorname,
                    'phone': company.phone,
                    
                }

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": data
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No data found",
                })

        else:
            # Return all notifications of type 'newuser' or 'paymentuser'
            # else:
            from django.utils.timesince import timesince
            from django.utils.timezone import now

            try:
                index = 0
                note = []
                op = request.user.id

                profile = Profiles.objects.get(user_id=op)

                if profile.role == 1:
                    notifications = Notification.objects.filter(
                        type__in=["newuser", "paymentuser"]
                    ).order_by("-created_at")

                    for n in notifications:
                        index += 1
                        try:
                            username = n.user.username if n.user else "Unknown"
                        except User.DoesNotExist:
                            username = "Unknown"

                        if n.type == "newuser":
                            message = f"New Company Registered: {username}"
                        elif n.type == "paymentuser":
                            message = f"{username} made a payment"
                        else:
                            message = "Unknown notification type"

                        note.append({
                            'row': index,
                            'id': n.id,
                            'type': n.type,
                            'message': message,
                            'created_at': n.created_at,
                            'time_ago': timesince(n.created_at, now()) + " ago", 

                        })

                    return Response({
                        "status": {"code": status.HTTP_200_OK, "response": "success"},
                        "error": None,
                        "data": note,
                        "count": len(note), 
                    })

                else:
                    # ? Non-admin user — return permission denied
                    return Response({
                        "status": {"code": status.HTTP_403_FORBIDDEN, "response": "forbidden"},
                        "error": True,
                        "message": "You do not have permission to view notifications.",
                        "data": []
                    })

            except Exception as e:
                return Response({
                    "status": {"code": status.HTTP_500_INTERNAL_SERVER_ERROR, "response": "failed"},
                    "error": True,
                    "message": str(e),
                })

    def delete(self, request, id=None):
        try:
            if id is not None:
                # Delete a specific notification
                notification = Notification.objects.get(id=id)
                notification.delete()
                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "message": "Notification deleted successfully"
                })
            else:
                # Delete all notifications
                op = request.user.id

                Notification.objects.filter(user_id=op).delete()
                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "message": "All notifications deleted successfully"
                })
        except ObjectDoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "Notification not found"
            })
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_500_INTERNAL_SERVER_ERROR, "response": "failed"},
                "error": True,
                "message": str(e)
            })


    

class ProductactivestatusupdateAPIView(APIView):
    
    def put(self, request, id):
        

        try:
            


            ven = Product.objects.get(id=id)

            if ven.status == 1:
                ven.status = 2
                ven.save()

            else:
                ven.status = 1
                ven.save()
            

           

            



           
    
            return Response({
                "status": {"code": status.HTTP_201_CREATED, "response": "success"},
                "error": None,
                "message": "Quote accepted successfully"
            })
        except KeyError as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": f"Missing required field: {e}"
            })


