from email import message
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 *
from datetime import datetime, timedelta, date
from django.conf import settings
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from rest_framework_simplejwt.tokens import RefreshToken
from passlib.hash import django_pbkdf2_sha256 as handler
from django.template.loader import render_to_string
from .authentication import authenticated
from django.core import mail
from django.core.mail import EmailMultiAlternatives
import math, random, pytz, string
from django.contrib import messages
import jwt
from django.core.files.storage import FileSystemStorage
import os
import ast
from django.db.models import Q
from pyfcm import FCMNotification
from django.views.generic import TemplateView
from admin_panel.models import ContentManagement,Faq, AdminNotifications
from user_app.serializers import ContentSerializer ,FAQSerializer
from user_app.models import *
from .serializers import *
from .functions import *
from django.utils.timesince import timesince
from twilio.rest import Client
from django.conf import settings
from django.utils import timezone
from datetime import timedelta
import json
from twilio.jwt.access_token.grants import (
	SyncGrant,
	ChatGrant,
	VideoGrant
)
from twilio.rest import Client
from twilio.jwt.access_token import AccessToken
from firebase_admin import messaging


account_sid= settings.TWILIO_ACCOUNT_SID
auth_token = settings.TWILIO_AUTH_TOKEN
chat_service_sid = settings.TWILIO_CHAT_SID
sync_service_sid = settings.TWILIO_SYNC_SID
api_sid = settings.TWILIO_API_SID
api_secret= settings.TWILIO_API_SECRET
client = Client(account_sid, auth_token)
# Create your views here.

def send_push_notification(registration_id, title, body, data=None):
	message = messaging.Message(
		notification=messaging.Notification(
			title=title,
			body=body,
			# data= data or {}
		),
		token=registration_id,
		data= {'AASASASAS':'SSAD'},  # Specify the registration token here
	)
	response = messaging.send(message)
	return response

class Register(APIView):
	def post(self, request):
		try:
			data = request.data
			full_name = data.get('full_name')
			email = data.get('email')
			password = data.get('password')
			address=data.get('address')
			latitude=data.get('latitude')
			longitude = data.get('longitude')
			fcm_token = data.get('fcm_token')
			
			# Input validation
			if not email or not full_name or not password:
				return Response({"message": 'All required fields must be provided'}, status=status.HTTP_400_BAD_REQUEST)

			# Password hashing
			new_password = handler.hash(password)

			# Check if the email is already registered
			trainer_obj = Trainer.objects.filter(email=email).first()
			if trainer_obj:
				return Response({"message": "The email is already registered"}, status=status.HTTP_409_CONFLICT)
			else:
				
				# Create Trainer instance
				the_otp=random.randrange(1000, 9999, 5)
				trainer_obj = Trainer.objects.create(
					full_name=full_name,
					email=email,
					password=new_password,
					otp=the_otp,
					address=address,
					latitude=latitude,
					longitude=longitude,
				)

				# TrainerNotifications.objects.create(message="You have received your referral bonus successfully", notification_type="referral_bonus", app_user=trainer_obj)
				
				# Email verification
				trainer_obj.otp = the_otp
				trainer_obj.save()
				subject = "Verify Account"
				html_message = render_to_string('email_verification.html', {'otp': the_otp})
				plain_message = html_message
				from_email = settings.EMAIL_HOST_USER
				to = email
				# mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)
				try:
					mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)
				except Exception as email_error:
					return Response({"message": "Your account has been created, but we encountered an issue sending the verification email. Please contact support for assistance."}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

				# Admin notification
				# AdminNotifications.objects.create(message=full_name + ' has been successfully registered with us.', type='app_user_register')

			return Response({"message": 'You have been successfully registered with us. Please verify your email.'})
		except Exception as e:
			return Response({"message": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		
class TrainerResendEmailOtp(APIView):
	def post(self, request):
		try:
			data = request.data
			email = data.get('email')
			email=email.lower()


			# Input validation
			if not email:
				return Response({"message": 'All required fields must be provided'}, status=status.HTTP_400_BAD_REQUEST)

			# Password hashing
			# Check if the email is already registered
			trainer_user_obj = Trainer.objects.filter(email=email).last()
			if not trainer_user_obj:
				return Response({"message": "Email not found"}, status=status.HTTP_409_CONFLICT)
			else:
				the_otp=random.randrange(1000, 9999, 5)
				trainer_user_obj.otp = the_otp
				trainer_user_obj.save()

				# AppUserNotifications.objects.create(message="You have received your referral bonus successfully", notification_type="referral_bonus", app_user=app_user_obj)

				# Email verificatio)
				subject = "Verify Account"
				html_message = render_to_string('email_verification.html', {'otp': the_otp})
				plain_message = html_message
				from_email = settings.EMAIL_HOST_USER
				to = email
				# mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)

				try:
					mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)
				except Exception as email_error:
					return Response({"message": "Your account has been created, but we encountered an issue sending the verification email. Please contact support for assistance."}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

				# Admin notification
				# AdminNotifications.objects.create(message=full_name + ' has been successfully registered with us.', type='app_user_register')

			return Response({"message": 'You have been successfully registered with us. Please verify your email.'})
		except Exception as e:
			return Response({"message": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class SocialLogin(APIView):
	def post(self, request):
		try:
			data = request.data
			provider_id = data.get('provider_id')
			email = data.get('email')
			full_name = data.get('full_name')
			# social_id = data.get('social_id')
			device_type = data.get('device_type')
			fcm_token = data.get('fcm_token')
			print("in social")
			print(fcm_token)
			if not provider_id :
				return Response({'message': 'provider_id is required.'}, status=status.HTTP_400_BAD_REQUEST)
			if not full_name:
				return Response({'message': 'full_name is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not email:
				return Response({'message': 'email is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not social_id:
			# 	return Response({'message': 'email is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not device_type:
				return Response({'message': 'device_type is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not fcm_token:
				return Response({'message': 'fcm_token is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			# Check if social account already exists in the database
			trainer_obj = Trainer.objects.filter(provider_id=provider_id,end_date__isnull=True).first()
			if not trainer_obj:
				# If social account not found, create a new one
				trainer_obj = Trainer.objects.create(full_name=full_name,
					  provider_id=provider_id,email=email,device_type=device_type,fcm_token=fcm_token)

			# Issue tokens (refresh token and access token) for the authenticated user
			refresh_token = RefreshToken.for_user(trainer_obj)

			allData={'id':trainer_obj.id,
					'full_name':trainer_obj.full_name,
					'email':trainer_obj.email,
					'is_profile_completed':trainer_obj.is_profile_completed,
					'refresh': str(refresh_token),
					'access': str(refresh_token.access_token),
				   }

			return Response({'message': 'Success', 'data': allData})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		

class OtpVerification(APIView):
	def post(self,request):
		try:
			data=request.data
			email = data.get('email')
			otp = data.get('otp')
			fcm_token = data.get('fcm_token')
			device_type = data.get('device_type')
			if not email:
				return Response({"message":'email is required'},status=status.HTTP_400_BAD_REQUEST)
			if not otp:
				return Response({"message":'otp is required'},status=status.HTTP_400_BAD_REQUEST)
			try:
				trainer_obj = Trainer.objects.get(email=email,otp=otp)
			except Exception as e:
				return Response({"message":'Invalid otp','data':{}},status=status.HTTP_400_BAD_REQUEST)
			trainer_obj.email_verified = True
			trainer_obj.fcm_token = fcm_token
			trainer_obj.device_type = device_type
   
			trainer_obj.save()
			refresh_token = RefreshToken.for_user(trainer_obj)
			allData={'id':trainer_obj.id,
				'full_name':trainer_obj.full_name,
				'email':trainer_obj.email,
				'is_profile_completed':trainer_obj.is_profile_completed,
				'refresh': str(refresh_token),
				'access': str(refresh_token.access_token),
				}
			AdminNotifications.objects.create(message = "A new trainer "+ trainer_obj.full_name +" has been registered successfully with us.",type = "trainer_registered")
			return Response({"message":'Success','data':allData})
		except Exception as e:
			return Response({"message":str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR) 

class RestoreAccount(APIView):
	def post(self, request):
		try:
			data = request.data
			
			email = data.get('email')
			email=email.lower()

			# Input validation
			if not email :
				return Response({"message": 'Email must be provided'}, status=status.HTTP_400_BAD_REQUEST)

			# Password hashing

			# Check if the email is already registered
			trainer_obj = Trainer.objects.filter(email=email,end_date__isnull=True).first()
			if trainer_obj:
				return Response({"message": "The email is already working"}, status=status.HTTP_409_CONFLICT)
			else:
				the_otp=random.randrange(1000, 9999, 5)
				app_user_obj = Trainer.objects.filter(email=email).update(
					otp=the_otp,
				)

				# AppUserNotifications.objects.create(message="You have received your referral bonus successfully", notification_type="referral_bonus", app_user=app_user_obj)

				# Email verification
				# app_user_obj.otp = the_otp
				# app_user_obj.save()
				subject = "Verify Account"
				html_message = render_to_string('email_verification.html', {'otp': the_otp})
				plain_message = html_message
				from_email = settings.EMAIL_HOST_USER
				to = email
				# mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)

				try:
					mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)
				except Exception as email_error:
					return Response({"message": "We encountered an issue sending the verification email. Please contact support for assistance."}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

				# Admin notification
				# AdminNotifications.objects.create(message=full_name + ' has been successfully registered with us.', type='app_user_register')

			return Response({"message": 'Otp sent successsfully','otp':the_otp})
		except Exception as e:
			return Response({"message": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class RestoreAccountOtpVerification(APIView):
	def post(self,request):
		try:
			data=request.data
			email = data.get('email')
			otp = data.get('otp')

			if not email:
				return Response({"message":'email is required'},status=status.HTTP_400_BAD_REQUEST)
			if not otp:
				return Response({"message":'otp is required'},status=status.HTTP_400_BAD_REQUEST)
			try:
				trainer_obj = Trainer.objects.get(email=email,otp=otp)
			except Exception as e:
				return Response({"message":'Invalid otp','data':{}},status=status.HTTP_400_BAD_REQUEST)
			# app_user_obj.email_verified = True
			trainer_obj.end_date= None
			trainer_obj.save()
			
			AdminNotifications.objects.create(message = "The account with "+ trainer_obj.full_name +" has been restored successfully",type = "trainer_restored")
			return Response({"message":'Success'})
		except Exception as e:
			return Response({"message":str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)		

class LoginUser(APIView):
	def post(self,request):
		try:
			data = request.data
			email = data.get('email')
			password = data.get('password')
			fcm_token = data.get('fcm_token')
			device_type = data.get('device_type')
			if not email:
				return Response({"message":'Invalid credentials'},status=status.HTTP_400_BAD_REQUEST) 
			if not password:
				return Response({"message":'Invalid credentials'},status=status.HTTP_400_BAD_REQUEST)  
			
			user  = Trainer.objects.filter(email=email).count()
			if user == 0:
				return Response({"message":'This email does not exist in our database, please register'},status=status.HTTP_404_NOT_FOUND)
			
			trainer_obj  = Trainer.objects.filter(email=email,status=True,end_date__isnull=True).first()
			if not trainer_obj:
				return Response({"message":'Your account has not been activated, Please contact to admin.'},status=status.HTTP_401_UNAUTHORIZED)
			
			check_password = trainer_obj.password
			check = handler.verify(password,check_password)
			
			if check:
				if trainer_obj.email_verified == False:
					the_otp=random.randrange(1000, 9999, 5)
					trainer_obj.otp = the_otp
					trainer_obj.save()
					subject = "Verify Account"
					html_message = render_to_string('email_verification.html', {'otp': the_otp})
					plain_message = html_message
					from_email = settings.EMAIL_HOST_USER
					to = email
					# mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)
					try:
						mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)
					except Exception as email_error:
						return Response({"message": "Failed to send the verification email. Please try again later."}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

					return Response({"message":'Please verify your email first'},status=status.HTTP_400_BAD_REQUEST)
				trainer_obj.fcm_token = fcm_token
				trainer_obj.device_type  =device_type
				trainer_obj.save()
				refresh_token = RefreshToken.for_user(trainer_obj)
				allData={'id':trainer_obj.id,
					'full_name':trainer_obj.full_name,
					'email':trainer_obj.email,
					'is_profile_completed':trainer_obj.is_profile_completed,
					'refresh': str(refresh_token),
					'access': str(refresh_token.access_token),
				   }
				return Response({"message":'Login Successfully','data':allData})
			else:
				return Response({"message":'Invalid password'},status=status.HTTP_401_UNAUTHORIZED)
		except Exception as e:
			return Response({"message":str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		

class ForgetPassword(APIView):
	def post(self,request):
			try:
				data = request.data
				email = data.get('email')
				if not email:
					return Response({"message":'Email is required'})
				user  = Trainer.objects.filter(email=email,end_date__isnull=True).count()
				if user == 0:
					return Response({"message":'This email does not exist in our database, please enter the valid email address.'},status=status.HTTP_404_NOT_FOUND)
				trainer_obj  = Trainer.objects.filter(email=email,end_date__isnull=True).first()
				if trainer_obj:
					the_otp=random.randrange(1000, 9999, 5)
					trainer_obj.otp = the_otp
					trainer_obj.save()
					subject = 'Forgot Password'
					html_message = render_to_string('forget_password_email.html', {'otp': the_otp})
					plain_message = html_message
					from_email = settings.EMAIL_HOST_USER
					to = email
					# mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)

					try:
						mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)
					except Exception as email_error:
						return Response({"message": "Failed to send the forgot email. Please try again later."}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

					return Response({"message":'Reset password otp has been sent to your email address.'})
				else:
					return Response({"message":'Email not exists'})

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


class ForgetPasswordVerification(APIView):
	def post(self,request):
		try:
			data=request.data
			email = data.get('email')
			otp = data.get('otp')
			if not email:
				return Response({"message":'email is required'},status=status.HTTP_400_BAD_REQUEST)
			if not otp:
				return Response({"message":'otp is required'},status=status.HTTP_400_BAD_REQUEST)
			
			trainer_obj = Trainer.objects.filter(email=email,end_date__isnull=True,otp=otp).first()
			if not trainer_obj:
				return Response({"message":'Invalid otp','data':{}},status=status.HTTP_400_BAD_REQUEST)
			
			return Response({"message":'Success'})
		except Exception as e:
			return Response({"message":str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR) 
	
class SetForgetPassword(APIView):
	def post(self,request):
		try:
			data=request.data
			email = data.get('email')
			new_password = data.get('new_password')
			otp = data.get('otp')
			if not new_password:
				return Response({"message":'new_password is required'},status=status.HTTP_400_BAD_REQUEST)
			if not email:
				return Response({"message":'email is required'},status=status.HTTP_400_BAD_REQUEST)
			if not otp:
				return Response({"message":'otp is required'},status=status.HTTP_400_BAD_REQUEST)
			
			trainer_obj = Trainer.objects.filter(email=email,otp=otp).first()
			encrypt_password = handler.hash(new_password)
			if trainer_obj:
				trainer_obj.password = encrypt_password
				trainer_obj.otp = None
				trainer_obj.save()
				return Response({"message":'Success'})
			else:
				return Response({"message":'Something went wrong'},status=status.HTTP_400_BAD_REQUEST)
		except Exception as e:
			return Response({"message":str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR) 
		

class getProfile(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message':str(e)},status=status.HTTP_401_UNAUTHORIZED)
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			allData=TrainerSerializer(trainer_obj).data
			return Response({'message':'Success','data':allData})
		except Exception as e:
			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class EditProfile(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)

			data = request.data
			full_name = data.get('full_name')
			gender = data.get('gender')
			age = data.get('age')
			image = data.get('image')
			speciality = data.get('speciality')
			description = data.get('description')
			total_experience = data.get('total_experience')

			if not full_name:
				return Response({"message": 'full_name is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not gender:
				return Response({"message": 'gender is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not age:
				return Response({"message": 'age is required'}, status=status.HTTP_400_BAD_REQUEST)
		 

			trainer_obj.full_name = full_name
			trainer_obj.gender = gender
			trainer_obj.age = age
			trainer_obj.speciality = speciality
			trainer_obj.description = description
			trainer_obj.total_experience = total_experience
			
			if image:
				# fileUrl=uploadTheProfile(image)
				trainer_obj.image=image
			trainer_obj.save()

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

class UploadImages(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)

			data = request.data
			images = data.getlist('images')
			image_urls = []

			for image in images:
				image_path = uploadTheProfile(image)
				# image_url = settings.BASE_URL + image_path 
				image_urls.append(image_path)
			# # image_urls_str = ','.join(image_urls)
			# if not trainer_obj.images:
			# 	trainer_obj.images = image_urls
			# 	trainer_obj.primary_image = image_urls[0]
			# 	trainer_obj.save()

			return Response({'message': 'Success','data':image_urls})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class RemoveImage(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			data = request.data
			image_name = data.get('image')
			if not image_name:
				return Response({'message':'image is required'},status=status.HTTP_400_BAD_REQUEST)
			image_path = os.path.join(settings.MEDIA_ROOT, image_name)
			if os.path.exists(image_path):
				os.remove(image_path) # delete the image
				# user_obj_image = Trainer.objects.filter(id=seer_user_obj).first()
				# user_images =  ast.literal_eval(user_obj_image.images)
				# form_data = []
				# y = image_name.replace("'","")
				# print(y)
				# for img in user_images:
				# 	if str(img) != y:
				# 		print(img)
				# 		form_data.append(img)
				# Trainer.objects.filter(id=seer_user_obj).update(images = form_data)
				return Response({'message': 'Image deleted successfully.'})
			else:
				return Response({'message': 'Image not found.'}, status=status.HTTP_404_NOT_FOUND)
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class DeleteAccount(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)

			trainer_obj.end_date = datetime.now()
			trainer_obj.save()
		
			return Response({'message': 'Account deleted successfully'})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class GetTrainerFaq(APIView):
	def get(self,request):
		try:
			faq_obj = Faq.objects.filter(end_date__isnull =True,type="trainer").order_by('-id')
			all_data = FAQSerializer(faq_obj,many=True).data
			return Response({'message':'Success','data':all_data})
		except Exception as e:
			print(e)
			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		

class GetTrainerPrivacyPolicy(APIView):
	def get(self,request):
		try:
			content_obj =  ContentManagement.objects.filter(page_type='Privacy Policy',user_type='trainer').first()
			allData=ContentSerializer(content_obj).data
			return Response({'message':'Success','data':allData})
		except Exception as e:
			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class GetTrainerTerms(APIView):
	def get(self,request):
		try:
			content_obj =  ContentManagement.objects.filter(page_type='Terms & conditions',user_type='trainer').first()
			allData=ContentSerializer(content_obj).data
			return Response({'message':'Success','data':allData})
		except Exception as e:
			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		


# Exercise
class GetExerciseList(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			# Read operation - Retrieve all exercise or a list of exercises
			exercise_obj = Exercise.objects.filter(trainer=trainer_obj,end_date__isnull = True)
			exercise_serializer = ExerciseSerializer(exercise_obj, many=True).data
			return Response({'message':'Success','data':exercise_serializer})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class AddExercise(APIView):
	def post(self, request):
		try:
			# Create operation - Add a new exercise
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

			data = request.data
			name = data.get('name')
			description = data.get('description')
			image = data.get('image')
			
			if not name:
				return Response({"message": 'name is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not description:
				return Response({"message": 'description is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not image:
				return Response({"message": 'image is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			exercise_obj = Exercise.objects.create(
					trainer=trainer_obj,
					name=name,
					description=description,
					image=image
				)

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

class EditExercise(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			data = request.query_params
			exercise_id = data.get('exercise_id')
			if not exercise_id:
				return Response({"message": 'exercise_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			exercise_obj = Exercise.objects.filter(id=exercise_id,trainer=trainer_obj,end_date__isnull=True).first()
			exercise_serializer = ExerciseSerializer(exercise_obj).data
			return Response({'message':'Success','data':exercise_serializer})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
	def post(self, request):
		try:
			# Update operation - Update an existing exercise
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

			data = request.data
			exercise_id = data.get('exercise_id')
			name = data.get('name')
			description = data.get('description')
			image = data.get('image')
			
			if not name:
				return Response({"message": 'name is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not description:
				return Response({"message": 'description is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not image:
				return Response({"message": 'image is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not exercise_id:
				return Response({"message": 'exercise_id is required'}, status=status.HTTP_400_BAD_REQUEST)
	
			exercise_obj = Exercise.objects.filter(id=exercise_id, trainer=trainer_obj,end_date__isnull=True).first()
			if not exercise_obj:
				return Response({'message': 'Exercise not found'}, status=status.HTTP_404_NOT_FOUND)
			
			exercise_obj.name=name
			exercise_obj.description=description
			exercise_obj.image=image
			exercise_obj.save()
			return Response({'message':'Success'})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class DeleteExercise(APIView):
	def post(self,request):
		try:
			# Update operation - Update an existing exercise
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

			data = request.data
			exercise_id = data.get('exercise_id')
		   
			
		   
			if not exercise_id:
				return Response({"message": 'exercise_id is required'}, status=status.HTTP_400_BAD_REQUEST)
	
			exercise_obj = Exercise.objects.filter(id=exercise_id, trainer=trainer_obj,end_date__isnull=True).first()
			if not exercise_obj:
				return Response({'message': 'Exercise not found'}, status=status.HTTP_404_NOT_FOUND)
			exercise_obj.end_date=datetime.now()
			exercise_obj.save()
			return Response({'message': 'Exercise deleted successfully'}, status=status.HTTP_200_OK)

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

# Sub exercise 


class GetSubExerciseList(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			# Read operation - Retrieve all exercise or a list of exercises
			data = request.query_params
			exercise_id = data.get('exercise_id')
			if not exercise_id:
				return Response({"message": 'exercise_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			exercise_obj = Exercise.objects.filter(id=exercise_id,trainer=trainer_obj,end_date__isnull=True).first()
			sub_exercise_obj = SubExercise.objects.filter(exercise=exercise_obj,end_date__isnull = True)
			sub_exercise_serializer = SubExerciseSerializer(sub_exercise_obj, many=True).data
			return Response({'message':'Success','data':sub_exercise_serializer})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class AddSubExercise(APIView):
	def post(self, request):
		try:
			# Create operation - Add a new exercise
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

			data = request.data
			exercise_id = data.get('exercise_id')
			name = data.get('name')
			description = data.get('description')
			comments = data.get('comments')
			note = data.get('note')
			focus_area = data.get('focus_area')
			sets = data.get('sets')
			reps = data.get('reps')
			weight = data.get('weight')
			youtube_link = data.get('youtube_link')
			images = data.get('images')
			videos = data.get('videos')
			video_link = data.get('video_link')

			if not exercise_id:
				return Response({"message": 'exercise_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not name:
				return Response({"message": 'name is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not description:
				return Response({"message": 'description is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not comments:
				return Response({"message": 'comments is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not note:
			# 	return Response({"message": 'note is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not focus_area:
				return Response({"message": 'focus_area is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not sets:
				return Response({"message": 'sets is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not reps:
				return Response({"message": 'reps is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not weight:
				return Response({"message": 'weight is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not youtube_link:
			# 	return Response({"message": 'youtube_link is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not images:
			# 	return Response({"message": 'images is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not videos:
			# 	return Response({"message": 'videos is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			exercise_obj = Exercise.objects.filter(id=exercise_id,end_date__isnull=True).first()
			sub_exercise_obj = SubExercise.objects.create(
					exercise=exercise_obj,
					name=name,
					description=description,
					comments = comments,
					note = note,
					focus_area = focus_area,
					sets = sets,
					reps = reps,
					weight = weight,
					youtube_link = youtube_link,
					video_link = video_link,
					images = images,
					videos = videos,
				)

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

class EditSubExercise(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			data = request.query_params
			exercise_id = data.get('exercise_id')
			if not exercise_id:
				return Response({"message": 'exercise_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			sub_exercise_obj = SubExercise.objects.filter(id=exercise_id).first()
			sub_exercise_serializer = SubExerciseSerializer(sub_exercise_obj).data
			return Response({'message':'Success','data':sub_exercise_serializer})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
	def post(self, request):
		try:
			# Update operation - Update an existing exercise
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

			data = request.data
			exercise_id = data.get('exercise_id')
			name = data.get('name')
			description = data.get('description')
			comments = data.get('comments')
			note = data.get('note')
			focus_area = data.get('focus_area')
			sets = data.get('sets')
			reps = data.get('reps')
			weight = data.get('weight')
			youtube_link = data.get('youtube_link')
			images = data.get('images')
			videos = data.get('videos')
			
			if not name:
				return Response({"message": 'name is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not description:
				return Response({"message": 'description is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not exercise_id:
				return Response({"message": 'exercise_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not comments:
				return Response({"message": 'comments is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not note:
			# 	return Response({"message": 'note is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not focus_area:
				return Response({"message": 'focus_area is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not sets:
				return Response({"message": 'sets is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not weight:
				return Response({"message": 'weight is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not reps:
				return Response({"message": 'reps is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not youtube_link:
			# 	return Response({"message": 'youtube_link is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not images:
			# 	return Response({"message": 'images is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not videos:
			# 	return Response({"message": 'videos is required'}, status=status.HTTP_400_BAD_REQUEST)
	
			sub_exercise_obj = SubExercise.objects.filter(id=exercise_id).first()
			if not sub_exercise_obj:
				return Response({'message': 'Exercise not found'}, status=status.HTTP_404_NOT_FOUND)
			
			sub_exercise_obj.name=name
			sub_exercise_obj.description=description
			sub_exercise_obj.comments = comments
			sub_exercise_obj.note = note
			sub_exercise_obj.focus_area = focus_area
			sub_exercise_obj.sets = sets
			sub_exercise_obj.weight = weight 
			sub_exercise_obj.reps = reps
			sub_exercise_obj.youtube_link = youtube_link
			sub_exercise_obj.images=images
			sub_exercise_obj.videos = videos
			sub_exercise_obj.save()
			return Response({'message':'Success'})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class DeleteSubExercise(APIView):
	def post(self, request):
		try:
			# Update operation - Update an existing exercise
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

			data = request.data
			exercise_id = data.get('exercise_id')
			
			
			
			if not exercise_id:
				return Response({"message": 'exercise_id is required'}, status=status.HTTP_400_BAD_REQUEST)
		   
	
			sub_exercise_obj = SubExercise.objects.filter(id=exercise_id).first()
			if not sub_exercise_obj:
				return Response({'message': 'Exercise not found'}, status=status.HTTP_404_NOT_FOUND)
			
			sub_exercise_obj.end_date=datetime.now()
			sub_exercise_obj.save()
			return Response({'message':'Subexercise deleted successfully'})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# Videos 

class GetVideosList(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			# Read operation - Retrieve all exercise or a list of exercises
			videos_obj = Videos.objects.filter(trainer=trainer_obj)
			videos_serializer = VideosSerializer(videos_obj, many=True).data
			return Response({'message':'Success','data':videos_serializer})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class AddVideos(APIView):
	def post(self, request):
		try:
			# Create operation - Add a new exercise
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

			data = request.data
			title = data.get('title')
			media_type = data.get('media_type')
			media_url = data.get('media_url')
			
			if not title:
				return Response({"message": 'title is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not media_type:
				return Response({"message": 'media_type is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not media_url:
				return Response({"message": 'media_url is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			videos_obj = Videos.objects.create(
					trainer=trainer_obj,
					title=title,
					media_type=media_type,
					media_url=media_url,
				)

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

class EditVideos(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			data = request.query_params
			video_id = data.get('video_id')
			if not video_id:
				return Response({"message": 'video_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			videos_obj = Videos.objects.filter(id=video_id,trainer=trainer_obj).first()
			videos_serializer = VideosSerializer(videos_obj).data
			return Response({'message':'Success','data':videos_serializer})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
	def post(self, request):
		try:
			# Update operation - Update an existing exercise
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

			data = request.data
			video_id = data.get('video_id')
			title = data.get('title')
			media_type = data.get('media_type')
			media_url = data.get('media_url')
			
			if not video_id:
				return Response({"message": 'video_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not title:
				return Response({"message": 'title is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not media_type:
				return Response({"message": 'media_type is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not media_url:
				return Response({"message": 'media_url is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			video_obj = Videos.objects.filter(id=video_id, trainer=trainer_obj).first()
			if not video_obj:
				return Response({'message': 'Video not found'}, status=status.HTTP_404_NOT_FOUND)
			
			video_obj.title=title
			video_obj.media_type=media_type
			video_obj.media_url=media_url
			video_obj.save()
			return Response({'message':'Success'})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class AddStudent(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

			data = request.data
			full_name = data.get('full_name')
			email = data.get('email')
			phone_number = data.get('phone_number')
			password = randomPasswordStringFunction()

			if not full_name:
				return Response({'message':'full_name is required'},status=status.HTTP_400_BAD_REQUEST)
			if not email:
				return Response({'message':'email is required'},status=status.HTTP_400_BAD_REQUEST)
			if not phone_number:
				return Response({'message':'phone_number is required'},status=status.HTTP_400_BAD_REQUEST)
			if not password:
				return Response({'message':'password is required'},status=status.HTTP_400_BAD_REQUEST)
		
			student_obj = AppUser.objects.filter(email=email).first()
			if student_obj:
				return Response({"message": "The email is already registered"}, status=status.HTTP_409_CONFLICT)
			
					
			student_obj_number = AppUser.objects.filter(phone_number=phone_number).first()
			if student_obj_number:
				return Response({"message": "The phone number is already registered"}, status=status.HTTP_409_CONFLICT)

			# Password hashing
			new_password = handler.hash(password)

			app_user_obj = AppUser.objects.create(full_name=full_name,email=email,phone_number=phone_number,password=new_password,email_verified=True)
			
			Students.objects.create(app_user=app_user_obj,trainer=trainer_obj,follow_request_status=True)

			subject = "Welcome to FitnessIQ! Get Started Now."
			html_message = render_to_string('student_registered.html', {'email': email,'password':password})
			plain_message = html_message
			from_email = settings.EMAIL_HOST_USER
			to = email
			# mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)

			try:
				mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)
			except Exception as email_error:
				return Response({"message": "Your student has been added, but we encountered an issue sending the verification email. Please contact support for assistance"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

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



class GetStudentList(APIView):
	def get(self, request):
		try:
			uid = authenticated(request)
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

		trainer_obj = Trainer.objects.filter(id=uid).first()
		if not trainer_obj:
			return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
		# Read operation - Retrieve all exercise or a list of exercises
		student_obj = Students.objects.filter(trainer=trainer_obj,follow_request_status=True)
		student_serializer = StudentSerializer(student_obj, many=True).data
		print(student_serializer)
		return Response({'message':'Success','data':student_serializer})
		# except Exception as e:
		# 	return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class GetStudentDetail(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data = request.query_params
			student_id = data.get('student_id')
			if not student_id:
				return Response({"message": 'student_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			student_obj = Students.objects.filter(id=student_id).first()
			if not student_obj:
				return Response({'message': 'Student not found'}, status=status.HTTP_404_NOT_FOUND)
			
			# Serialize the student object using StudentSerializer
			student_serializer = StudentSerializer(student_obj).data
			
			# Additional logic to fetch assessments if needed
			
			return Response({'message': 'Success', 'data': student_serializer})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



class PendingFollowRequestList(APIView):
	def get(self, request):
		try:

			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)

			pending_requests = Students.objects.filter(trainer_id=trainer_obj, follow_request_status=False)
			requests_serializer = StudentSerializer(pending_requests, many=True).data
			
			return Response({'message':'Success','data':requests_serializer})

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



class AcceptFollowRequest(APIView):
	def post(self, request):
		try:
			
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			data = request.data
			follow_request_id = data.get('follow_request_id')
			if not follow_request_id:
				return Response({'message': 'Follow request ID is required'}, status=status.HTTP_400_BAD_REQUEST)

			follow_request = Students.objects.get(id=follow_request_id)
			follow_request.follow_request_status = True
			follow_request.save()
			# push notification
			if follow_request.app_user.notification_status:
				registration_id = follow_request.app_user.fcm_token
				server_key = str(settings.FIREBASE_SERVER_KEY)
				if follow_request.app_user.device_type == 'Android':
					send_push_notification(registration_id, "REQUEST ACCEPTED", trainer_obj.full_name + ' accepted your follow request.')
					
				if follow_request.app_user.device_type == 'Ios':
					send_push_notification(registration_id, "REQUEST ACCEPTED", trainer_obj.full_name + ' accepted your follow request.')
			return Response({'message': 'Follow request accepted successfully'})

		except Students.DoesNotExist:
			return Response({'message': 'Follow request not found'}, status=status.HTTP_404_NOT_FOUND)
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class RejectFollowRequest(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			data = request.data
			follow_request_id = data.get('follow_request_id')
			if not follow_request_id:
				return Response({'message': 'Follow request ID is required'}, status=status.HTTP_400_BAD_REQUEST)

			follow_request = Students.objects.get(id=follow_request_id)
			follow_request.delete()
			# AppUserNotification.objects.create(message=trainer_obj.full_name + ' rejected your follow request.',type="rejected your follow request.",user=follow_request.app_user)
			return Response({'message': 'Follow request rejected successfully'})

		except Students.DoesNotExist:
			return Response({'message': 'Follow request not found'}, status=status.HTTP_404_NOT_FOUND)
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		


class getTrainerNotifications(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			notify_obj = TrainerNotification.objects.filter(trainer=trainer_obj,end_date__isnull = True).order_by('-id')
			notification_count=TrainerNotification.objects.filter(trainer=trainer_obj.id,end_date__isnull = True,is_read=False).count()
			allData=[]
			for notify in notify_obj:
				alldata = {
					'id':notify.id,
					'message': notify.message,
					'notification_type' : notify.type,
					'start_date':timesince(notify.start_date)+' ago',
				}
				allData.append(alldata)
			return Response ({'status_code':status.HTTP_200_OK,'status_message':'','data':allData,'unread_notifications':notification_count})
		except Exception as e:
			return Response({'status_code':status.HTTP_500_INTERNAL_SERVER_ERROR,'status_message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class deleteTrainerNotifications(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			notification_id =  request.data.get('notification_id')
			if not notification_id:
				return Response({'status_code':status.HTTP_400_BAD_REQUEST,'status_message':'Notification Id is required'},status=status.HTTP_400_BAD_REQUEST)
			TrainerNotification.objects.filter(id=notification_id).update(end_date=datetime.now())
			return Response({'status_code':status.HTTP_200_OK,'status_message':'Notification Deleted Successfully'})
		except Exception as e:
			return Response({'status_code':status.HTTP_500_INTERNAL_SERVER_ERROR,'status_message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)



class deleteTrainerAccount(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			trainer_obj.is_account_deleted = True
			trainer_obj.save()
			return Response({'status_code':status.HTTP_200_OK,'status_message':'Account Deleted Successfully'})
		except Exception as e:
			return Response({'status_code':status.HTTP_500_INTERNAL_SERVER_ERROR,'status_message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)



class AddFriend(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			data = request.data
			friend_id = data.get('friend_id')
			if not friend_id:
				return Response({'message':'friend_id is required'},status=status.HTTP_400_BAD_REQUEST)
			try:
				friend = Trainer.objects.get(id=friend_id)
			except Trainer.DoesNotExist:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)

			friendship_request = TrainerFriends.objects.filter(from_user=trainer_obj, to_user=friend).first()
			if not friendship_request:
				friendship_request = TrainerFriends.objects.create(from_user=trainer_obj, to_user=friend, accepted=False)
				
				
				# push notification
				registration_id = friend.fcm_token
				print("registration_id",registration_id)
				server_key = str(settings.FIREBASE_SERVER_KEY)
				if friend.device_type == 'Android':
					print("1111111111111111111111111")
					send_push_notification(registration_id, 'NEW FOLLOW REQUEST RECEIVED', trainer_obj.full_name +' sent you a follow request.')
				if friend.device_type == 'Ios':
					print("2222222222222222222222222")
					
					send_push_notification(registration_id, 'NEW FOLLOW REQUEST RECEIVED', trainer_obj.full_name +' sent you a follow request.')
			
				# end

				# system notification
				TrainerNotification.objects.create(message=trainer_obj.full_name+' sent you a follow request.',type="friend_request_received",trainer=friend)

				return Response({'message': 'success'})
			else:
				return Response({'message': 'Request already sent'})
		except Exception as e:
				return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)



class AcceptRejectRequest(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			data = request.data
			request_id = data.get('request_id')
			status_type = data.get('status')  # 'accept' or 'reject'
			if not request_id:
				return Response({'message': 'Request ID is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not status_type:
				return Response({'message': 'Status is required'}, status=status.HTTP_400_BAD_REQUEST)
			try:
				friendship_request = TrainerFriends.objects.get(id=request_id, accepted=False)
			except TrainerFriends.DoesNotExist:
				return Response({'message': 'Friendship request not found or already accepted'}, status=status.HTTP_404_NOT_FOUND)

			if status_type == 'accept':
				friendship_request.accepted = True
				friendship_request.save()

				# # push notification
				if friendship_request.from_user.notification_status:
					registration_id = friendship_request.from_user.fcm_token
					server_key = str(settings.FIREBASE_SERVER_KEY)
					if friendship_request.from_user.device_type == 'Android':
						send_push_notification(registration_id,  'Request Accepted',f"{trainer_obj.full_name} accepted your follow request.")
					elif friendship_request.from_user.device_type == 'Ios':
						send_push_notification(registration_id,  'Request Accepted',f"{trainer_obj.full_name} accepted your follow request.")

				# end

				# system notification
				TrainerNotification.objects.create(message=f"{trainer_obj.full_name} accepted your follow request.", type="friend_request_accepted", trainer=friendship_request.from_user)

				return Response({'message': 'Friend request accepted'})
			elif status_type == 'reject':
				friendship_request.delete()
				return Response({'message': 'Friend request rejected'})
			else:
				return Response({'message': 'Status type must be accept/reject'}, status=status.HTTP_400_BAD_REQUEST)
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class SentRequestsList(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			friendship_request = TrainerFriends.objects.filter(from_user=trainer_obj, accepted=False)
			all_data = SentFriendListSerializer(friendship_request, many=True).data
			return Response({'message': 'Success', 'data': all_data})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class ReceivedRequestsList(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			received_friendlist = TrainerFriends.objects.filter(to_user=trainer_obj, accepted=False)
			all_data = ReceivedFriendListSerializer(received_friendlist, many=True).data
			return Response({'message': 'Success', 'data': all_data})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



class FriendList(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			friends = TrainerFriends.objects.filter(
				(Q(from_user=trainer_obj) | Q(to_user=trainer_obj)) & Q(accepted=True)
			).select_related('from_user', 'to_user')

			friend_list = []
			for friend in friends:
				friend_user = friend.to_user if friend.from_user == trainer_obj else friend.from_user
				friend_list.append(friend_user)

			all_data = AppTrainerFriendSerializer(friend_list, many=True).data
			return Response({'message': 'Success', 'data': all_data})

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


class SearchFriend(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data = request.query_params
			search = data.get('search')
			if not search:
				return Response({'message': 'Search parameter is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			search_friend = Trainer.objects.filter(Q(full_name__icontains=search) | Q(email__icontains=search), end_date__isnull=True).exclude(id=trainer_obj.id)
			user_data = AppTrainerFriendSerializer(search_friend, many=True, context={'login_user': trainer_obj}).data
			return Response({'message': 'Success', 'data': user_data})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class CancelSentRequest(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data = request.data
			request_id = data.get('request_id')
			if not request_id:
				return Response({'message': 'Request ID is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			try:
				friendship_request = TrainerFriends.objects.get(id=request_id, accepted=False)
			except TrainerFriends.DoesNotExist:
				return Response({'message': 'Friendship request not found or already accepted'}, status=status.HTTP_404_NOT_FOUND)
			
			friendship_request.delete()
			return Response({'message': 'Friend request cancelled'})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)




class AddAssessment(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data = request.data
			name = data.get('name')
			exercise = data.get('exercise')
			completion_time = data.get('completion_time')
			repetitions = data.get('repetitions')
			sets = data.get('sets')
			weight = data.get('weight')
			results = data.get('results')
			notes = data.get('notes')
			images = data.get('images')
			print('images',type(images))

			next_assessment_date = data.get('next_assessment_date')
			videos = data.get('videos')
			youtube_link = data.get('youtube_link')
			student_id = data.get('student_id')
			if not name:
				return Response({'message': 'name is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not exercise:
				return Response({'message': 'exercise is required'}, status=status.HTTP_400_BAD_REQUEST)
		
			exercise_obj =  SubExercise.objects.filter(id=exercise).first()
			if not exercise_obj:
				return Response({'message': 'exercise not found'}, status=status.HTTP_404_NOT_FOUND)
			get_images=ast.literal_eval(exercise_obj.images)
			print('get_images',type(get_images))
			if get_images:
				images=images+get_images
			get_videos=ast.literal_eval(exercise_obj.videos)
			if get_videos:
				videos=videos+get_videos
			# if not completion_time:
			#     return Response({'message': 'completion_time is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not repetitions:
			#     return Response({'message': 'repetitions is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not sets:
			#     return Response({'message': 'sets is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not results:
			#     return Response({'message': 'results is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not notes:
			# 	return Response({'message': 'notes is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not next_assessment_date:
				return Response({'message': 'next_assessment_date is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not images:
			# 	return Response({'message': 'images is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not videos:
			#     return Response({'message': 'videos is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not images:
				return Response({'message': 'add atleast one image'}, status=status.HTTP_404_NOT_FOUND)
			if not videos:
				return Response({'message': 'add atleast one video'}, status=status.HTTP_404_NOT_FOUND)
			assesment_obj = Assesments.objects.create(name = name,exercise = exercise_obj,completion_time = completion_time,
				repetitions=repetitions,sets=sets,results=results,notes=notes,
				next_assessment_date=next_assessment_date,images=images,videos=videos,
				trainer=trainer_obj,youtube_link=youtube_link,weight=weight)
			
			if student_id:
				try:
					student = Students.objects.get(id=student_id)
				except Students.DoesNotExist:
					return Response({'message': 'Student not found'}, status=status.HTTP_404_NOT_FOUND)
				
				assessment_progress = data.get('assessment_progress')
				completed_time = data.get('completed_time')
				# Create the StudentAssessment object
				student_assessment = StudentAssessment.objects.create(
					student=student,
					assessment=assesment_obj,
					assessment_progress=assessment_progress
				)
				if assessment_progress == 'completed':
					student_assessment.total_attempt = 1
					student_assessment.save()
				
					# Create an attempt for the student assessment
					attempt = AssessmentAttempt.objects.create(
						user=student.app_user,
						assessment=student_assessment,
						attempt_number = 1,
						completed_date = date.today(),
						completion_time = completed_time
					)
			
			return Response({'message': 'Success'})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



class EditAssessment(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			assessment_id = request.GET.get('assessment_id')
			if not assessment_id:
				return Response({'message': 'assessment_id is required'}, status=status.HTTP_400_BAD_REQUEST)

			assessment_obj = Assesments.objects.get(id=assessment_id)

			all_data = {
				'id':assessment_obj.id,
				'name':assessment_obj.name,
				'exercise':assessment_obj.exercise.name,
				'exercise_id':assessment_obj.exercise.id,
				'completion_time':assessment_obj.completion_time,
				'completion_time':assessment_obj.completion_time,
				'repetitions':assessment_obj.repetitions,
				'sets':assessment_obj.sets,
				'weight':assessment_obj.weight,
				'results':assessment_obj.results,
				'notes':assessment_obj.notes,
				'next_assessment_date':assessment_obj.next_assessment_date,
				'youtube_link':assessment_obj.youtube_link,
				'images':assessment_obj.images.strip("[]").replace("'", "").split(", ") if assessment_obj.images else [],
				'videos':assessment_obj.videos.strip("[]").replace("'", "").split(", ") if assessment_obj.videos else [],
			}
			return Response({'message': 'Success', 'data': all_data})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		

	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			assessment_id = request.data.get('assessment_id')
			if not assessment_id:
				return Response({'message': 'assessment_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			name = request.data.get('name')
			youtube_link = request.data.get('youtube_link')
			weight = request.data.get('weight')
			if not name:
				return Response({'message': 'name is required'}, status=status.HTTP_400_BAD_REQUEST)
			exercise = request.data.get('exercise')
			if not exercise:
				return Response({'message': 'exercise is required'}, status=status.HTTP_400_BAD_REQUEST)
			exercise_obj =  SubExercise.objects.get(id=exercise)
			if not exercise_obj:
				return Response({'message': 'exercise not found'}, status=status.HTTP_404_NOT_FOUND)

			completion_time = request.data.get('completion_time')
			# if not completion_time:
			#     return Response({'message': 'completion_time is required'}, status=status.HTTP_400_BAD_REQUEST)
			repetitions = request.data.get('repetitions')
			# if not repetitions:
			#     return Response({'message': 'repetitions is required'}, status=status.HTTP_400_BAD_REQUEST)
			sets = request.data.get('sets')
			# if not sets:
			#     return Response({'message': 'sets is required'}, status=status.HTTP_400_BAD_REQUEST)
			results = request.data.get('results')
			# if not results:
			#     return Response({'message': 'results is required'}, status=status.HTTP_400_BAD_REQUEST)
			notes = request.data.get('notes')
			# if not notes:
			# 	return Response({'message': 'notes is required'}, status=status.HTTP_400_BAD_REQUEST)
			next_assessment_date = request.data.get('next_assessment_date')
			if not next_assessment_date:
				return Response({'message': 'next_assessment_date is required'}, status=status.HTTP_400_BAD_REQUEST)
			images = request.data.get('images')
			# if not images:
			# 	return Response({'message': 'images is required'}, status=status.HTTP_400_BAD_REQUEST)
			videos = request.data.get('videos')
			# if not videos:
			#     return Response({'message': 'videos is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			Assesments.objects.filter(id =assessment_id ).update(name = name,exercise = exercise_obj,
						completion_time = completion_time,repetitions=repetitions,results=results,
						notes=notes,next_assessment_date=next_assessment_date,images=images,
						videos=videos,trainer=trainer_obj,youtube_link=youtube_link,weight=weight)
			return Response({'message': 'Success'})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



class DeleteAssessment(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)

			assessment_id = request.data.get('assessment_id')
			if not assessment_id:
				return Response({'message': 'assessment_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			assessment_obj = Assesments.objects.filter(trainer = trainer_obj,id = assessment_id).first()
			if not assessment_obj:
				return Response({'message': 'No assessment found'}, status=status.HTTP_404_NOT_FOUND)
			
			check_assessment = StudentAssessment.objects.filter(assessment_id = assessment_obj).first()
			if check_assessment:
				return Response({'message': 'You cannot delete this assessment as it is already assigned to some student.'}, status=status.HTTP_404_NOT_FOUND)
			
			else:
				assessment_obj.delete()
			
			return Response({'message': 'Success'})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)




class AllAssessmentList(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			

			assessment_obj = Assesments.objects.filter(trainer = trainer_obj).order_by('-id')
			if not assessment_obj:
				return Response({'message': 'No data found'}, status=status.HTTP_404_NOT_FOUND)

			assessment_serializer = GetIdAssessmentSerializer(assessment_obj,many=True).data
			print(assessment_serializer)
			return Response({'message': 'Success', 'data': assessment_serializer})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		

class AssessmentDetails(APIView):
	def get(self, request):	
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			assessment_id = request.GET.get('assessment_id')
			if not assessment_id:
				return Response({'message': 'assessment_id is required'}, status=status.HTTP_400_BAD_REQUEST)

			assessment_obj = Assesments.objects.get(id=assessment_id)
			all_data = GetIdAssessmentSerializer(assessment_obj).data
			# all_data = {
			# 	'id':assessment_obj.id,
			# 	'name':assessment_obj.name,
			# 	'exercise':assessment_obj.name,
			# 	'completion_time':assessment_obj.completion_time,
			# 	'completion_time':assessment_obj.completion_time,
			# 	'repetitions':assessment_obj.repetitions,
			# 	'sets':assessment_obj.sets,
			# 	'results':assessment_obj.results,
			# 	'notes':assessment_obj.notes,
			# 	'next_assessment_date':assessment_obj.next_assessment_date,
			# 	'images':assessment_obj.images.strip("[]").replace("'", "").split(", ") if assessment_obj.images else [],
			# 	'videos':assessment_obj.videos.strip("[]").replace("'", "").split(", ") if assessment_obj.videos else [],
			# }
			return Response({'message': 'Success', 'data': all_data})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class AssignAssessment(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data = request.data

			assessment_id = data.get('assessment_id')
			student_id = data.get('student_id')
			if not assessment_id:
				return Response({'message': 'assessment_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not student_id:
				return Response({'message': 'student_id is required'}, status=status.HTTP_400_BAD_REQUEST)

			try:
				assessment = Assesments.objects.get(id=assessment_id)
			except Assesments.DoesNotExist:
				return Response({'message': 'Assessment not found'}, status=status.HTTP_404_NOT_FOUND)

			try:
				student = Students.objects.get(id=student_id)
			except Students.DoesNotExist:
				return Response({'message': 'Student not found'}, status=status.HTTP_404_NOT_FOUND)

			# Create the StudentAssessment object
			get_student_assessment = StudentAssessment.objects.filter(
				student=student,
				assessment=assessment
			)
			if get_student_assessment:
				return Response({'message': 'assessment already assigned to student'}, status=status.HTTP_400_BAD_REQUEST)

			student_assessment = StudentAssessment.objects.create(
				student=student,
				assessment=assessment
			)
			
			if student.app_user.notification_status:
				registration_id = student.app_user.fcm_token
				if student.app_user.device_type == 'Android':
					send_push_notification(
						registration_id,
						'ASSIGN ASSESSMENT',
						'A new assessment is assigned to you.',
						data={'title': 'ASSIGN ASSESSMENT', 'body': 'A new assessment is assigned to you.', 'assessment_id': '1234'}
					)
				if student.app_user.device_type == 'Ios':
					send_push_notification(registration_id,   'ASSIGN ASSESSMENT', 'A new assessment is assigned to you.')
			
			# AppUserNotification.objects.create(message=f"{trainer_obj.full_name} assigned you an assessment", type="assigned_assessment", user=student.app_user)
			return Response({'message': 'Success'})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		
class DeleteAssignAssessment(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data = request.data

			assessment_id = data.get('assessment_id')
			# student_id = data.get('student_id')
			if not assessment_id:
				return Response({'message': 'assessment_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not student_id:
			# 	return Response({'message': 'student_id is required'}, status=status.HTTP_400_BAD_REQUEST)

			# try:
			# 	assessment = Assesments.objects.get(id=assessment_id)
			# except Assesments.DoesNotExist:
			# 	return Response({'message': 'Assessment not found'}, status=status.HTTP_404_NOT_FOUND)

			# try:
			# 	student = Students.objects.get(id=student_id)
			# except Students.DoesNotExist:
			# 	return Response({'message': 'Student not found'}, status=status.HTTP_404_NOT_FOUND)

			# Create the StudentAssessment object
			student_assessment = StudentAssessment.objects.filter(
				id=assessment_id
			).first()
			if not student_assessment:
				return Response({'message': 'Assigned assessment not found '}, status=status.HTTP_404_NOT_FOUND)
			
			if student_assessment.student.app_user.notification_status:
				registration_id =student_assessment.student.app_user.fcm_token
				if student_assessment.student.app_user.device_type == 'Android':
					send_push_notification(registration_id, 'Deleted ASSESSMENT', 'The assigned assessment has been deleted.')
				if student_assessment.student.app_user.device_type == 'Ios':
					send_push_notification(registration_id, 'Deleted ASSESSMENT', 'The assigned assessment has been deleted.')
			student_assessment.delete()
			

			
			# AppUserNotification.objects.create(message=f"{trainer_obj.full_name} assigned you an assessment", type="assigned_assessment", user=student.app_user)
			return Response({'message': 'Assessment deleted successfully'})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		

class StudentAssignedAssessments(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data = request.query_params

			student_id = data.get('student_id')
			if not student_id:
				return Response({'message': 'student_id is required'}, status=status.HTTP_400_BAD_REQUEST)

			try:
				student = Students.objects.get(id=student_id)
			except Students.DoesNotExist:
				return Response({'message': 'Student not found'}, status=status.HTTP_404_NOT_FOUND)

			# Create the StudentAssessment object
			student_assessment = StudentAssessment.objects.filter(
				student=student
			).order_by('-id')
			student_serializer = GetIdStudentAssessmentSerializer(student_assessment,many=True).data
			
			return Response({'message': 'Success','data':student_serializer})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class StudentAssignedAssessmentDetail(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data = request.query_params

			student_assessment_id = data.get('student_assessment_id')
			if not student_assessment_id:
				return Response({'message': 'student_assessment_id is required'}, status=status.HTTP_400_BAD_REQUEST)


			# Create the StudentAssessment object
			student_assessment = StudentAssessment.objects.filter(
				id=student_assessment_id
			).first()
			if not student_assessment:
				return Response({'message': 'StudentAssessment not found'}, status=status.HTTP_404_NOT_FOUND)
			student_serializer = GetIdStudentAssessmentSerializer(student_assessment).data
			
			return Response({'message': 'Success','data':student_serializer})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class ChangeAssessmentProgress(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data = request.data

			student_assessment_id = data.get('student_assessment_id')
			assessment_progress = data.get('assessment_progress')
			completed_time = data.get('completed_time')
			repetitions = data.get('repetitions')
			sets = data.get('sets')
			weight = data.get('weight')
			
			
			if not student_assessment_id:
				return Response({'message': 'student_assessment_id is required'}, status=status.HTTP_400_BAD_REQUEST)

			try:
				student_assessment = StudentAssessment.objects.get(id=student_assessment_id)
			except StudentAssessment.DoesNotExist:
				return Response({'message': 'StudentAssessment not found'}, status=status.HTTP_404_NOT_FOUND)

			student_assessment.assessment_progress = assessment_progress
			student_assessment.save()

			# Get the last attempt number for the assessment
			last_attempt = AssessmentAttempt.objects.filter(assessment_id=student_assessment_id).order_by('-attempt_number').first()
			if last_attempt:
				next_attempt_number = last_attempt.attempt_number + 1 if last_attempt else 1
			else:
				next_attempt_number = 1

			from datetime import datetime
			if completed_time:
				assessment_obj = Assesments.objects.get(id = student_assessment.assessment_id)
				total_time = assessment_obj.completion_time
				completed_time_str = str(completed_time)
				total_time_str = str(total_time)
				completed_time_new = datetime.strptime(completed_time_str, '%H:%M:%S')
				total_time = datetime.strptime(total_time_str, '%H:%M:%S')
				time_difference = total_time - completed_time_new
				total_seconds_difference = (time_difference.days * 86400) + time_difference.seconds  
				total_seconds_total_time = (total_time.hour * 3600) + (total_time.minute * 60) + total_time.second
				fraction_completion = total_seconds_difference / total_seconds_total_time
				percentage_completed = fraction_completion * 100
				
				if percentage_completed > 100:
					percentage_completed = 100
				elif percentage_completed < 0:
					percentage_completed = 0

			else:
				assessment_obj = Assesments.objects.get(id = student_assessment.assessment_id)
				completed_sets = int(sets) 
				completed_reps = int(repetitions)
				total_sets_planned = int(assessment_obj.sets)
				reps_per_set_planned = int(assessment_obj.repetitions)
				total_reps_completed = (completed_sets * reps_per_set_planned) + completed_reps
				total_reps_planned = total_sets_planned * reps_per_set_planned
				percentage_completed = (total_reps_completed / total_reps_planned) * 100

				if percentage_completed > 100:
					percentage_completed = 100
				elif percentage_completed < 0:
					percentage_completed = 0

			attempt = AssessmentAttempt.objects.create(user=student_assessment.student.app_user, 
				assessment=student_assessment, attempt_number=next_attempt_number,sets=sets,
				repetitions=repetitions,weight=weight,
				completion_time = completed_time,completed_date = date.today(),complete_percent =percentage_completed )


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



class WorkoutPlanCreate(APIView):
	def post(self, request, *args, **kwargs):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data =  request.data

			name = data.get('name')
			goal = data.get('goal')
			description = data.get('description')
			notes = data.get('notes')
			image = data.get('image')
			duration_type = data.get('duration_type')
			duration_minutes = data.get('duration_minutes')
			duration_weeks = data.get('duration_weeks')
			work_access = data.get('work_access')

			if not name:
				return Response({'message': 'name is required'}, status=status.HTTP_400_BAD_REQUEST)
		  
			if not description:
				return Response({'message': 'description is required'}, status=status.HTTP_400_BAD_REQUEST)
		   
			
			if not duration_type:
				return Response({'message': 'duration_type is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			if not work_access:
				return Response({'message': 'work_access is required'}, status=status.HTTP_400_BAD_REQUEST)

			
			if duration_type == 'week':
				print("here")
				workout_plan = WorkoutPlan.objects.create(trainer=trainer_obj,name=name,goal=goal,
					description=description,notes=notes,image=image,duration_weeks=duration_weeks,duration_type=duration_type,work_access=work_access)
			else:
				print("here else")
				workout_plan = WorkoutPlan.objects.create(trainer=trainer_obj,name=name,goal=goal,
					description=description,notes=notes,image=image,duration_minutes=duration_minutes,duration_type=duration_type,work_access=work_access)
			
			workout_plan_serializer = WorkoutPlanSerializer(workout_plan).data
			return Response({'message': 'Success','data':workout_plan_serializer})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



class WorkoutWeekCreate(APIView):
	def post(self, request, *args, **kwargs):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data =  request.data

			workout_id = data.get('workout_id')
			body_part = data.get('body_part')
			week_number = data.get('week_number')
			day_name = data.get('day_name')
			# exercise_id = data.get('exercise_id')
			# sets = data.get('sets')
			# reps = data.get('reps')
			# weight = data.get('weight')
			# weight = data.get('weight')
			exercise_data = data.get('exercise_data')

		
			if not workout_id:
				return Response({'message': 'workout_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not body_part:
				return Response({'message': 'body_part is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			if not day_name:
				return Response({'message': 'day_name is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not exercise_id:
			#     return Response({'message': 'exercise_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			if not exercise_data:
				return Response({'message': 'exercise_data is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			# if not sets:
			#     return Response({'message': 'sets is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not reps:
			#     return Response({'message': 'reps is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not weight:
			#     return Response({'message': 'weight is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			workout_plan = WorkoutPlan.objects.filter(id=workout_id,trainer=trainer_obj).first()
			if not workout_plan:
				return Response({'message': 'Workout Plan not found'}, status=status.HTTP_404_NOT_FOUND)
			
			# exercise_obj =  SubExercise.objects.filter(id=exercise_id).first()
			# if not exercise_obj:
			#     return Response({'message': 'exercise not found'}, status=status.HTTP_404_NOT_FOUND)


			# Check if a week with the given week number already exists for the workout plan
			workout_week = WorkoutWeek.objects.filter(plan=workout_plan, week_number=week_number).first()
			if not workout_week:
				# If week does not exist, create a new week
				workout_week = WorkoutWeek.objects.create(plan=workout_plan, week_number=week_number)

			# Check if a day with the given name already exists for the week
			workout_day = WorkoutDay.objects.filter(week=workout_week, name=day_name).first()
			if not workout_day:
				# If day does not exist, create a new day
				workout_day = WorkoutDay.objects.create(week=workout_week, name=day_name)

			# Create plan exercise for the day
			plan_exercise = PlanExercise.objects.create(day=workout_day,body_part=body_part,exercise_data=exercise_data)
			
			workout_plan_serializer = WorkoutPlanSerializer(workout_plan).data
			

			return Response({'message': 'Success','data':workout_plan_serializer})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)




class WorkoutWeekDetail(APIView):
	def get(self, request, *args, **kwargs):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data =  request.query_params
			workout_id = data.get('workout_id')

			if not workout_id:
				return Response({'message': 'workout_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			workout_plan = WorkoutPlan.objects.filter(id=workout_id,trainer=trainer_obj).first()

			if not workout_plan:
				return Response({'message': 'Workout Plan not found'}, status=status.HTTP_404_NOT_FOUND)
			
			workout_plan_serializer = WorkoutPlanSerializer(workout_plan).data
			print(workout_plan_serializer)
			feedback=CreateStudentFeedback.objects.filter(trainer=trainer_obj,workout=workout_plan).values('student__app_user__full_name','student__app_user__image','feedback')
			print(feedback)
			workout_plan_serializer['feedbacks'] = list(feedback)

# Now `workout_plan_serializer` contains the workout data with feedbacks included
			print(workout_plan_serializer)

			return Response({'message': 'Success','data':workout_plan_serializer})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class GetAllSubExerciseList(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			sub_exercise_obj = SubExercise.objects.filter(exercise__trainer=trainer_obj)
			sub_exercise_serializer = SubExerciseSerializer(sub_exercise_obj, many=True).data
			return Response({'message':'Success','data':sub_exercise_serializer})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class WorkOutList(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			workout_plan_obj = WorkoutPlan.objects.filter(trainer=trainer_obj)
			workout_plan_serializer = WorkoutPlanListSerializer(workout_plan_obj, many=True).data
			return Response({'message':'Success','data':workout_plan_serializer})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



class WorkoutPlanEdit(APIView):
	def post(self, request, *args, **kwargs):
		try:
			# Authenticate the user
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			# Get workout plan ID from URL kwargs
			data =  request.data
			workout_plan_id = data.get('workout_plan_id')
			if not workout_plan_id:
				return Response({'message': 'workout_plan_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			# Retrieve the workout plan to be edited
			workout_plan = WorkoutPlan.objects.filter(id=workout_plan_id, trainer=trainer_obj).first()
			if not workout_plan:
				return Response({'message': 'Workout Plan not found'}, status=status.HTTP_404_NOT_FOUND)
			
			# Update workout plan fields based on request data
			data = request.data
			workout_plan.name = data.get('name', workout_plan.name)
			workout_plan.goal = data.get('goal', workout_plan.goal)
			workout_plan.description = data.get('description', workout_plan.description)
			workout_plan.notes = data.get('notes', workout_plan.notes)
			workout_plan.image = data.get('image', workout_plan.image)
			workout_plan.work_access = data.get('work_access', workout_plan.work_access)



			workout_plan.duration_type = data.get('duration_type', workout_plan.duration_type)
			if  data.get('duration_type') == 'week':
				workout_plan.duration_minutes = 0
				workout_plan.duration_weeks = data.get('duration_weeks', workout_plan.duration_weeks)
			else:
				workout_plan.duration_minutes = data.get('duration_minutes', workout_plan.duration_minutes)   
				workout_plan.duration_weeks = 0
			# Save the updated workout plan
			workout_plan.save()
			
			data={
				"id": workout_plan.id,
				"trainer_id": workout_plan.trainer_id,
				"name": workout_plan.name,
				"goal": workout_plan.goal,
				"description": workout_plan.description,
				"notes": workout_plan.notes,
				"image": workout_plan.image,
				"duration_type": workout_plan.duration_type,
				"duration_minutes": workout_plan.duration_minutes,
				"duration_weeks": workout_plan.duration_weeks,
				"work_access": workout_plan.work_access,
				"likes": workout_plan.likes,
				"created_at":workout_plan.created_at,
				"updated_at": workout_plan.updated_at,
				"end_date": workout_plan.end_date
			}
			return Response({'message': 'Workout Plan updated successfully', 'data': data})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class WorkoutWeekEdit(APIView):
	def post(self, request, *args, **kwargs):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data =  request.data

			workout_id = data.get('workout_id')
			body_part = data.get('body_part')
			week_number = data.get('week_number')
			day_name = data.get('day_name')
			exercise_id = data.get('exercise_id')
			# sets = data.get('sets')
			# reps = data.get('reps')
			# weight = data.get('weight')
			# weight = data.get('weight')
			exercise_data = data.get('exercise_data')

			
			if not workout_id:
				return Response({'message': 'workout_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not body_part:
				return Response({'message': 'body_part is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not week_number:
				return Response({'message': 'week_number is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not day_name:
				return Response({'message': 'day_name is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not exercise_id:
			#     return Response({'message': 'exercise_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not sets:
			#     return Response({'message': 'sets is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not reps:
			#     return Response({'message': 'reps is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			workout_plan = WorkoutPlan.objects.filter(id=workout_id, trainer=trainer_obj).first()
			if not workout_plan:
				return Response({'message': 'Workout Plan not found'}, status=status.HTTP_404_NOT_FOUND)
			
			exercise_obj =  SubExercise.objects.filter(id=exercise_id).first()
			if not exercise_obj:
				return Response({'message': 'Exercise not found'}, status=status.HTTP_404_NOT_FOUND)

			# Check if a week with the given week number already exists for the workout plan
			workout_week, created = WorkoutWeek.objects.get_or_create(plan=workout_plan, week_number=week_number)
			print(workout_week)
			
			# Check if a day with the given name already exists for the week
			workout_day, created = WorkoutDay.objects.get_or_create(week=workout_week, name=day_name)
			print(workout_day)
			# Check if there's already a plan exercise for the day, if yes, update it
			plan_exercise, created = PlanExercise.objects.get_or_create(day=workout_day)
			print("here1")
			plan_exercise.exercise_data = exercise_data
			print("here2")
			# plan_exercise.reps = reps
			plan_exercise.body_part = body_part
			print("here3")

			plan_exercise.save()
			
			# workout_plan_serializer = WorkoutPlanSerializer(workout_plan).data
			# print(workout_plan_serializer)

			
			return Response({'message': 'Success', 'data': workout_plan})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class PlanExerciseEdit(APIView):
	def post(self, request, *args, **kwargs):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data =  request.data
			workout_id = data.get('workout_id')
			plan_exercise_id = data.get('plan_exercise_id')
			body_part = data.get('body_part')
			exercise_data = data.get('exercise_data')

			
			if not plan_exercise_id:
				return Response({'message': 'plan_exercise_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not body_part:
				return Response({'message': 'body_part is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not exercise_data:
				return Response({'message': 'exercise_data is required'}, status=status.HTTP_400_BAD_REQUEST)

		
			workout_plan = WorkoutPlan.objects.filter(id=workout_id, trainer=trainer_obj).first()
			if not workout_plan:
				return Response({'message': 'Workout Plan not found'}, status=status.HTTP_404_NOT_FOUND)


			# Check if there's already a plan exercise for the day, if yes, update it
			plan_exercise = PlanExercise.objects.get(id=plan_exercise_id)
			plan_exercise.exercise_data=exercise_data
			plan_exercise.body_part = body_part
			plan_exercise.save()
			
			workout_plan_serializer = WorkoutPlanSerializer(workout_plan).data
			
			return Response({'message': 'Success', 'data': workout_plan_serializer})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		
class AssignWorkOut(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data = request.data

			workout_id = data.get('workout_id')
			student_id = data.get('student_id')
			if not workout_id:
				return Response({'message': 'workout_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not student_id:
				return Response({'message': 'student_id is required'}, status=status.HTTP_400_BAD_REQUEST)

			try:
				workout = WorkoutPlan.objects.get(id=workout_id)
			except WorkoutPlan.DoesNotExist:
				return Response({'message': 'Assessment not found'}, status=status.HTTP_404_NOT_FOUND)

			try:
				student = Students.objects.get(id=student_id)
			except Students.DoesNotExist:
				return Response({'message': 'Student not found'}, status=status.HTTP_404_NOT_FOUND)

			# Create the StudentWorkout object
			get_workout=StudentWorkOutPlan.objects.filter(
				student=student,
				workout=workout
			).first()
			if get_workout:
				return Response({'message': 'workout already assigned to student'}, status=status.HTTP_404_NOT_FOUND)
			
			create_workout=StudentWorkOutPlan.objects.create(
				student=student,
				workout=workout
			)
			if student.app_user.notification_status:
				registration_id = student.app_user.fcm_token
				server_key = str(settings.FIREBASE_SERVER_KEY)
				if student.app_user.device_type == 'Android':
					
					send_push_notification(registration_id,  'ASSIGN WORKOUT', 'A new workout is assigned to you.')
				if student.app_user.device_type == 'Ios':
					send_push_notification(registration_id,  'ASSIGN WORKOUT', 'A new workout is assigned to you.')
			return Response({'message': 'Success'})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class DeleteAssignWorkOut(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data = request.data

			workout_id = data.get('workout_id')
			# student_id = data.get('student_id')
			# if not workout_id:
			# 	return Response({'message': 'workout_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not student_id:
			# 	return Response({'message': 'student_id is required'}, status=status.HTTP_400_BAD_REQUEST)

			# try:
			# 	workout = WorkoutPlan.objects.get(id=workout_id)
			# except WorkoutPlan.DoesNotExist:
			# 	return Response({'message': 'Workout not found'}, status=status.HTTP_404_NOT_FOUND)

			# try:
			# 	student = Students.objects.get(id=student_id)
			# except Students.DoesNotExist:
			# 	return Response({'message': 'Student not found'}, status=status.HTTP_404_NOT_FOUND)

			# Create the StudentWorkout object
			get_workout=StudentWorkOutPlan.objects.filter(
				  id=workout_id,
			).first()
			if not get_workout:
				return Response({'message': 'No workout assigned found'}, status=status.HTTP_404_NOT_FOUND)
			if get_workout.student.app_user.notification_status:
				registration_id =get_workout.student.app_user.fcm_token
				if get_workout.student.app_user.device_type == 'Android':
					send_push_notification(registration_id, 'Deleted WORKOUT', 'The assigned workout has been deleted.')
				if get_workout.student.app_user.device_type == 'Ios':
					send_push_notification(registration_id, 'Deleted WORKOUT', 'The assigned workout has been deleted.')
			get_workout.delete()
			return Response({'message': 'Assigned workout deleted successfully'})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		
		
class CreateConversationwithStudent(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message':str(e)},status=status.HTTP_401_UNAUTHORIZED)
			print(uid)
			trainer_obj = Trainer.objects.get(id=uid)
			print(trainer_obj)
			# student_obj = Students.objects.get(app_user=user)
			
			if not trainer_obj:
				return Response({'message': 'trainer_obj not found'}, status=status.HTTP_404_NOT_FOUND)
			
			student_id=request.data.get('student_id')
			print(student_id)
			if not student_id:
				return Response({'status_code': status.HTTP_400_BAD_REQUEST, 'status_message': 'student_id is required.','id':student_id})
			
			
			# student_obj = Students.objects.get(app_user=user)
			student_obj = AppUser.objects.filter(id=student_id).first()   
			if not student_obj:
				return Response({'status_code': status.HTTP_400_BAD_REQUEST, 'status_message': 'No student found'})
			
			existing_conversation = Conversation.objects.filter(student=student_obj.id, trainer=trainer_obj.id).first()
			if existing_conversation:
				twilio_channel_sid = existing_conversation.conversation_room_id
				existing_conversation.is_read = True
				existing_conversation.save()
				is_read=existing_conversation.is_read
			else:
				concatinate_names= str(trainer_obj.full_name) + str(student_obj.full_name) + str(student_obj.id) + str(trainer_obj.id)
				suffle_string = list(concatinate_names)
				random.shuffle(suffle_string)
				conversation_name = ''.join(suffle_string)
				account_sid = settings.TWILIO_ACCOUNT_SID
				# print(account_sid)
				auth_token = settings.TWILIO_AUTH_TOKEN
				client = Client(account_sid, auth_token)
				# Create Conversation chat
				conversation = client.conversations \
						.v1 \
						.conversations \
						.create(friendly_name=conversation_name)
				

				conversation_obj = Conversation.objects.create(student=student_obj,trainer=trainer_obj )
				conversation_obj.conversation_room_id = conversation.sid
				conversation_obj.last_message = datetime.now()
				conversation_obj.save()

				student_attributes= {"id":str(student_obj.id),"name":str(student_obj.full_name),
					"image":str(student_obj.image)
				}
				student_json_attributes = json.dumps(student_attributes)

				student_participant = client.conversations \
					.v1 \
					.conversations(conversation.sid) \
					.participants \
					.create(identity=str(student_obj.id),attributes=student_json_attributes)
				

				trainer_attributes= {"id":str(trainer_obj.id),"name":str(trainer_obj.full_name),
					"image":str(trainer_obj.image)
				}
				trainer_attributes_json_attributes = json.dumps(trainer_attributes)

				trainer_attributes_participant = client.conversations \
					.v1 \
					.conversations(conversation.sid) \
					.participants \
					.create(identity=str(trainer_obj.id),attributes=trainer_attributes_json_attributes)

				conversation_obj.student_twilio_id = student_participant.sid
				conversation_obj.trainer_twilio_id = trainer_attributes_participant.sid
				conversation_obj.is_read = True
				conversation_obj.save()
				is_read=conversation_obj.is_read 

				twilio_channel_sid = conversation_obj.conversation_room_id


			return Response ({'status_code':status.HTTP_200_OK,'status_message':'success','twilio_channel_sid':twilio_channel_sid,'is_read':is_read})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		

		
# class GetTrainerConversationsView(APIView):
#     def get(self,request):
#             try:
#                 try:
#                     uid = authenticated(request)
#                 except Exception as e:
#                     return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
#                 trainer_obj = Trainer.objects.filter(id=uid).first()
#                 # student_obj = Students.objects.get(app_user=user)
#                 if not trainer_obj:
#                     return Response({'message': 'User not found'}, status=status.HTTP_404_NOT_FOUND)
	
#                 get_conversation =  Conversation.objects.filter(trainer=trainer_obj).values('id','conversation_room_id','student_twilio_id','trainer_twilio_id','created_at','updated_at','student','trainer',
#                                                                                             'student__app_user__full_name','trainer__full_name','student__app_user__image','trainer__image').order_by('id')
#                 all_data=[]
#                 for conversations in get_conversation: 
#                     conversations['student_full_name']=conversations.pop('student__app_user__full_name')
#                     conversations['trainer_full_name']=conversations.pop('trainer__full_name')
#                     conversations['student_image']=conversations.pop('student__app_user__image')
#                     conversations['trainer_image']=conversations.pop('trainer__image')
#                     all_data.append(conversations)
#                 return Response({'message':'Success','all_data':all_data})
				
#             except Exception as e:
#                 return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class CreateFavourateSubCategory(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
				
			app_user_obj = AppUser.objects.filter(id=uid).first()
			if not app_user_obj:
				return Response({'message': "User not found"})
			discover_subcategory_id=request.GET.get('discover_subcategory_id')
			is_deleted=request.GET.get('is_deleted')
			
			try:
				discover_subcategory_obj=DiscoverSubCategory.objects.get(id=discover_subcategory_id)
			except Exception as e:
					return Response({'message': f"{e}"})
			try:
				check_favourite_subcategory=FavouriteDiscoverSubCategory.objects.get(user=app_user_obj,
					discover_sub_category=discover_subcategory_obj)
				if check_favourite_subcategory:
					if is_deleted:
					
						check_favourite_subcategory.is_deleted=True
						check_favourite_subcategory.updated_at=datetime.now()
						check_favourite_subcategory.save()
						return Response({'message': "Favourate Subcategory Deleted",
				'deleted':True})
					else:
						check_favourite_subcategory.is_deleted=False
						check_favourite_subcategory.updated_at=datetime.now()
						check_favourite_subcategory.save()
						return Response({'message': "Favourate Subcategory Created",'deleted':False})
			except:
				FavouriteDiscoverSubCategory.objects.create(
					user=app_user_obj,
					discover_sub_category=discover_subcategory_obj,
					is_deleted=False
				)
			return Response({'message': "Favourate Subcategory Created"})
		except Exception as e:
		   return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class GetFavouriteSubCategory(APIView):
	def get(self,request):
				try:
					try:
						uid = authenticated(request)
					except Exception as e:
						return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
					
					app_user_obj = AppUser.objects.filter(id=uid).first()
					# student_obj = Students.objects.get(app_user=user)
					student_obj = Students.objects.filter( app_user=app_user_obj).first()
					if not student_obj:
						return Response({'message': 'User not found'}, status=status.HTTP_404_NOT_FOUND)
			
					
					get_favourite_subcategory =  FavouriteDiscoverSubCategory.objects.filter(user=app_user_obj).values('user','discover_sub_category','is_deleted','created_at','updated_at',
													  'discover_sub_category__main_category',
													 'discover_sub_category__title',
													  'discover_sub_category__description',
													   'discover_sub_category__image',
														'discover_sub_category__start_date',
														'discover_sub_category__end_date',
														  ).order_by('id')
													   
					all_data=[]
					for favourite in get_favourite_subcategory: 
						favourite['discover_sub_main_category']=favourite.pop('discover_sub_category__main_category')
						favourite['discover_sub_category_title']=favourite.pop('discover_sub_category__title')
						favourite['discover_sub_category_description']=favourite.pop('discover_sub_category__description')
						favourite['discover_sub_category_image']=favourite.pop('discover_sub_category__image')
						favourite['discover_sub_category_start_date']=favourite.pop('discover_sub_category__start_date')
						favourite['discover_sub_category_end_date']=favourite.pop('discover_sub_category__end_date')
						all_data.append(favourite)
					return Response({'message':'Success','all_data':all_data})
				except Exception as e:
					return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
			
class CreateTrainerAccessToken(APIView):
		def post(self,request):
			try:
				try:
					uid = authenticated(request)
				except Exception as e:
					return Response({'message':str(e)},status=status.HTTP_401_UNAUTHORIZED)
				print(uid)
				trainer_obj = Trainer.objects.get(id=uid)
				print(trainer_obj)
				# student_obj = Students.objects.get(app_user=user)
				
				if not trainer_obj:
					return Response({'message': 'trainer_obj not found'}, status=status.HTTP_404_NOT_FOUND)
				
				identity = trainer_obj.id
				token = AccessToken(account_sid,api_sid,api_secret,identity=identity)

				if chat_service_sid:
					chat_grant = ChatGrant(service_sid=chat_service_sid)
					token.add_grant(chat_grant)

				notification = client.conversations \
				.v1 \
				.services(chat_service_sid) \
				.configuration \
				.notifications() \
				.update(
					new_message_enabled=True,
					new_message_sound='default',
					new_message_template="You have a new message in ${CONVERSATION}: ${MESSAGE}"
				)

				alldata = {
				'identity':identity,
				'token':token.to_jwt(),
				}
				return Response ({'status_code':status.HTTP_200_OK,'status_message':'Token Created Successfully','data':alldata})
		
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class GetTrainerConversation(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message':str(e)},status=status.HTTP_401_UNAUTHORIZED)
			trainer_obj = Trainer.objects.filter(id=uid).first()
					# student_obj = Students.objects.get(app_user=user)
			
			if not trainer_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			conversations = Conversation.objects.filter(trainer = trainer_obj)
			account_sid = settings.TWILIO_ACCOUNT_SID
			auth_token = settings.TWILIO_AUTH_TOKEN
			client = Client(account_sid, auth_token)
			conversation_list = []
			for conversation in conversations:
				messages = client.conversations \
				  .v1 \
				  .conversations(conversation.conversation_room_id) \
				  .messages \
				  .list(order='desc', limit=1)
				last_message = ''
				time = ''
				message_date = ''
				for record in messages:
					if record.body:
						last_message = record.body
						time = timesince(record.date_created)+' ago'
						message_date = record.date_created
					elif record.media:
						
						last_message = 'file'
						time = timesince(record.date_created)+' ago'
						message_date = record.date_created
				
				conversation_data = {
					"id": conversation.id,
					"twilio_channel_sid": conversation.conversation_room_id,
					"customer_name": conversation.student.full_name,
					"customer_image": conversation.student.image,
					"customer_id":conversation.student.id,
					"trainer_name": conversation.trainer.full_name,
					"trainer_image": conversation.trainer.image,
					"trainer_id": conversation.trainer.id,
					"last_message":last_message,
					"time":time,
					"message_date":message_date,
					"is_read":conversation.is_read
				}
				conversation_list.append(conversation_data)
			return Response ({'status_code':status.HTTP_200_OK,'status_message':'success','data':conversation_list})    
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		
class GetWorkoutFeedback(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			workout_id=request.GET.get('workout_id')
			if not workout_id:
				return Response({'message': 'workout_id not found'}, status=status.HTTP_404_NOT_FOUND)
			workout_obj=WorkoutPlan.objects.filter(id=workout_id).first()
			if not workout_obj:
				return Response({'message': 'workout_obj not found'}, status=status.HTTP_404_NOT_FOUND)
			
			feedback = CreateStudentFeedback.objects.filter(workout=workout_obj).values("student__app_user__full_name","student__app_user__image","feedback","created_at")
			
			return Response({'message':'Success','data':feedback})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class SaveTrainerBankDetails(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data = request.data

			
			account_number = data.get('account_number')
			routing_number = data.get('routing_number')
			bank_name = data.get('bank_name')
			holder_name = data.get('holder_name')
			address = data.get('address')
			phone_number = data.get('phone_number')
			account_type = data.get('account_type')
			if not account_type:
				return Response({'message': 'account_type is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not account_number:
				return Response({'message': 'account_number is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not routing_number:
				return Response({'message': 'routing_number is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not bank_name:
				return Response({'message': 'bank_name is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not holder_name:
				return Response({'message': 'holder_name is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not address:
				return Response({'message': 'address is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not phone_number:
				return Response({'message': 'phone_number is required'}, status=status.HTTP_400_BAD_REQUEST)
			

			check_account_exists=TrainerBankDetails.objects.filter(trainer=trainer_obj,account_number=account_number)
			if not check_account_exists.exists():
				TrainerBankDetails.objects.create(
					trainer=trainer_obj,
					account_number=account_number,
					routing_number=routing_number,
					bank_name=bank_name,
					holder_name=holder_name,
					address=address,
					phone_number=phone_number,
					account_type=account_type

				)
				return Response({'message': 'Success'})
			else:
				check_account_exists.update(routing_number=routing_number,
				bank_name=bank_name,
				holder_name=holder_name,
				phone_number=phone_number,
				address=address,
				account_type=account_type)

				
				return Response({'message': 'Account updated successfully'})

			
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		
class GetTrainerBankDetails(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			account=TrainerBankDetails.objects.filter(trainer=trainer_obj).values()
			if not account.exists():
				return Response({'message': 'Back details does not exist'})
			else:
				return Response({'message':'Success','data':account})
			
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class GetTrainerWallet(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			get_wallet=TrainerWallet.objects.filter(trainer=trainer_obj)
			if not get_wallet.exists():
				return Response({'message': 'get_wallet does not exist'})
			else:
				return Response({'message':'Success','data':get_wallet.values()})
			
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
	
class RequestMoney(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			
			data = request.data

			amount = data.get('amount')
			if not amount:
				return Response({'message': 'amount is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			try:
				Requestmoney.objects.create(
					trainer=trainer_obj,
					requested_money=amount,
					status='pending'
					
				)
				return Response({'message': 'Requestmoney created'}, status=status.HTTP_400_BAD_REQUEST)
			except Exception as e:
				return Response({'message': f'{e}'})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		
class TrainerDashboard(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			total_workouts=WorkoutPlan.objects.filter(trainer=trainer_obj,end_date__isnull=True).count()
			total_assessments=Assesments.objects.filter(trainer=trainer_obj,end_date__isnull=True).count()
			total_clients=Students.objects.filter(trainer=trainer_obj,end_date__isnull=True).count()
			total_data={
				'total_workouts':total_workouts,
				'total_assessments':total_assessments,
				'total_clients':total_clients

			}
			return Response({'data':total_data }, status=status.HTTP_200_OK)
			
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		
class ReadNotifications(APIView):
		def post(self,request):
			try :
				try:
					uid = authenticated(request)
				except Exception as e:
					return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
				
				trainer_obj = Trainer.objects.filter(id=uid).first()
				if not trainer_obj:
					return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
				notification=TrainerNotification.objects.update(is_read=True)
				return Response({'message': ''}, status=status.HTTP_404_NOT_FOUND)
				
				
			except Exception as e:
				return Response({e}, status=status.HTTP_404_NOT_FOUND)

class Showstudentfeedback(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			feedback=CreateStudentFeedback.objects.filter(trainer=trainer_obj).values()
			return Response({'data':feedback }, status=status.HTTP_200_OK)
			
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		
class Calculateprivateworkoutperformance(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			workout_id=request.GET.get('workout_id')
			user_id=request.GET.get('user_id')
			workout_week=request.GET.get('workout_week')
			if not workout_id:
				return Response({'message': 'workout_id not found'}, status=status.HTTP_404_NOT_FOUND)
			if not user_id:
				return Response({'message': 'user_id not found'}, status=status.HTTP_404_NOT_FOUND)
			if not workout_week:
				return Response({'message': 'workout_week not found'}, status=status.HTTP_404_NOT_FOUND)
			get_user=AppUser.objects.filter(id=user_id,end_date__isnull=True).first()
			get_workout=WorkoutPlan.objects.filter(id=workout_id,end_date__isnull=True).first()
			get_student_workout=StudentWorkOutPlan.objects.filter(workout=get_workout,end_date__isnull=True).first()

			if not get_user:
				return Response({'message': 'user with user_id not found'}, status=status.HTTP_404_NOT_FOUND)
			if not get_workout:
				return Response({'message': 'workout with workout_id not found'}, status=status.HTTP_404_NOT_FOUND)
			today = timezone.now().date()


			start_of_week = today - timedelta(days=today.weekday())

			# Calculate the end of the week (e.g., Sunday)
			end_of_week = start_of_week + timedelta(days=6)


			attempt = WorkoutAttempt.objects.filter(user=get_user, workout=get_student_workout,workout_week=workout_week,created_at__date__range=[start_of_week, end_of_week]).values()

# Initialize list to store complete data
			complete_data = []

			# Loop through each attempt entry
			for att in attempt:
				# Initialize dictionary for each attempt
				entry_data = {}
				entry_data["user_id"] = att["user_id"]
				entry_data["workout_id"] = att["workout_id"]
				entry_data["workout_day"] = att["workout_day"]
				entry_data["workout_week"] = int(str(att["workout_week"]).strip('"'))

				# Parse exercise_data string into a list of dictionaries
				try:
					exercises = json.loads(att["exercise_data"].replace("'", '"'))
				except json.JSONDecodeError:
					exercises = []

				# Calculate total training volume for all exercises in this attempt
				training_volume = sum(float(ex['weight']) * int(ex['reps']) * int(ex['sets']) for ex in exercises)
				calories_per_pound_lifted = 0.0015  # ~0.0015 calories per pound lifted

				# Calculate total weight lifted
				total_weight_lifted = [float(ex['weight']) * int(ex['reps']) * int(ex['sets']) for ex in exercises]

				# Estimate calories burned
				calories_burned = total_weight_lifted[0] * calories_per_pound_lifted

				# Add training volume to the entry data
				entry_data["training_volume"] = training_volume
				entry_data["total_calories_count"] = calories_burned

				# Append each entry's data to the complete data list
				complete_data.append(entry_data)

			# Print result
			print(complete_data)
			return Response({'data':complete_data }, status=status.HTTP_200_OK)
			
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) 

class Calculatepublicworkoutperformance(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			workout_id=request.GET.get('workout_id')
			user_id=request.GET.get('user_id')
			if not workout_id:
				return Response({'message': 'workout_id not found'}, status=status.HTTP_404_NOT_FOUND)
			if not user_id:
				return Response({'message': 'user_id not found'}, status=status.HTTP_404_NOT_FOUND)
			get_user=AppUser.objects.filter(id=user_id,end_date__isnull=True).first()
			get_workout=WorkoutPlan.objects.filter(id=workout_id,end_date__isnull=True).first()

			if not get_user:
				return Response({'message': 'user with user_id not found'}, status=status.HTTP_404_NOT_FOUND)
			if not get_workout:
				return Response({'message': 'workout with workout_id not found'}, status=status.HTTP_404_NOT_FOUND)
			today = timezone.now().date()


			start_of_week = today - timedelta(days=today.weekday())

			# Calculate the end of the week (e.g., Sunday)
			end_of_week = start_of_week + timedelta(days=6)


			attempt = PublicWorkoutAttempt.objects.filter(user=get_user, workout=get_workout,created_at__date__range=[start_of_week, end_of_week]).values()

# Initialize list to store complete data
			complete_data = []

			# Loop through each attempt entry
			for att in attempt:
				# Initialize dictionary for each attempt
				entry_data = {}
				entry_data["user_id"] = att["user_id"]
				entry_data["workout_id"] = att["workout_id"]
				entry_data["workout_day"] = att["workout_day"]

				# Parse exercise_data string into a list of dictionaries
				try:
					exercises = json.loads(att["exercise_data"].replace("'", '"'))
				except json.JSONDecodeError:
					exercises = []

				# Calculate total training volume for all exercises in this attempt
				training_volume = sum(float(ex['weight']) * int(ex['reps']) * int(ex['sets']) for ex in exercises)

				# Add training volume to the entry data
				entry_data["training_volume"] = training_volume

				# Append each entry's data to the complete data list
				complete_data.append(entry_data)

			# Print result
			print(complete_data)
			return Response({'data':complete_data }, status=status.HTTP_200_OK)
			
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) 

class GetallWeeklyPublicworkouts(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				print(e)
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			today = timezone.now().date()
			print("here in try")
			user_id=request.GET.get('user_id')

			if not user_id:
				return Response({'message': 'user_id not found'}, status=status.HTTP_404_NOT_FOUND)
			get_user=AppUser.objects.filter(id=user_id,end_date__isnull=True).first()
			

			if not get_user:
				return Response({'message': 'user with user_id not found'}, status=status.HTTP_404_NOT_FOUND)
			start_of_week = today - timedelta(days=today.weekday())

			# Calculate the end of the week (e.g., Sunday)
			end_of_week = start_of_week + timedelta(days=6)
			all_data=[]
			attempt = PublicWorkoutAttempt.objects.filter(user=get_user,created_at__date__range=[start_of_week, end_of_week])
			for att in attempt:
				exercise_data=att.exercise_data
				exercise_data = exercise_data.replace("'", '"')
				exercise_data_list = json.loads(exercise_data)
				all_data.append({
					"id": att.id,
					"user_id": att.user.id,
					"workout_id": att.workout.id,
					"exercise_data": exercise_data_list,
					"workout_week": att.workout_week,
					"workout_day": att.workout_day,
					"attempt_number": att.attempt_number,
					"completion_time": att.completion_time,})

				# Convert JSON string to a list of dictionaries
			return Response({'data':all_data }, status=status.HTTP_200_OK)
		except Exception as e:
			print("in except",e)

			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) 
		
class GetallWeeklyPrivateworkouts(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			user_id=request.GET.get('user_id')
			workout_id=request.GET.get('workout_id')
			workout_week=request.GET.get('workout_week')
			if not user_id:
				return Response({'message': 'user_id not found'}, status=status.HTTP_404_NOT_FOUND)
			if not workout_id:
				return Response({'message': 'workout_id not found'}, status=status.HTTP_404_NOT_FOUND)
			if not workout_week:
				return Response({'message': 'workout_week not found'}, status=status.HTTP_404_NOT_FOUND)
			get_user=AppUser.objects.filter(id=user_id,end_date__isnull=True).first()

			if not get_user:
				return Response({'message': 'user with user_id not found'}, status=status.HTTP_404_NOT_FOUND)
			get_workout=WorkoutPlan.objects.filter(id=workout_id,end_date__isnull=True).first()
			get_student_workout=StudentWorkOutPlan.objects.filter(workout=get_workout,end_date__isnull=True).first()
			if not get_workout:
				return Response({'message': 'workout with workout_id not found'}, status=status.HTTP_404_NOT_FOUND)
			today = timezone.now().date()


			start_of_week = today - timedelta(days=today.weekday())

			# Calculate the end of the week (e.g., Sunday)
			end_of_week = start_of_week + timedelta(days=6)
			completed_workouts=0
			all_data=[]
			time_values=[]
			attempt = WorkoutAttempt.objects.filter(workout=get_student_workout,user=get_user,created_at__date__range=[start_of_week, end_of_week],workout_week=workout_week)
			for att in attempt:
				# exercise_data=att.exercise_data
				# exercise_data = exercise_data.replace("'", '"')
				# exercise_data_list = json.loads(exercise_data)
				all_data.append({
					"id": att.id,
					"user_id": att.user.id,
					"workout_id": att.workout.id,
					"exercise_data": json.loads(att.exercise_data),
					"workout_week": att.workout_week,
					"workout_day": att.workout_day,
					"attempt_number": att.attempt_number,
					"completion_time": att.completion_time,
					"created_at": att.created_at

					})
				completed_workouts+=len(ast.literal_eval(att.exercise_data))
				if att.completion_time:
					print(att.completion_time)
					time_values.append(f"{att.completion_time}")
			total_seconds = sum(
				int(h) * 3600 + int(m) * 60 + int(s)
				for h, m, s in (time.split(":") for time in time_values)
			)

			total_time = timedelta(seconds=total_seconds)
			total_seconds = total_time.total_seconds()
			minutes, remaining_seconds = divmod(total_seconds, 60)
			total_days=len(all_data)
			# print(time_values)   
			week_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

# Sort the `all_data` list based on the day name
			all_data.sort(key=lambda x: week_order.index(x['workout_day'])) 

			return Response({'status':True,'workout_minutes':f"{int(minutes)}:{int(remaining_seconds)}",'total_days':total_days,'completed_workouts':completed_workouts,'message':'success','data':all_data }, status=status.HTTP_200_OK)
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) 

# class GetallWeeklyPublicworkouts(APIView):
# 	def get(self,request):
# 		try:
# 			try:
# 				uid = authenticated(request)
# 			except Exception as e:
# 				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
# 			trainer_obj = Trainer.objects.filter(id=uid).first()
# 			if not trainer_obj:
# 				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
# 			user_id=request.GET.get('user_id')
# 			if not user_id:
# 				return Response({'message': 'user_id not found'}, status=status.HTTP_404_NOT_FOUND)
# 			get_user=AppUser.objects.filter(id=user_id,end_date__isnull=True).first()

# 			if not get_user:
# 				return Response({'message': 'user with user_id not found'}, status=status.HTTP_404_NOT_FOUND)
# 			today = timezone.now().date()


# 			start_of_week = today - timedelta(days=today.weekday())

# 			# Calculate the end of the week (e.g., Sunday)
# 			end_of_week = start_of_week + timedelta(days=6)
# 			attempt = PublicWorkoutAttempt.objects.filter(user=get_user,created_at__date__range=[start_of_week, end_of_week]).values()
# 			return Response({'data':attempt }, status=status.HTTP_200_OK)
# 		except Exception as e:
# 			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) 

class GetPrivateworkoutdetail(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			workout_day=request.GET.get('workout_day')
			today = timezone.now().date()


			start_of_week = today - timedelta(days=today.weekday())

			# Calculate the end of the week (e.g., Sunday)
			end_of_week = start_of_week + timedelta(days=6)
			attempt = WorkoutAttempt.objects.filter(workout_day=workout_day,created_at__date__range=[start_of_week, end_of_week]).values()
			return Response({'data':attempt }, status=status.HTTP_200_OK)
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) 

class GetPublicworkoutdetail(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			trainer_obj = Trainer.objects.filter(id=uid).first()
			if not trainer_obj:
				return Response({'message': 'Trainer not found'}, status=status.HTTP_404_NOT_FOUND)
			workout_day=request.GET.get('workout_day')
			today = timezone.now().date()

			start_of_week = today - timedelta(days=today.weekday())

			end_of_week = start_of_week + timedelta(days=6)
			attempt = PublicWorkoutAttempt.objects.filter(workout_day=workout_day,created_at__date__range=[start_of_week, end_of_week]).values()
			return Response({'data':attempt }, status=status.HTTP_200_OK)
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)