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 .functions import *
import random
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 django.core import mail
from django.core.mail import EmailMultiAlternatives
import math, random, pytz, string
from django.contrib import messages
from . import forms
from admin_panel.models import *
import json
from rest_framework.authentication import get_authorization_header
import jwt
from .authentication import authenticated
from django.core.files.storage import FileSystemStorage
import os
from admin_panel.common_functions import *
from .serializers import *
from admin_panel.serializers import ContentSerializer, FAQSerializer
from fortune_teller.models import *
from fortune_teller.serializers import FortuneTellerSerializer
import ast
from django.db.models import Q
import stripe
from pyfcm import FCMNotification
from twilio.rest import Client
from rest_framework import generics

# Create your views here.


# twillio
account_sid= settings.TWILIO_ACCOUNT_SID
auth_token = settings.TWILIO_AUTH_TOKEN
client = Client(account_sid, auth_token)
from_mobile_number = settings.TWILIO_MOBILE_NUMBER

def uploadTheProfile(image):

	fullPath='media/user_profile'
	fs = FileSystemStorage(location=fullPath)
	fullPath2='/media/user_profile'
	filetype = os.path.splitext(image.name)[1]
	theName=randomStringFunctionForImage()
	theImageName=str(theName)+str(filetype)
	filename = fs.save(theImageName, image)
	return str(fullPath2)+'/'+filename


def generateAppointment():
	lastObj= FortuneAppointmentBook.objects.all().last()
	if lastObj:
		if not lastObj.appointment_id:
			return 'APOIN00001'

		theId=lastObj.appointment_id
		theId=theId[5:]
		theId=int(theId)+1
		theId=str(theId)
		theId=theId.zfill(5)
		return "APOIN"+str(theId)
	else:
		return 'APOIN00001'


def generateTranscationsIdFortune():
	lastObj= FortuneTellerTranscations.objects.all().last()
	if lastObj:
		if not lastObj.transcation_id:
			return 'TRANS000001'

		theId=lastObj.transcation_id
		theId=theId[5:]
		theId=int(theId)+1
		theId=str(theId)
		theId=theId.zfill(5)
		return "TRANS"+str(theId)
	else:
		return 'TRANS000001'


def generateTranscationsId():
	lastObj= SeerUserTranscation.objects.all().last()
	if lastObj:
		if not lastObj.transcation_id:
			return 'TRANS000001'

		theId=lastObj.transcation_id
		theId=theId[5:]
		theId=int(theId)+1
		theId=str(theId)
		theId=theId.zfill(5)
		return "TRANS"+str(theId)
	else:
		return 'TRANS000001'


class Register(APIView):
	def post(self,request):
		try:
			data = request.data
			first_name = data.get('first_name')
			last_name = data.get('last_name')
			email = data.get('email')
			password = data.get('password')
			date_of_birth = data.get('date_of_birth')
			get_referal_code = data.get('get_referal_code')
			if not email:
				return Response({"message":'email is required'},status=status.HTTP_400_BAD_REQUEST)
			if not first_name:
				return Response({"message":'first_name is required'},status=status.HTTP_400_BAD_REQUEST)
			if not last_name:
				return Response({"message":'last_name is required'},status=status.HTTP_400_BAD_REQUEST)
			if not password:
				return Response({"message":'password is required'},status=status.HTTP_400_BAD_REQUEST)
			if not date_of_birth:
				return Response({"message":'date_of_birth is required'},status=status.HTTP_400_BAD_REQUEST)
			new_password = handler.hash(password)
			seer_user_obj = SeerUser.objects.filter(email=email).first()
			if seer_user_obj:
				return Response({"message":"The email is already registered"},status=status.HTTP_409_CONFLICT)
			else:
				if get_referal_code:
					check_code = SeerUser.objects.filter(referal_code=get_referal_code).first()
					if not check_code:
						return Response({"message":"Invalid referal code"},status=status.HTTP_409_CONFLICT)
					
				seer_user_obj = SeerUser.objects.create(first_name=first_name,last_name=last_name,email=email,date_of_birth=date_of_birth,password=new_password,referal_code=generate_referral_code())
				if get_referal_code:
					check_code = SeerUser.objects.filter(referal_code=get_referal_code).first()
					if check_code:
						referal_bonus = GeneralSettings.objects.all().first()
						SeerUserWallet.objects.create(seer_user=seer_user_obj,amount=referal_bonus.refer_friend_off)
						
						check_wallet = SeerUserWallet.objects.filter(seer_user = check_code).first()
						if check_wallet:
							new_amount = int(check_wallet.amount) + int(referal_bonus.refer_friend_off)
							check_wallet.amount = new_amount
							check_wallet.save()
						else:
							SeerUserWallet.objects.create(seer_user=check_code,amount=referal_bonus.refer_friend_off)

						SeerUserNotifications.objects.create(message="You have received your referal bonus successfully",notification_type="referal_bonus",seer_user=seer_user_obj)
				verify_token = RefreshToken.for_user(seer_user_obj)
				token = verify_token.access_token
				verify_link = '/seer_user/email-verify?token=' + str(token)
				complete_link = settings.BASE_URL+verify_link
				seer_user_obj.email_verification_link = token
				seer_user_obj.save()
				subject = "Verify Account"
				html_message = render_to_string('email_verifcation.html', {'link': complete_link})
				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)
				AdminNotifications.objects.create(message=first_name+' '+last_name+' seer user has been succesfully registered with us.',type='seer_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')
			first_name = data.get('first_name')
			last_name = data.get('last_name')
			social_id = data.get('social_id')
			device_type = data.get('device_type')
			fcm_token = data.get('fcm_token')
			
			if not provider_id or not social_id:
				return Response({'message': 'Provider and social_id are required.'}, status=status.HTTP_400_BAD_REQUEST)
			if not first_name:
				return Response({'message': 'first_name is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not last_name:
				return Response({'message': 'last_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
			seer_user_obj = SeerUser.objects.filter(social_id=social_id).first()
			if seer_user_obj.account_deleted == 1:
				return Response({'message': 'This account has been deleted.For more information contact admin.'}, status=status.HTTP_400_BAD_REQUEST)
			if not seer_user_obj:
				# If social account not found, create a new one
				seer_user_obj = SeerUser.objects.create(first_name=first_name, last_name=last_name, social_id=social_id,
					  provider_id=provider_id,email=email,device_type=device_type,fcm_token=fcm_token,referal_code=generate_referral_code())
				# Additional logic for generating and sending OTP via email
				# OTP = GenerateOTP()
				# customerObj.otp = OTP
				# customerObj.save()
				# message = "\nOTP has been sent on you registered email successfully:\n" + OTP
				# context = {}
				# context['message'] = message
				# context['email'] = email
				# email_data = render_to_string('forgot-link.html', context)
				# to_emails = customerObj.email
				# subject = "Verify OTP:"
				# message = EmailMultiAlternatives(subject=subject, from_email=settings.EMAIL_HOST_USER, to=[to_emails], body=message)
				# message.attach_alternative(email_data, "text/html")
				# message.send(fail_silently=False)

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

			allData={'id':seer_user_obj.id,
					'first_name':seer_user_obj.first_name,
					'last_name':seer_user_obj.last_name,
					'email':seer_user_obj.email,
					'date_of_birth':seer_user_obj.date_of_birth,
					'is_profile_completed':seer_user_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 LoginMobile(APIView):
	def post(self,request):
		try:
			data = request.data
			country_code = data.get('country_code') 
			phone_number = data.get('phone_number')
			fcm_token = data.get('fcm_token')
			device_type = data.get('device_type')
			the_otp=random.randrange(1000, 9999, 5)
			if not country_code:
				return Response({"message":'country_code 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)
			mobile_number = country_code + phone_number
			seer_user_obj = SeerUser.objects.filter(phone_number=mobile_number).first()
			if seer_user_obj:
				if seer_user_obj.account_deleted == 1:
					return Response({'message': 'This account has been deleted.For more information contact admin.'}, status=status.HTTP_400_BAD_REQUEST)
			if not seer_user_obj:
				seer_user_obj = SeerUser.objects.create(phone_number=mobile_number,referal_code=generate_referral_code())
			seer_user_obj.otp = the_otp
			seer_user_obj.fcm_token = fcm_token
			seer_user_obj.device_type  =device_type
			seer_user_obj.save()
			# message = client.messages.create(
            #             body= 'Your SEER verification code is: '+str(the_otp),
            #             from_=from_mobile_number,
            #             to= mobile_number
            #         )
			userData = {
				'otp':seer_user_obj.otp,			
			}
			return Response({"message":'Success','data':userData})
		except Exception as e:
			return Response({"message":str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR) 


class emailVerification(APIView):
	def get(self,request):
		try:
			token = request.GET.get('token')
			customer_Obj = SeerUser.objects.filter(email_verification_link = token).first()
			customer_Obj.email_verified = True
			customer_Obj.save()
			return render(request,'email_verification_success.html')
		except  Exception as e:
			return render(request,'email_verfication_failed.html')

	
class OtpVerification(APIView):
	def post(self,request):
		try:
			data=request.data
			country_code = data.get('country_code') 
			phone_number = data.get('phone_number')
			otp = data.get('otp')
			if not country_code:
				return Response({"message":'country_code 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 otp:
				return Response({"message":'otp is required'},status=status.HTTP_400_BAD_REQUEST)
			mobile_number = country_code + phone_number
			try:
				seer_user_obj = SeerUser.objects.get(phone_number=mobile_number,otp=otp)
			except Exception as e:
				return Response({"message":'Invalid otp','data':{}},status=status.HTTP_400_BAD_REQUEST)
			refresh_token = RefreshToken.for_user(seer_user_obj)
			allData={'id':seer_user_obj.id,
				'first_name':seer_user_obj.first_name,
				'last_name':seer_user_obj.last_name,
				'email':seer_user_obj.email,
				'date_of_birth':seer_user_obj.date_of_birth,
				'is_profile_completed':seer_user_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 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":'email is required'},status=status.HTTP_400_BAD_REQUEST) 
			if not password:
				return Response({"message":'password is required'},status=status.HTTP_400_BAD_REQUEST)  
			user  = SeerUser.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)
			userObj  = SeerUser.objects.filter(email=email,status=True,end_date__isnull=True).first()
			if not userObj:
				return Response({"message":'Your account has not been activated, Please contact to admin.'},status=status.HTTP_401_UNAUTHORIZED)
			if userObj.account_deleted == 1:
				return Response({'message': 'This account has been deleted.For more information contact admin.'}, status=status.HTTP_400_BAD_REQUEST)
			check_password = userObj.password
			check = handler.verify(password,check_password)
			if userObj.email_verified == False:
				return Response({"message":'Please verify your email first'},status=status.HTTP_400_BAD_REQUEST)
			if check:
				userObj.fcm_token = fcm_token
				userObj.device_type  =device_type
				userObj.save()
				refresh_token = RefreshToken.for_user(userObj)
				allData={'id':userObj.id,
					'first_name':userObj.first_name,
					'last_name':userObj.last_name,
					'email':userObj.email,
					'date_of_birth':userObj.date_of_birth,
					'is_profile_completed':userObj.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 SeerUserForgetPassword(APIView):
	def post(self,request):
			try:
				data = request.data
				email = data.get('email')
				if not email:
					return Response({"message":'Email is required'})
				user  = SeerUser.objects.filter(email=email).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)
				userObj  = SeerUser.objects.filter(email=email).first()
				if userObj:
					ran_num = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(12)])
					baselink =  '/seer_user/forgot/' + str(userObj.email) + '/' + ran_num
					completelink = str(settings.BASE_URL) + baselink
					userObj.forgot_password_link = baselink
					userObj.save()
					subject = 'Forgot Password'
					html_message = render_to_string('forget_password_email.html', {'link': completelink})
					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)
					return Response({"message":'Reset password link has been sent to this 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 get(self,request):
		link = str(self.request.path)
		user_email = link.split('/')[-2]
		link_expiry = SeerUser.objects.filter(email = user_email).first()
		if link_expiry.forgot_password_link == "LinkExpiry":
			return render(request,'link-expire.html')
		user_obj = SeerUser.objects.filter(email = user_email, forgot_password_link = link).first()
		
		if user_obj:
			valid = True
		else:
			valid = False
		return render(request,'forgot.html',{'valid':valid})	

	def post(self,request):
		form = forms.forgetverification(request.POST)
		if form.is_valid():
			new_password = form.cleaned_data.get('new_password')
			confirm_new_password = form.cleaned_data.get('confirm_new_password')
			link = str(self.request.path)
			user_email = link.split('/')[-3]
			encrypt_password = handler.hash(new_password)
			user_obj = SeerUser.objects.filter(email = user_email).first()
			if user_obj:
				user_obj.password = encrypt_password
				user_obj.forgot_password_link = "LinkExpiry"
				user_obj.save()
				messages.success(request, "Changed successfully")
				return render(request,'password_success.html')
		else:
			return render(request, 'forgot.html', {'form': form})	
		
class GetHobbies(APIView):
	def get(self,request):
		try:
			hob_obj = Hobbies.objects.filter(status=True,end_date__isnull = True)
			allData = []
			for hob in hob_obj:
				all_data = {
					'id':hob.id,
					'hobby':hob.hobby
				}
				allData.append(all_data)
			return Response({"message":'Success','data':allData})
		except Exception as e:
			return Response({"message":str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR) 
		


class SeerUserHelpSupport(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			user_obj =  SeerUser.objects.filter(id = uid).first()
			data = request.data
			title = data.get('title')
			message = data.get('message')
			if not title:
				return Response({'message':'title is required'},status=status.HTTP_400_BAD_REQUEST)
			if not message:
				return Response({'message':'message is required'},status=status.HTTP_400_BAD_REQUEST)
			HelpSupport.objects.create(title=title,message=message,seer_user=user_obj)
			AdminNotifications.objects.create(message=user_obj.first_name+' '+user_obj.last_name+' seer user has a help & support',type='seer_user_help_support')

			return Response({'message':'Your request has been submitted successfully. We will revert you back sortly.'})
		except Exception as e:
		   return Response({"message":str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR) 
  

  
			
class getLifestyleQuestion(APIView):
	def get(self,request):
		try:
			question_obj = LifestyleOptions.objects.filter(end_date__isnull = True)
			question_dict = {}

			for question in question_obj:
				question_name = question.lifestyle_question.question_title

				if question_name not in question_dict:
					question_dict[question_name] = {
						'question': question_name,
						'options': []
					}

				option_id = question.id
				option_data = question.option

				question_dict[question_name]['options'].append({
					'option_id':option_id,
					'option_value': option_data
				})

			new_feature_dict = {'question_dict': list(question_dict.values())}
			json_feature_dict = json.dumps(new_feature_dict, separators=(',', ':'))
			new_feature_dict = json.loads(json_feature_dict)
			return Response({'message':'Success','data':new_feature_dict})

		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)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			allData=SeerUserSerializer(seer_user_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 SeerUserCompleteProfile(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

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

			data = request.data
			first_name = data.get('first_name')
			last_name = data.get('last_name')
			email = data.get('email')
			gender = data.get('gender')
			date_of_birth = data.get('date_of_birth')
			religion = data.get('religion')
			profession = data.get('profession')
			height = data.get('height')
			country_origin = data.get('country_origin')
			state = data.get('state')
			city = data.get('city')
			languages = data.get('languages')
			hobbies = data.get('hobbies')
			bio = data.get('bio')
			education = data.get('education')
			income = data.get('income')
			timezone = data.get('timezone')
			
			check_email = SeerUser.objects.filter(email=email).exclude(id=seer_user_obj.id).first()
			if check_email:
				return Response({"message":"The email is already registered"},status=status.HTTP_409_CONFLICT)
			
			if not email:
				return Response({"message": 'email is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not first_name:
				return Response({"message": 'first_name is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not last_name:
				return Response({"message": 'last_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 date_of_birth:
				return Response({"message": 'date_of_birth is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not timezone:
				return Response({"message": 'timezone is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not religion:
			# 	return Response({"message": 'religion is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not profession:
			# 	return Response({"message": 'profession is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not height:
			# 	return Response({"message": 'height is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not country_origin:
				return Response({"message": 'country_origin is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not state:
				return Response({"message": 'state is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not city:
				return Response({"message": 'city is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not languages:
				return Response({"message": 'languages is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not hobbies:
			# 	return Response({"message": 'hobbies is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not education:
			# 	return Response({"message": 'education is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not income:
			# 	return Response({"message": 'income is required'}, status=status.HTTP_400_BAD_REQUEST)
	
			# Get birthdate input from the user format: YYYY-MM-DD
			year, month, day = map(int, date_of_birth.split('-'))
			# Get the astrological sign
			horoscope = get_astrological_sign(day, month)
			# Get the chines Zodiac
			zodiac = get_chinese_zodiac(year)
			# Get the five element
			element = get_five_element(year)

			horoscope_obj = Horoscope.objects.filter(horoscope=horoscope).first()
			chinese_obj =  ChineseZodiac.objects.filter(chinese_zodiac=zodiac).first()
			elements_obj = FiveElements.objects.filter(element_name=element).first()
			sign_detail = SeerUserSignDetail.objects.create(seer_user=seer_user_obj,horoscope=horoscope_obj,
						chinese_zodiac=chinese_obj,five_element=elements_obj)
			seer_user_obj.first_name = first_name
			seer_user_obj.last_name = last_name
			seer_user_obj.date_of_birth = date_of_birth
			seer_user_obj.email = email
			seer_user_obj.gender = gender
			seer_user_obj.religion = religion
			seer_user_obj.profession = profession
			seer_user_obj.height = height
			seer_user_obj.country_origin = country_origin
			seer_user_obj.state = state
			seer_user_obj.city = city
			seer_user_obj.languages = languages
			seer_user_obj.hobbies = hobbies
			seer_user_obj.bio = bio
			seer_user_obj.education = education
			seer_user_obj.income = income
			seer_user_obj.is_profile_completed = True
			seer_user_obj.user_stripe_id = generate_strip_id()
			seer_user_obj.timezone = timezone
			seer_user_obj.save()

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

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

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

			data = request.data
			first_name = data.get('first_name')
			last_name = data.get('last_name')
			gender = data.get('gender')
			# date_of_birth = data.get('date_of_birth')
			religion = data.get('religion')
			profession = data.get('profession')
			height = data.get('height')
			country_origin = data.get('country_origin')
			state = data.get('state')
			city = data.get('city')
			languages = data.get('languages')
			hobbies = data.get('hobbies')
			bio = data.get('bio')
			education = data.get('education')
			income = data.get('income')
			timezone = data.get('timezone')
			
			if not first_name:
				return Response({"message": 'first_name is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not last_name:
				return Response({"message": 'last_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 timezone:
				return Response({"message": 'timezone is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not date_of_birth:
			# 	return Response({"message": 'date_of_birth is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not religion:
			# 	return Response({"message": 'religion is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not profession:
			# 	return Response({"message": 'profession is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not height:
			# 	return Response({"message": 'height is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not country_origin:
				return Response({"message": 'country_origin is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not state:
				return Response({"message": 'state is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not city:
				return Response({"message": 'city is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not languages:
				return Response({"message": 'languages is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not hobbies:
			# 	return Response({"message": 'hobbies is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not education:
			# 	return Response({"message": 'education is required'}, status=status.HTTP_400_BAD_REQUEST)
			# if not income:
			# 	return Response({"message": 'income is required'}, status=status.HTTP_400_BAD_REQUEST)
	
			# # Get birthdate input from the user format: YYYY-MM-DD
			# year, month, day = map(int, date_of_birth.split('-'))
			# # Get the astrological sign
			# horoscope = get_astrological_sign(day, month)
			# # Get the chines Zodiac
			# zodiac = get_chinese_zodiac(year)
			# # Get the five element
			# element = get_five_element(year)

			# horoscope_obj = Horoscope.objects.filter(horoscope=horoscope).first()
			# chinese_obj =  ChineseZodiac.objects.filter(chinese_zodiac=zodiac).first()
			# elements_obj = FiveElements.objects.filter(element_name=element).first()
			# sign_detail = SeerUserSignDetail.objects.create(seer_user=seer_user_obj,horoscope=horoscope_obj,
			# 			chinese_zodiac=chinese_obj,five_element=elements_obj)
			seer_user_obj.first_name = first_name
			seer_user_obj.last_name = last_name
			# seer_user_obj.date_of_birth = date_of_birth
			seer_user_obj.gender = gender
			seer_user_obj.religion = religion
			seer_user_obj.profession = profession
			seer_user_obj.height = height
			seer_user_obj.country_origin = country_origin
			seer_user_obj.state = state
			seer_user_obj.city = city
			seer_user_obj.languages = languages
			seer_user_obj.hobbies = hobbies
			seer_user_obj.bio = bio
			seer_user_obj.education = education
			seer_user_obj.income = income
			seer_user_obj.timezone = timezone
			seer_user_obj.save()

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

def most_common(lst):
	return max(set(lst), key=lst.count)



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

			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			extraversion_introversion = str(request.data.get('extraversion_introversion'))
			print("extraversion_introversion",extraversion_introversion)
			if not extraversion_introversion:
				return Response({"message": 'extraversion_introversion is required'}, status=status.HTTP_400_BAD_REQUEST)
			first_pair_mbti = most_common(eval(extraversion_introversion))
			
			sensing_intuition = str(request.data.get('sensing_intuition'))
			print("sensing_intuition",sensing_intuition)

			if not sensing_intuition:
				return Response({"message": 'sensing_intuition is required'}, status=status.HTTP_400_BAD_REQUEST)
			second_pair_mbti = most_common(eval(sensing_intuition))

			thinking_feeling = str(request.data.get('thinking_feeling'))
			print("thinking_feeling",thinking_feeling)

			if not thinking_feeling:
				return Response({"message": 'thinking_feeling is required'}, status=status.HTTP_400_BAD_REQUEST)
			third_pair_mbti = most_common(eval(thinking_feeling))

			judging_perceiving = str(request.data.get('judging_perceiving'))
			print("judging_perceiving",judging_perceiving)

			if not judging_perceiving:
				return Response({"message": 'fourth array is required'}, status=status.HTTP_400_BAD_REQUEST)
			fourth_pair_mbti = most_common(eval(judging_perceiving))

			created_mbti = first_pair_mbti + second_pair_mbti + third_pair_mbti + fourth_pair_mbti
			fetch_mbti = MBTI.objects.filter(mbti_name = created_mbti,end_date__isnull = True).first()
			SeerUserSignDetail.objects.filter(seer_user = seer_user_obj).update(mbti = fetch_mbti )
			return Response({'message': 'Success','data':f'You are {fetch_mbti.tagline}({created_mbti}) type!' })

		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)

# 			seer_user_obj = SeerUser.objects.filter(id=uid).first()
# 			if not seer_user_obj:
# 				return Response({'message': 'user 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)
# 			seer_user_obj.images = image_urls
# 			seer_user_obj.primary_image = image_urls[0]
# 			seer_user_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 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)

			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user 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 seer_user_obj.images:
				seer_user_obj.images = image_urls
				seer_user_obj.primary_image = image_urls[0]
				seer_user_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 EditImages(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

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

			data = request.data
			image_urls = data.get('image_urls')
			seer_user_obj.images = image_urls
			seer_user_obj.primary_image = image_urls[0]
			seer_user_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 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)

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

#             data = request.data
#             images = data.getlist('images')
#             remove_images = data.getlist('remove_images')  # Newly added line

#             # Existing image URLs
#             image_urls = []
#             if seer_user_obj.images:
#                 image_urls.extend(seer_user_obj.images)

#             # Remove images from existing image URLs
#             for remove_image in remove_images:
#                 if remove_image in image_urls:
#                     image_urls.remove(remove_image)

#             # Add new images to the list
#             for image in images:
#                 image_path = uploadTheProfile(image)
#                 image_urls.append(image_path)

#             seer_user_obj.images = image_urls
#             seer_user_obj.primary_image = image_urls[0] if image_urls else None  # Set primary image to None if no images
#             seer_user_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)

			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_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 = SeerUser.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)
				SeerUser.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 SeerUserDeleteAccount(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			seer_user_obj.delete()
			AdminNotifications.objects.create(message=seer_user_obj.first_name+' '+seer_user_obj.last_name+' seer user has deleted their account',type='seer_user_help_support')

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

class GetUserFaq(APIView):
	def get(self,request):
		try:
			faq_obj = Faq.objects.filter(end_date__isnull =True,type="User").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 GetUserBlog(APIView):
	def get(self,request):
		try:
			content_obj =  ContentManagement.objects.filter(page_type='Blog').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 GetUserPrivacyPolicy(APIView):
	def get(self,request):
		try:
			content_obj =  ContentManagement.objects.filter(page_type='Privacy Policy',user_type='user').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 GetUserTerms(APIView):
	def get(self,request):
		try:
			content_obj =  ContentManagement.objects.filter(page_type='Terms & conditions',user_type='user').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 FortuneTellerList(APIView):
# 	def get(self,request):
# 		try:
# 			try:
# 				uid = authenticated(request)
# 			except Exception as e:
# 				return Response({'message':str(e)},status=status.HTTP_401_UNAUTHORIZED)
# 			seer_user_obj = SeerUser.objects.filter(id=uid).first()
# 			if not seer_user_obj:
# 				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
# 			fortune_teller_obj = FortuneTeller.objects.filter(end_date__isnull=True,is_profile_completed=True)
# 			allData=FortuneTellerSerializer(fortune_teller_obj,many=True).data
# 			# for fortune_teller in allData:
# 			# 	fortune_id = fortune_teller['id']
# 			# 	total_count = FortunetellerRatingReviews.objects.filter(fortune_teller=fortune_id).count()
# 			# 	all_rating = [float(fortune_rat.rating) for fortune_rat in FortunetellerRatingReviews.objects.filter(fortune_teller=fortune_id)]
				
# 			# 	if all_rating:
# 			# 		final_rating = sum(all_rating)
# 			# 		average = final_rating / total_count
# 			# 	else:
# 			# 		average = ''

# 			# 	fortune_teller['average_rating'] = average
# 			return Response({'message':'Success','data':allData})
# 		except Exception as e:
# 			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class FortuneTellerList(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message':str(e)},status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			data = request.query_params
			service = data.get('service')
			language = data.get('language')
			skills = data.get('skills')
			min_rating = data.get('min_rating')
			max_rating = data.get('max_rating')
			lookups = Q()
			if service:
				lookups.add(Q(services__contains=service), Q.AND)
			if language:
				lookups.add(Q(languages__contains=language), Q.AND)
			if skills:
				lookups.add(Q(skills__contains=skills), Q.AND)
			if min_rating and max_rating:
				lookups.add(Q(rating__gte=min_rating, rating__lte=max_rating), Q.AND)
			fortune_teller_obj = FortuneTeller.objects.filter(lookups,end_date__isnull=True,is_profile_completed=True)
			fortuner_data = FortuneTellerSerializer(fortune_teller_obj,many=True,context={'seer_user': seer_user_obj}).data
			'''========= Available fortune teller =========='''
			online_fortune = FortuneTeller.objects.filter(is_online=True,end_date__isnull=True,is_profile_completed=True)
			online_fortune_tellers=FortuneTellerSerializer(online_fortune,many=True).data
			'''================= End of Code ================='''
			services = Service.objects.filter(status=True, end_date__isnull=True)
			serialized_services = ServiceSerializer(services, many=True).data
			allData = {
				'fortune_tellers':fortuner_data,
				'online_fortune_tellers':online_fortune_tellers,
				'services':serialized_services,
				'languages':ast.literal_eval(seer_user_obj.languages)
			}

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

class FortuneTellerDetail(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message':str(e)},status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			data = request.query_params
			fortune_id = data.get('id')
			if not fortune_id:
				return Response({"message":"id is required"}, status=status.HTTP_400_BAD_REQUEST)
			fortune_teller_obj = FortuneTeller.objects.filter(id=fortune_id).first()
			allData=FortuneTellerSerializer(fortune_teller_obj,context={'seer_user': seer_user_obj}).data


			# total_count = FortunetellerRatingReviews.objects.filter(fortune_teller=fortune_id).count()
			# all_rating = [float(fortune_rat.rating) for fortune_rat in FortunetellerRatingReviews.objects.filter(fortune_teller=fortune_id)]
			# if all_rating:
			# 	final_rating = sum(all_rating)
			# 	average=float(final_rating)/float(total_count)
			# else:
			# 	average=''

			review_obj = FortunetellerRatingReviews.objects.filter(fortune_teller=fortune_id)
			review_data = FortunerTellerReviewSerializer(review_obj,many=True).data
			return Response({'message':'Success','data':allData,'reviews':review_data})
		except Exception as e:
			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# class FortuneFilteration(APIView):
# 	def get(self,request):
# 		try:
# 			try:
# 				uid = authenticated(request)
# 			except Exception as e:
# 				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
# 			seer_user_obj = SeerUser.objects.filter(id=uid).first()
# 			if not seer_user_obj:
# 				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
# 			language_obj = SeerUser.objects.filter(id=uid).first()
# 			service_obj = Service.objects.filter(end_date__isnull=True)
# 			service_data = ServiceSerializer(service_obj, many=True).data
# 			return Response({'message':'Success','service_data':service_data,'language_data':language_obj.languages})
# 		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)

# 			seer_user_obj = SeerUser.objects.filter(id=uid).first()
# 			if not seer_user_obj:
# 				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
# 			filter = request.data.get('filter')
# 			service_filter = request.data.get('service_filter')
# 			language_filter = request.data.get('language_filter')
# 			skills_filter = request.data.get('skills_filter')
# 			ratings = request.data.get('ratings')
# 			if filter == 'yes':
# 				lookups = Q()
# 				if service_filter:
# 					lookups.add(Q(services__in = service_filter), Q.AND)
# 				if language_filter:
# 					lookups.add(Q(languages__in = language_filter), Q.AND)
# 				if skills_filter:
# 					lookups.add(Q(skills__in = language_filter), Q.AND)
# 				if ratings:
# 					lookups.add(Q(fortunetellerratingreviews__rating__in=ratings), Q.AND)
# 				fortune_teller_obj = FortuneTeller.objects.filter(lookups,end_date__isnull = True)
# 			else:
# 				fortune_teller_obj = FortuneTeller.objects.filter(end_date__isnull=True)
# 			allData=FortuneTellerSerializer(fortune_teller_obj,many=True).data
# 			for fortune_teller in allData:
# 				fortune_id = fortune_teller['id']
# 				total_count = FortunetellerRatingReviews.objects.filter(fortune_teller=fortune_id).count()
# 				all_rating = [float(fortune_rat.rating) for fortune_rat in FortunetellerRatingReviews.objects.filter(fortune_teller=fortune_id)]
				
# 				if all_rating:
# 					final_rating = sum(all_rating)
# 					average = final_rating / total_count
# 				else:
# 					average = ''

# 				fortune_teller['average_rating'] = average
# 			return Response({'message':'Success','data':allData})
# 		except Exception as e:
# 			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class FavUnfavouriteFortune(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			fortune_teller_id = request.data.get('fortune_teller_id')
			if not fortune_teller_id:
				return Response({"message": 'Fortune teller id is required'}, status=status.HTTP_400_BAD_REQUEST)
			fortune_obj = FortuneTeller.objects.filter(id=fortune_teller_id).first()
			if not fortune_obj:
				return Response({"message": 'Fortune teller id is required'}, status=status.HTTP_400_BAD_REQUEST)
			favourite_post, created = FavouriteUnfavouriteFortune.objects.get_or_create(fortune=fortune_obj,seer_user=seer_user_obj,is_favourite=1)
			if not created:
				favourite_post.delete()
				return Response({'message':'Removed from favourite list'})
			else: 
				favourite_post.save()
				return Response({'message':'Added to favourite list.'})
		except Exception as e:
			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		


class FortuneFavListing(APIView):
	def get(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			
			fav_obj = FavouriteUnfavouriteFortune.objects.filter(seer_user=seer_user_obj, is_favourite=1)
			all_Data = []
			for fav in fav_obj:
				fortune_teller_obj = FortuneTeller.objects.filter(id=fav.fortune.id, end_date__isnull=True)
				allData = FortuneTellerSerializer(fortune_teller_obj, many=True).data
				all_Data.extend(allData)  # Use extend instead of append
			
			return Response({'message': 'Success', 'data': all_Data})
		
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		

		


class ContactUs(APIView):
	def post(self,request):
		try:
			first_name = request.data.get('first_name')
			if not first_name:
				return Response({"message": 'First name is required'}, status=status.HTTP_400_BAD_REQUEST)
			last_name = request.data.get('last_name')
			if not last_name:
				return Response({"message": 'Last name is required'}, status=status.HTTP_400_BAD_REQUEST)
			email = request.data.get('email')
			if not email:
				return Response({"message": 'Email is required'}, status=status.HTTP_400_BAD_REQUEST)
			phone_number = request.data.get('phone_number')
			if not phone_number:
				return Response({"message": 'Email is required'}, status=status.HTTP_400_BAD_REQUEST)
			message = request.data.get('message')
			if not message:
				return Response({"message": 'Message is required'}, status=status.HTTP_400_BAD_REQUEST)
			subject = "Verify Account"
			html_message = render_to_string('contact_us_email.html', {'first_name': first_name,'last_name':last_name,'email':email,'phone_number':phone_number,'message':message})
			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)
			return Response({'message':'Success'})
		except Exception as e:
			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		

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

			old_password = request.data.get('old_password')
			if not old_password:
				return Response({'message':'old password is required'},status=status.HTTP_400_BAD_REQUEST)
			new_password = request.data.get('new_password')
			if not new_password:
				return Response({'message':'new password is required'},status=status.HTTP_400_BAD_REQUEST)
			check_password = seer_user_obj.password
			check = handler.verify(old_password,check_password)
			if check == False:
				return Response({'message':'Old password is incorrect'},status=status.HTTP_403_FORBIDDEN)
			password = new_password
			encrypt_password = handler.hash(password)
			seer_user_obj.password = encrypt_password
			seer_user_obj.save()
			return Response({'message':'Success'}) 
		except Exception as e:
			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class GetNotificationSettings(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			notification_data = request.data.get('notification_data')
			if not notification_data:
				return Response({'message':'notification data is required'},status=status.HTTP_400_BAD_REQUEST)
			seer_user_obj.notification_status = notification_data
			seer_user_obj.save()
			return Response({'message':'Success','data':seer_user_obj.notification_status})
		except Exception as e:
			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class GetUserNotifications(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			notification_obj = SeerUserNotifications.objects.filter(seer_user = seer_user_obj,end_date__isnull = True).order_by('-id')
			all_data = UserNotificationSerializer(notification_obj,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 DeleteUserNotifications(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			notification_id = request.data.get('id')
			if not notification_id:
				return Response({'message':'id is required'},status=status.HTTP_400_BAD_REQUEST)
			SeerUserNotifications.objects.filter(id=notification_id).update(end_date=datetime.now())
			return Response({'message':'Success'})
		except Exception as e:
			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class FortuneBookAppointment(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()

			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			fortune_teller_id = request.query_params.get('fortune_teller_id')
			if not fortune_teller_id:
				return Response({'message':'Fortune teller id is required'},status=status.HTTP_400_BAD_REQUEST)
			fortune_services = FortuneTeller.objects.filter(id=fortune_teller_id,end_date__isnull=True).first()
			return Response({'message':'Success','services':fortune_services.services})
		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)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			fortune_teller_id = request.data.get('fortune_teller_id')
			if not fortune_teller_id:
				return Response({'message':'Fortune teller id is required'},status=status.HTTP_400_BAD_REQUEST)
			fortune_obj = FortuneTeller.objects.filter(id=fortune_teller_id,end_date__isnull=True).first()
			generate_appointment = generateAppointment()
			appointment_date = request.data.get('appointment_date')
			if not appointment_date:
				return Response({'message':'Appointment date is required'},status=status.HTTP_400_BAD_REQUEST)
			appointment_time = request.data.get('appointment_time')
			if not appointment_time:
				return Response({'message':'Appointment time is required'},status=status.HTTP_400_BAD_REQUEST)
			service_name = request.data.get('service_name')
			if not service_name:
				return Response({'message':'service is required'},status=status.HTTP_400_BAD_REQUEST)
			service_obj = Service.objects.filter(service_name = service_name).first()
			if not service_obj:
				return Response({'message':'No service found'},status=status.HTTP_400_BAD_REQUEST)
			service_type = request.data.get('service_type')
			if not service_type:
				return Response({'message':'Service type is required'},status=status.HTTP_400_BAD_REQUEST)
			price = request.data.get('price')
			if not price:
				return Response({'message':'Price is required'},status=status.HTTP_400_BAD_REQUEST)
			timezone = seer_user_obj.timezone
			# time slot management
			time_obj = FortuneTellerTiming.objects.filter(fortune_teller=fortune_obj).first()
			time = datetime.strptime(appointment_time, "%I:%M %p")
			time_slot = time + timedelta(minutes=int(15))
			taken_time = time_slot.strftime("%I:%M %p")

			book_appointment_obj = FortuneAppointmentBook.objects.create(appointment_id=generate_appointment,fortune_teller=fortune_obj,seer_user=seer_user_obj,appointment_date=appointment_date,appointment_time=appointment_time + "-" + taken_time,
							service=service_obj,service_type=service_type,price=price,timezone=timezone)
			
			# general_obj =GeneralSettings.objects.all().first()
			# if general_obj:
			# 	commision_percent = general_obj.commission_percentage
			# 	fortune_teller_wallet = price * (commision_percent / 100)
			# 	commision_amount = int(price) - int(fortune_teller_wallet)
			# else:
			# 	commision_amount= int(0)
			
			# wallet_obj = FotuneTellerWallet.objects.filter(fortune_teller=fortune_obj.id).first()
			# if wallet_obj:
			# 	wallet_obj.amount += commision_amount
			# 	wallet_obj.save()
			# else:
			# 	FotuneTellerWallet.objects.create(fortune_teller=fortune_obj.id,amount=commision_amount)

			# FortuneTellerTranscations.objects.create(transcation_id=generateTranscationsIdFortune(),seer_user=seer_user_obj,fortune_teller=fortune_obj,amount=commision_amount,payment_mode='wallet',transcation_type="appointment")

			FortuneTellerNotifications.objects.create(fortune_teller = fortune_obj, message=seer_user_obj.first_name+' '+seer_user_obj.last_name+' booked an appointment.',notification_type='appointment_booking')
			data = {
				'appointment_id':book_appointment_obj.id
			}
			if fortune_obj.notification_status:
				registration_id = fortune_obj.fcm_token
				server_key = str(settings.FIREBASE_SERVER_KEY)
				if fortune_obj.device_type == 'Android':

					data_message = {		'type': 'appointment_booking',
											'title' : 'BOOKED APPOINTMENT',
											"message" : seer_user_obj.first_name+' '+seer_user_obj.last_name+' booked an appointment.'
										}
					
					result = FCMNotification(api_key=server_key).notify_single_device(registration_id=registration_id,  data_message=data_message)
				if fortune_obj.device_type == 'Ios':
					message_title = 'BOOKED APPOINTMENT',
					message_body =  seer_user_obj.first_name+' '+seer_user_obj.last_name+' booked an appointment.'
					data_message = {		'type': 'appointment_booking',
											'title' : 'BOOKED APPOINTMENT',
											"message" :  seer_user_obj.first_name+' '+seer_user_obj.last_name+' booked an appointment.'
										}
					result = FCMNotification(api_key=server_key).notify_single_device(registration_id=registration_id, message_title=message_title, 
					message_body=message_body, data_message=data_message)

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


class GetBookingList(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			booking_type = request.query_params.get('booking_type')
			if not booking_type:
				return Response({'message':'Booking type is required'},status=status.HTTP_400_BAD_REQUEST)
			if booking_type == 'Upcoming':
				appoint_obj = FortuneAppointmentBook.objects.filter(appointment_status__in=['Pending', 'Accepted'],seer_user=seer_user_obj).order_by('-id')
			else:
				appoint_obj = FortuneAppointmentBook.objects.filter(seer_user=seer_user_obj).exclude(appointment_status__in=['Pending', 'Accepted']).order_by('-id')
			all_data = AppointmentFortuneTeller(appoint_obj,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 GetBookingDetails(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			booking_id =  request.query_params.get('booking_id')
			if not booking_id:
				return Response({'message':'Booking Id is required'},status=status.HTTP_400_BAD_REQUEST)
			appoint_obj = FortuneAppointmentBook.objects.filter(seer_user=seer_user_obj,id=booking_id)
			if not appoint_obj:
				return Response({'message':'No appointment found'},status=status.HTTP_400_BAD_REQUEST)
			all_data = AppointmentFortuneTeller(appoint_obj,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 AddMoneyToWallet(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)

			seer_user_obj = SeerUser.objects.filter(id=uid).first()

			data = request.data
			# payment_token = data.get('payment_token')
			# if not payment_token:
			# 	return Response({'message':'payment_token is required'},status=status.HTTP_400_BAD_REQUEST)
			amount = data.get('amount')
			if not amount:
				return Response({'message':'amount is required'},status=status.HTTP_400_BAD_REQUEST)
			card_id = request.data.get('card_id')
			if not card_id:
				return Response({'message': 'card_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			card_obj = SeerUserCards.objects.filter(id=card_id,seer_user=uid).first()
			if not card_obj:
				return Response({'message': 'No card found is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			capture_value = 'true'
			thePaymentObj = paymentWithExistingCard(card_obj.the_user_stripe,card_obj.card_id,int(amount),capture_value)
			if thePaymentObj['status'] == True:
			# stripe.api_key =settings.STRIPE_SECRET_KEY

			# charge = stripe.Charge.create(
			# 	amount=int(amount) * 100,
			# 	currency='usd',
			# 	source=payment_token,
			# 	description='Adding money to wallet'
			# )
			
			# Check if the user has an existing wallet
				seer_user_wallet = seer_user_obj.wallet.first()

				if seer_user_wallet:
					seer_user_wallet.amount += int(amount)
					seer_user_wallet.save()
				else:
					SeerUserWallet.objects.create(
						seer_user=seer_user_obj,
						amount=amount
					)
				AdminNotifications.objects.create(message=seer_user_obj.first_name+' '+seer_user_obj.last_name+' seer user added money to their wallet.',type='seer_user_wallet')
				return Response({'message': 'Money added to wallet successfully'})

		except stripe.error.CardError as e:
			return Response({'message': str(e)}, status=status.HTTP_400_BAD_REQUEST)

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


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

			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			
			# Retrieve the wallet detail for the user
			wallet_detail = SeerUserWallet.objects.filter(seer_user=seer_user_obj).first()
			serializer = SeerUserWalletSerializer(wallet_detail).data

			wallet_transcation = SeerUserTranscation.objects.filter(seer_user = seer_user_obj, payment_mode='wallet')[:3]
			transcation_serializer = WalletTranscationSerializer(wallet_transcation,many=True).data

			return Response({'message': 'Success', 'data': serializer})

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


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

			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			transcation_type = request.query_params.get('transcation_type')
			if not transcation_type:
				return Response({'message':'transcation_type is required'},status=status.HTTP_400_BAD_REQUEST)
			
			if transcation_type == "pay":
				wallet_transcation = SeerUserTranscation.objects.filter(seer_user = seer_user_obj, transcation_type='pay').order_by('-id')
				transcation_serializer = WalletTranscationSerializer(wallet_transcation,many=True).data
			elif transcation_type == 'refund':
				wallet_transcation = SeerUserTranscation.objects.filter(seer_user = seer_user_obj, transcation_type='refund').order_by('-id')
				transcation_serializer = WalletTranscationSerializer(wallet_transcation,many=True).data
			else:
				wallet_transcation = SeerUserTranscation.objects.filter(seer_user = seer_user_obj).order_by('-id')
				transcation_serializer = WalletTranscationSerializer(wallet_transcation,many=True).data

			return Response({'message': 'Success','data':transcation_serializer})

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


# class getFortuneTimeSlot(APIView):
# 	def get(self, request):
# 		try:
# 			fortune_teller = self.request.query_params.get('fortune_teller')
# 			day = self.request.query_params.get('day')
# 			date = self.request.query_params.get('date')
# 			# date_object = datetime.strptime(date_string, "%Y-%m-%d")
# 			# date = date_object.strftime("%d %B %Y")
# 			# Get current time
# 			current_time = datetime.now()
# 			if not fortune_teller:
# 				return Response({'message': 'fortune_teller is required'}, status=status.HTTP_400_BAD_REQUEST)
			
# 			time_obj = FortuneTellerTiming.objects.filter(fortune_teller=fortune_teller).first()
# 			if not time_obj:
# 				return Response({'message': 'Fortune timing data not found'}, status=status.HTTP_404_NOT_FOUND)
			
# 			timedata = json.loads(time_obj.slots)
# 			booked_appointments = list(FortuneAppointmentBook.objects.filter(fortune_teller=fortune_teller, appointment_date=date).values_list('appointment_time', flat=True))
			
# 			open_slots = []
	
# 			for data in timedata:
# 				if data['day'] == day:
# 					if not data['is_active']:
# 						return Response({'message': 'No slots available for this day', 'data': open_slots})
					
# 					morning_open = None
# 					morning_close = None
# 					#  check if morning open and close has time slot or not
# 					if data['morning_opening'] and data['morning_closing']:
# 						morning_open = datetime.strptime(data['morning_opening'], '%I:%M %p')
# 						morning_close = datetime.strptime(data['morning_closing'], '%I:%M %p')
	
# 					if morning_open and morning_close:
# 						while morning_open < morning_close:
# 							time_slot = morning_open.strftime('%I:%M %p')
# 							slot_available = True
# 							compare_time = datetime.strptime(str(morning_open), "%Y-%m-%d %H:%M:%S")
# 							date_time_str = datetime.strptime(date, "%d %B %Y").strftime("%Y-%m-%d") + " " + compare_time.strftime("%H:%M:%S")
# 							if datetime.strptime(date_time_str, "%Y-%m-%d %H:%M:%S") < current_time:
# 								slot_available = False
# 							for booked_appointment in booked_appointments:
# 								booked_start, booked_end = booked_appointment.split('-')
# 								if time_slot >= booked_start.strip() and time_slot < booked_end.strip():
# 									slot_available = False
# 									break
	
# 							open_slots.append({
# 								'Time': time_slot,
# 								'Available': slot_available,
# 								'session_time':data['session_time'],
# 								'video_price':data['video_price'],
# 								'chat_price':data['chat_price'],
# 							})
	
# 							morning_open += timedelta(minutes=int(data['session_time']))
					
# 					evening_open = None
# 					evening_close = None
# 					#  check if evening open and close has time slot or not
# 					if data['evening_opening'] and data['evening_closing']:
# 						evening_open = datetime.strptime(data['evening_opening'], '%I:%M %p')
# 						evening_close = datetime.strptime(data['evening_closing'], '%I:%M %p')
	
# 					if evening_open and evening_close:
# 						while evening_open <= evening_close:
# 							time_slot = evening_open.strftime('%I:%M %p')
# 							slot_available = True
# 							compare_time = datetime.strptime(str(evening_open), "%Y-%m-%d %H:%M:%S")
# 							date_time_str = datetime.strptime(date, "%d %B %Y").strftime("%Y-%m-%d") + " " + compare_time.strftime("%H:%M:%S")
# 							if datetime.strptime(date_time_str, "%Y-%m-%d %H:%M:%S") < current_time:
# 								slot_available = False
# 							for booked_appointment in booked_appointments:
# 								booked_start, booked_end = booked_appointment.split('-')
# 								if time_slot >= booked_start.strip() and time_slot < booked_end.strip():
# 									slot_available = False
# 									break
	
# 							open_slots.append({
# 								'Time': time_slot,
# 								'Available': slot_available,
# 								'session_time':data['session_time'],
# 								'video_price':data['video_price'],
# 								'chat_price':data['chat_price'],
# 							})
	
# 							evening_open += timedelta(minutes=int(data['session_time']))

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



# from django.utils import timezone
# class getFortuneTimeSlot(APIView):

# 	def convert_time_to_user_timezone(self, time_str, user_timezone, fortune_timezone,date):
# 		# Convert a time string to the user's time zone
# 		time_format = "%Y-%m-%d %I:%M %p"
# 		date_part = date
# 		input_date = datetime.strptime(date_part, "%d %B %Y")

# 		# New date format as "2022-11-06"
# 		new_date_format = input_date.strftime("%Y-%m-%d")
# 		combined_time = new_date_format + " " + time_str
# 		# Create a datetime object in the source timezone
# 		time = datetime.strptime(combined_time, time_format)
# 		print('time============',time)
# 		time = fortune_timezone.localize(time)
# 		print('time============2',time)
# 		# Convert the time to the target timezone
# 		time = time.astimezone(user_timezone)
# 		print('time============3',time)
# 		return time.strftime(time_format)

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

# 			seer_user_obj = SeerUser.objects.filter(id=uid).first()
# 			fortune_teller = self.request.query_params.get('fortune_teller')
# 			day = self.request.query_params.get('day')
# 			date = self.request.query_params.get('date')

# 			# Determine the user's time zone (e.g., 'Asia/Kolkata')
# 			user_timezone = pytz.timezone(seer_user_obj.timezone)
# 			# Convert the current time to the user's time zone
# 			current_time = timezone.now().astimezone(user_timezone)
# 			# Remove the microseconds and timezone offset from current_time
# 			current_time = current_time.replace(microsecond=0, tzinfo=None)
# 			if not fortune_teller:
# 				return Response({'message': 'fortune_teller is required'}, status=status.HTTP_400_BAD_REQUEST)
			
# 			time_obj = FortuneTellerTiming.objects.filter(fortune_teller=fortune_teller).first()
# 			if not time_obj:
# 				return Response({'message': 'Fortune timing data not found'}, status=status.HTTP_404_NOT_FOUND)
# 			fortune_timezone = pytz.timezone(time_obj.fortune_teller.timezone)
# 			print('fortune_timezone',fortune_timezone)
# 			timedata = json.loads(time_obj.slots)
# 			print('timedata', timedata)
# 			booked_appointments = list(FortuneAppointmentBook.objects.filter(fortune_teller=fortune_teller, appointment_date=date).values_list('appointment_time', flat=True))
			

# 			converted_slots = []

# 			print('converted_slots', converted_slots)


# 			for slot in timedata:
# 				if slot['day'] == day and slot['is_active']:
# 					converted_slot = {
# 						'day': slot['day'],
# 						'is_active': True,
# 						'morning_opening': self.convert_time_to_user_timezone(slot['morning_opening'], user_timezone,fortune_timezone,date),
# 						'morning_closing': self.convert_time_to_user_timezone(slot['morning_closing'], user_timezone,fortune_timezone,date),
# 						'evening_opening': self.convert_time_to_user_timezone(slot['evening_opening'], user_timezone,fortune_timezone,date),
# 						'evening_closing': self.convert_time_to_user_timezone(slot['evening_closing'], user_timezone,fortune_timezone,date),
# 						'chat_price': slot['chat_price'],
# 						'video_price': slot['video_price'],
# 						'session_time': slot['session_time']
# 					}
# 					converted_slots.append(converted_slot)
# 			print('converted_slots------------0',converted_slots)

# 			open_slots = []
	
# 			for data in converted_slots:
# 				if data['day'] == day:
# 					if not data['is_active']:
# 						return Response({'message': 'No slots available for this day', 'data': open_slots})
					
# 					morning_open = None
# 					morning_close = None
# 					#  check if morning open and close has time slot or not
# 					if data['morning_opening'] and data['morning_closing']:
# 						morning_open = datetime.strptime(data['morning_opening'], '%Y-%m-%d %I:%M %p')
# 						morning_close = datetime.strptime(data['morning_closing'], '%Y-%m-%d %I:%M %p')
	
# 					if morning_open and morning_close:
# 						while morning_open < morning_close:
# 							print('yes-------------------')
# 							time_slot = morning_open.strftime('%I:%M %p')
# 							slot_available = True
# 							compare_time = datetime.strptime(str(morning_open), "%Y-%m-%d %H:%M:%S")
# 							date_time_str = datetime.strptime(date, "%d %B %Y").strftime("%Y-%m-%d") + " " + compare_time.strftime("%H:%M:%S")
# 							print('yes-------------------2')
# 							print(datetime.strptime(date_time_str, "%Y-%m-%d %H:%M:%S"))
# 							print('current_time',current_time)
# 							if datetime.strptime(date_time_str, "%Y-%m-%d %H:%M:%S") < current_time:
# 								slot_available = False
# 							for booked_appointment in booked_appointments:
# 								booked_start, booked_end = booked_appointment.split('-')
# 								if time_slot >= booked_start.strip() and time_slot < booked_end.strip():
# 									slot_available = False
# 									break
	
# 							open_slots.append({
# 								'Time': time_slot,
# 								'Available': slot_available,
# 								'session_time':data['session_time'],
# 								'video_price':data['video_price'],
# 								'chat_price':data['chat_price'],
# 							})
	
# 							morning_open += timedelta(minutes=int(data['session_time']))

					
# 					evening_open = None
# 					evening_close = None
# 					#  check if evening open and close has time slot or not
# 					if data['evening_opening'] and data['evening_closing']:
# 						evening_open = datetime.strptime(data['evening_opening'], '%Y-%m-%d %I:%M %p')
# 						evening_close = datetime.strptime(data['evening_closing'], '%Y-%m-%d %I:%M %p')
	
# 					if evening_open and evening_close:
# 						while evening_open <= evening_close:
# 							print('yes-------------------')
# 							time_slot = evening_open.strftime('%I:%M %p')
# 							slot_available = True
# 							compare_time = datetime.strptime(str(evening_open), "%Y-%m-%d %H:%M:%S")
# 							date_time_str = datetime.strptime(date, "%d %B %Y").strftime("%Y-%m-%d") + " " + compare_time.strftime("%H:%M:%S")
# 							if datetime.strptime(date_time_str, "%Y-%m-%d %H:%M:%S") < current_time:
# 								slot_available = False
# 							for booked_appointment in booked_appointments:
# 								booked_start, booked_end = booked_appointment.split('-')
# 								if time_slot >= booked_start.strip() and time_slot < booked_end.strip():
# 									slot_available = False
# 									break
	
# 							open_slots.append({
# 								'Time': time_slot,
# 								'Available': slot_available,
# 								'session_time':data['session_time'],
# 								'video_price':data['video_price'],
# 								'chat_price':data['chat_price'],
# 							})
	
# 							evening_open += timedelta(minutes=int(data['session_time']))

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


# from django.utils import timezone
# class getFortuneTimeSlot(APIView):

# 	def convert_time_to_user_timezone(self, time_str, user_timezone, fortune_timezone,date):
# 		# Convert a time string to the user's time zone
# 		time_format = "%Y-%m-%d %I:%M %p"
# 		date_part = date
# 		input_date = datetime.strptime(date_part, "%d %B %Y")

# 		# New date format as "2022-11-06"
# 		new_date_format = input_date.strftime("%Y-%m-%d")
# 		combined_time = new_date_format + " " + time_str
# 		# Create a datetime object in the source timezone
# 		time = datetime.strptime(combined_time, time_format)
# 		print('time============',time)
# 		time = fortune_timezone.localize(time)
# 		print('time============2',time)
# 		# Convert the time to the target timezone
# 		time = time.astimezone(user_timezone)
# 		print('time============3',time)
# 		return time.strftime(time_format)

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

# 			seer_user_obj = SeerUser.objects.filter(id=uid).first()
# 			fortune_teller = self.request.query_params.get('fortune_teller')
# 			day = self.request.query_params.get('day')
# 			date = self.request.query_params.get('date')

# 			# Determine the user's time zone (e.g., 'Asia/Kolkata')
# 			user_timezone = pytz.timezone(seer_user_obj.timezone)
# 			# Convert the current time to the user's time zone
# 			current_time = timezone.now().astimezone(user_timezone)
# 			# Remove the microseconds and timezone offset from current_time
# 			current_time = current_time.replace(microsecond=0, tzinfo=None)
# 			if not fortune_teller:
# 				return Response({'message': 'fortune_teller is required'}, status=status.HTTP_400_BAD_REQUEST)
			
# 			time_obj = FortuneTellerTiming.objects.filter(fortune_teller=fortune_teller).first()
# 			if not time_obj:
# 				return Response({'message': 'Fortune timing data not found'}, status=status.HTTP_404_NOT_FOUND)
# 			fortune_timezone = pytz.timezone(time_obj.fortune_teller.timezone)
# 			print('fortune_timezone',fortune_timezone)
# 			timedata = json.loads(time_obj.slots)
# 			print('timedata', timedata)
# 			booked_appointments = list(FortuneAppointmentBook.objects.filter(fortune_teller=fortune_teller, appointment_date=date).values_list('appointment_time', flat=True))
			

# 			converted_slots = []

# 			print('converted_slots', converted_slots)


# 			for slot in timedata:
# 				if slot['day'] == day and slot['is_active']:
# 					converted_slot = {
# 						'day': slot['day'],
# 						'is_active': True,
# 						'morning_opening': self.convert_time_to_user_timezone(slot['morning_opening'], user_timezone,fortune_timezone,date),
# 						'morning_closing': self.convert_time_to_user_timezone(slot['morning_closing'], user_timezone,fortune_timezone,date),
# 						'evening_opening': self.convert_time_to_user_timezone(slot['evening_opening'], user_timezone,fortune_timezone,date),
# 						'evening_closing': self.convert_time_to_user_timezone(slot['evening_closing'], user_timezone,fortune_timezone,date),
# 						'chat_price': slot['chat_price'],
# 						'video_price': slot['video_price'],
# 						'session_time': slot['session_time']
# 					}
# 					converted_slots.append(converted_slot)
# 			print('converted_slots------------0',converted_slots)

# 			open_slots = []
	
# 			for data in converted_slots:
# 				if data['day'] == day:
# 					if not data['is_active']:
# 						return Response({'message': 'No slots available for this day', 'data': open_slots})
					
# 					morning_open = None
# 					morning_close = None
# 					#  check if morning open and close has time slot or not
# 					if data['morning_opening'] and data['morning_closing']:
# 						morning_open = datetime.strptime(data['morning_opening'], '%Y-%m-%d %I:%M %p')
# 						morning_close = datetime.strptime(data['morning_closing'], '%Y-%m-%d %I:%M %p')
	
# 					if morning_open and morning_close:
# 						while morning_open < morning_close:
# 							print('yes-------------------')
# 							time_slot = morning_open.strftime('%I:%M %p')
# 							date_slot = morning_open.strftime('%Y-%m-%d')
# 							slot_available = True
# 							compare_time = datetime.strptime(str(morning_open), "%Y-%m-%d %H:%M:%S")
# 							date_time_str = datetime.strptime(date, "%d %B %Y").strftime("%Y-%m-%d") + " " + compare_time.strftime("%H:%M:%S")
# 							print('yes-------------------2')
# 							print(datetime.strptime(date_time_str, "%Y-%m-%d %H:%M:%S"))
# 							if datetime.strptime(date_time_str, "%Y-%m-%d %H:%M:%S") < current_time:
# 								slot_available = False
# 							for booked_appointment in booked_appointments:
# 								booked_start, booked_end = booked_appointment.split('-')
# 								if time_slot >= booked_start.strip() and time_slot < booked_end.strip():
# 									slot_available = False
# 									break
	
# 							open_slots.append({
# 								'Time': time_slot,
# 								'Date':date_slot,
# 								'Available': slot_available,
# 								'session_time':data['session_time'],
# 								'video_price':data['video_price'],
# 								'chat_price':data['chat_price'],
# 							})
	
# 							morning_open += timedelta(minutes=int(data['session_time']))

					
# 					evening_open = None
# 					evening_close = None
# 					#  check if evening open and close has time slot or not
# 					if data['evening_opening'] and data['evening_closing']:
# 						evening_open = datetime.strptime(data['evening_opening'], '%Y-%m-%d %I:%M %p')
# 						evening_close = datetime.strptime(data['evening_closing'], '%Y-%m-%d %I:%M %p')
	
# 					if evening_open and evening_close:
# 						while evening_open <= evening_close:
# 							print('yes-------------------')
# 							time_slot = evening_open.strftime('%I:%M %p')
# 							date_slot = evening_open.strftime('%Y-%m-%d')
# 							slot_available = True
# 							compare_time = datetime.strptime(str(evening_open), "%Y-%m-%d %H:%M:%S")
# 							date_time_str = datetime.strptime(date, "%d %B %Y").strftime("%Y-%m-%d") + " " + compare_time.strftime("%H:%M:%S")
# 							if datetime.strptime(date_time_str, "%Y-%m-%d %H:%M:%S") < current_time:
# 								slot_available = False
# 							for booked_appointment in booked_appointments:
# 								booked_start, booked_end = booked_appointment.split('-')
# 								if time_slot >= booked_start.strip() and time_slot < booked_end.strip():
# 									slot_available = False
# 									break
	
# 							open_slots.append({
# 								'Time': time_slot,
# 								'Date':date_slot,
# 								'Available': slot_available,
# 								'session_time':data['session_time'],
# 								'video_price':data['video_price'],
# 								'chat_price':data['chat_price'],
# 							})
	
# 							evening_open += timedelta(minutes=int(data['session_time']))

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


from django.utils import timezone
class getFortuneTimeSlot(APIView):

	def convert_time_to_user_timezone(self, time_str, user_timezone, fortune_timezone,date):
		# Convert a time string to the user's time zone
		time_format = "%Y-%m-%d %I:%M %p"
		date_part = date
		input_date = datetime.strptime(date_part, "%d %B %Y")

		# New date format as "2022-11-06"
		new_date_format = input_date.strftime("%Y-%m-%d")
		combined_time = new_date_format + " " + time_str
		# Create a datetime object in the source timezone
		time = datetime.strptime(combined_time, time_format)
		time = fortune_timezone.localize(time)
		# Convert the time to the target timezone
		time = time.astimezone(user_timezone)
		return time.strftime(time_format)

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

			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			fortune_teller = self.request.query_params.get('fortune_teller')
			day = self.request.query_params.get('day')
			date = self.request.query_params.get('date')

			# Determine the user's time zone (e.g., 'Asia/Kolkata')
			user_timezone = pytz.timezone(seer_user_obj.timezone)
			# Convert the current time to the user's time zone
			current_time = timezone.now().astimezone(user_timezone)
			# Remove the microseconds and timezone offset from current_time
			current_time = current_time.replace(microsecond=0, tzinfo=None)
			if not fortune_teller:
				return Response({'message': 'fortune_teller is required'}, status=status.HTTP_400_BAD_REQUEST)
			
			time_obj = FortuneTellerTiming.objects.filter(fortune_teller=fortune_teller).first()
			if not time_obj:
				return Response({'message': 'Fortune timing data not found'}, status=status.HTTP_404_NOT_FOUND)
			fortune_timezone = pytz.timezone(time_obj.fortune_teller.timezone)
			timedata = json.loads(time_obj.slots)
			booked_appointments = list(FortuneAppointmentBook.objects.filter(fortune_teller=fortune_teller, appointment_date=date,appointment_status__in=['Pending', 'Accepted']).values_list('appointment_time', flat=True))
			
			
			converted_slots_all_days = []
			# Parse the input date from the query parameters
			input_date = datetime.strptime(date, "%d %B %Y").date()
			# Loop through previous, current, and future days
			for day_offset in range(-1, 2):
				target_date = input_date + timedelta(days=day_offset)
				target_date_str = target_date.strftime("%d %B %Y")

				converted_slots = []

				for slot in timedata:
					if slot['day'] == target_date.strftime('%A') and slot['is_active']:
						converted_slot = {
							'day': slot['day'],
							'is_active': True,
							'morning_opening': self.convert_time_to_user_timezone(slot['morning_opening'], user_timezone, fortune_timezone, target_date_str),
							'morning_closing': self.convert_time_to_user_timezone(slot['morning_closing'], user_timezone, fortune_timezone, target_date_str),
							'evening_opening': self.convert_time_to_user_timezone(slot['evening_opening'], user_timezone, fortune_timezone, target_date_str),
							'evening_closing': self.convert_time_to_user_timezone(slot['evening_closing'], user_timezone, fortune_timezone, target_date_str),
							'chat_price': slot['chat_price'],
							'video_price': slot['video_price'],
							'session_time': slot['session_time']
						}
						converted_slots.append(converted_slot)

				converted_slots_all_days.append({
					'date': target_date_str,
					'converted_slots': converted_slots
				})
			print('converted_slots_all_days------------0',converted_slots_all_days)

			open_slots = []

			for day_data in converted_slots_all_days:
				day = day_data['date']
				converted_slots = day_data['converted_slots']

	
				for data in converted_slots:
					if not data['is_active']:
						continue

					for slot_type in ['morning', 'evening']:
						opening_key = f'{slot_type}_opening'
						closing_key = f'{slot_type}_closing'

						opening_time_str = data[opening_key]
						closing_time_str = data[closing_key]

						if opening_time_str and closing_time_str:
							opening_time = datetime.strptime(opening_time_str, '%Y-%m-%d %I:%M %p')
							closing_time = datetime.strptime(closing_time_str, '%Y-%m-%d %I:%M %p')

							while opening_time < closing_time:
								time_slot = opening_time.strftime('%I:%M %p')
								date_slot = opening_time.strftime('%Y-%m-%d')
								slot_available = True

								compare_time = datetime.strptime(str(opening_time), "%Y-%m-%d %H:%M:%S")
								date_time_str = datetime.strptime(date_slot, "%Y-%m-%d").strftime("%Y-%m-%d") + " " + compare_time.strftime("%H:%M:%S")

								if datetime.strptime(date_time_str, "%Y-%m-%d %H:%M:%S") < current_time:
									slot_available = False

								for booked_appointment in booked_appointments:
									booked_start, booked_end = booked_appointment.split('-')
									if time_slot >= booked_start.strip() and time_slot < booked_end.strip():
										slot_available = False
										break

								open_slots.append({
									'Time': time_slot,
									'Date': date_slot,
									'Available': slot_available,
									'session_time': data['session_time'],
									'video_price': data['video_price'],
									'chat_price': data['chat_price'],
								})

								opening_time += timedelta(minutes=int(data['session_time']))
			# Filter open_slots for the current date
			selected_date_slots = [slot for slot in open_slots if slot['Date'] == input_date.strftime('%Y-%m-%d')]

						
						# evening_open = None
						# evening_close = None
						# #  check if evening open and close has time slot or not
						# if data['evening_opening'] and data['evening_closing']:
						# 	evening_open = datetime.strptime(data['evening_opening'], '%Y-%m-%d %I:%M %p')
						# 	evening_close = datetime.strptime(data['evening_closing'], '%Y-%m-%d %I:%M %p')
		
						# if evening_open and evening_close:
						# 	while evening_open <= evening_close:
						# 		print('yes-------------------')
						# 		time_slot = evening_open.strftime('%I:%M %p')
						# 		date_slot = evening_open.strftime('%Y-%m-%d')
						# 		slot_available = True
						# 		compare_time = datetime.strptime(str(evening_open), "%Y-%m-%d %H:%M:%S")
						# 		date_time_str = datetime.strptime(date, "%d %B %Y").strftime("%Y-%m-%d") + " " + compare_time.strftime("%H:%M:%S")
						# 		if datetime.strptime(date_time_str, "%Y-%m-%d %H:%M:%S") < current_time:
						# 			slot_available = False
						# 		for booked_appointment in booked_appointments:
						# 			booked_start, booked_end = booked_appointment.split('-')
						# 			if time_slot >= booked_start.strip() and time_slot < booked_end.strip():
						# 				slot_available = False
						# 				break
		
						# 		open_slots.append({
						# 			'Time': time_slot,
						# 			'Date':date_slot,
						# 			'Available': slot_available,
						# 			'session_time':data['session_time'],
						# 			'video_price':data['video_price'],
						# 			'chat_price':data['chat_price'],
						# 		})
		
						# 		evening_open += timedelta(minutes=int(data['session_time']))

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



class AddUserCard(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			card_id = request.data.get('card_id')
			if not card_id:
				return Response({'message': 'card_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			if not seer_user_obj.user_stripe_id:
				seer_user_obj.user_stripe_id = generate_strip_id()
				seer_user_obj.save()
			if seer_user_obj.user_stripe_id:
				user_id = seer_user_obj.user_stripe_id
				stripe.api_key = settings.STRIPE_SECRET_KEY
				createCard = stripe.Customer.create_source(user_id,source=card_id)
				if createCard:
					# alreadyAdefaultCardPresent= SeerUserCards.objects.filter(seer_user=seer_user_obj,isdefault=True).first()
					# if alreadyAdefaultCardPresent:
					# 	theDefault=False
					# else:
					# 	theDefault=True
					cardObj = SeerUserCards.objects.create(seer_user=seer_user_obj,card_id=createCard['id'],exp_month=createCard['exp_month'],exp_year=createCard['exp_year'],the_user_stripe=createCard['customer'],last_digits=createCard['last4'])
					alldata = SeerUserCardSerializer(cardObj).data 
			return Response({'message': 'Success', 'data': alldata})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class GetUserCard(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			card_obj = SeerUserCards.objects.filter(seer_user = seer_user_obj)
			alldata = SeerUserCardSerializer(card_obj,many=True).data 
			return Response({'message': 'Success', 'data': alldata})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class DeleteUserCard(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			card_id = request.data.get('card_id')
			if not card_id:
				return Response({'message': 'card_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			card_obj = SeerUserCards.objects.filter(id=card_id).first()
			if not card_obj:
				return Response({'message': 'No card found'}, status=status.HTTP_400_BAD_REQUEST)
			stripe.api_key = settings.STRIPE_SECRET_KEY
			stripe.Customer.delete_source(
				card_obj.the_user_stripe,
				card_obj.card_id
			)
			card_obj.delete()
			return Response({'message': 'Success'})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		

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

			appointment_id = request.data.get('appointment_id')
			if not appointment_id:
				return Response({'message': 'appointment_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			appointment_obj = FortuneAppointmentBook.objects.filter(id=appointment_id).first()
			if not appointment_obj:
				return Response({'message': 'No appointment found'}, status=status.HTTP_400_BAD_REQUEST)
			card_id = request.data.get('card_id')
			if not card_id:
				return Response({'message': 'card_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			card_obj = SeerUserCards.objects.filter(id=card_id,seer_user=uid).first()
			if not card_obj:
				return Response({'message': 'No card found is required'}, status=status.HTTP_400_BAD_REQUEST)
			capture_value = 'false'
			thePaymentObj = paymentWithExistingCard(card_obj.the_user_stripe,card_obj.card_id,appointment_obj.price,capture_value)
			if thePaymentObj['status'] == True:
				CustTransaction = SeerUserTranscation.objects.create(transcation_id=generateTranscationsId(),seer_user=seer_user_obj,booking=appointment_obj,amount=str(appointment_obj.price),txn_id=thePaymentObj['data']['balance_transaction'],recipet_url=thePaymentObj['data']['receipt_url'],payment_mode = thePaymentObj['data']['payment_method_details']['type'],charge_id=thePaymentObj['data']['id'],transcation_type="pay")
				appointment_obj.is_paid = True
				appointment_obj.save()
				
				# wallet_obj = FotuneTellerWallet.objects.filter(fortune_teller=appointment_obj.fortune_teller).first()
				# if wallet_obj:
				# 	wallet_obj.amount += appointment_obj.price
				# 	wallet_obj.save()
				# else:
				# 	FotuneTellerWallet.objects.create(fortune_teller=appointment_obj.fortune_teller,amount=appointment_obj.price)

				# FortuneTellerTranscations.objects.create(transcation_id=generateTranscationsIdFortune(),seer_user=seer_user_obj,fortune_teller=appointment_obj.fortune_teller,amount=appointment_obj.price,payment_mode='wallet',transcation_type="appointment")
				return Response({'message': 'Success'})
			else:
				return Response({'message':thePaymentObj['message']},status=status.HTTP_400_BAD_REQUEST)	
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		

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

			appointment_id = request.data.get('appointment_id')
			if not appointment_id:
				return Response({'message': 'appointment_id is required'}, status=status.HTTP_400_BAD_REQUEST)
			appointment_obj = FortuneAppointmentBook.objects.filter(id=appointment_id).first()
			if not appointment_obj:
				return Response({'message': 'No appointment found'}, status=status.HTTP_400_BAD_REQUEST)
			wallet_obj = SeerUserWallet.objects.filter(seer_user = seer_user_obj).first()
			if not wallet_obj:
				return Response({'message': 'No wallet found for this user.'}, status=status.HTTP_400_BAD_REQUEST)
			if int(appointment_obj.price) > int(wallet_obj.amount):
				print('appointment',appointment_obj.price)
				print('wallet',wallet_obj.amount)

				return Response({'message': 'You do not have sufficent balance in wallet.'}, status=status.HTTP_400_BAD_REQUEST)
			CustTransaction = SeerUserTranscation.objects.create(transcation_id = generateTranscationsId(),seer_user=seer_user_obj,booking=appointment_obj,amount=str(appointment_obj.price),payment_mode = 'wallet',transcation_type='pay')
			appointment_obj.is_paid = True
			appointment_obj.save()	
			new_wallet = int(wallet_obj.amount) - int(appointment_obj.price)
			wallet_obj.amount = new_wallet
			wallet_obj.save()
			# fortune_wallet_obj = FotuneTellerWallet.objects.filter(fortune_teller=appointment_obj.fortune_teller).first()
			# if fortune_wallet_obj:
			# 	fortune_wallet_obj.amount += appointment_obj.price
			# 	fortune_wallet_obj.save()
			# else:
			# 	FotuneTellerWallet.objects.create(fortune_teller=appointment_obj.fortune_teller,amount=appointment_obj.price)

			# FortuneTellerTranscations.objects.create(transcation_id=generateTranscationsIdFortune(),seer_user=seer_user_obj,fortune_teller=appointment_obj.fortune_teller,amount=appointment_obj.price,payment_mode='wallet',transcation_type="appointment")
			return Response({'message': 'Success'})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



# Get all user compatibility score
def get_compatibility_scores(uid,login_user_gender,login_user_horoscope, login_user_chinese_zodiac, login_user_element_name, login_user_mbti_name):
	compatibility_scores = []
	compatibility_data = {}
	
	# Get compatibility scores from Horoscope compatibility table
	if login_user_gender == 'Male':
		horoscope_compatibility = CompatibilityHoroscope.objects.filter(male_horoscope=login_user_horoscope)
		chinese_zodiac_compatibility = CompatibilityChineseZodiac.objects.filter(male_chinese_zodiac=login_user_chinese_zodiac)
		five_elements_compatibility = CompatibilityFiveElements.objects.filter(male_element_name=login_user_element_name)
		mbti_compatibility = CompatibilityMBTI.objects.filter(male_mbti_name=login_user_mbti_name)
		# matching_users = SeerUserSignDetail.objects.filter(seer_user__gender='Female').exclude(seer_user_id=uid)

	else:
		horoscope_compatibility = CompatibilityHoroscope.objects.filter(female_horoscope=login_user_horoscope)
		chinese_zodiac_compatibility = CompatibilityChineseZodiac.objects.filter(female_chinese_zodiac=login_user_chinese_zodiac)
		five_elements_compatibility = CompatibilityFiveElements.objects.filter(female_element_name=login_user_element_name)
		mbti_compatibility = CompatibilityMBTI.objects.filter(female_mbti_name=login_user_mbti_name)
		# matching_users = SeerUserSignDetail.objects.filter(seer_user__gender='Male').exclude(seer_user_id=uid)
	
	# if login_user_gender == 'Male':
	# 	matching_users = SeerUserSignDetail.objects.filter(seer_user__gender='Female').exclude(seer_user_id=uid)
	# else:
	# 	matching_users = SeerUserSignDetail.objects.filter(seer_user__gender='Male').exclude(seer_user_id=uid)
	
	for compatibility in horoscope_compatibility:
		male_horoscope = compatibility.male_horoscope
		female_horoscope = compatibility.female_horoscope
		compatibility_score = compatibility.compatibility_score
		
		if login_user_gender == 'Male':
			matching_users = SeerUserSignDetail.objects.filter(seer_user__gender='Female',horoscope__horoscope=female_horoscope).exclude(seer_user_id=uid)
		else:
			matching_users = SeerUserSignDetail.objects.filter(seer_user__gender='Male',horoscope__horoscope=male_horoscope).exclude(seer_user_id=uid)
		# matching_users = SeerUserSignDetail.objects.filter(horoscope__horoscope=male_horoscope).exclude(seer_user_id=uid)

		for user_signs in matching_users:
			user = user_signs.seer_user
			if user.id not in compatibility_data:
				compatibility_data[user.id] = {
					'user':SeerUserSerializer(user).data,
					'horoscope_compatibility_score': compatibility_score,
				}
			else:
				compatibility_data[user.id]['horoscope_compatibility_score'] = compatibility_score

	# Get compatibility scores from Chinese Zodiac compatibility table
	# chinese_zodiac_compatibility = CompatibilityChineseZodiac.objects.filter(female_chinese_zodiac=login_user_chinese_zodiac)
	for compatibility in chinese_zodiac_compatibility:
		male_chinese_zodiac = compatibility.male_chinese_zodiac
		female_chinese_zodiac = compatibility.female_chinese_zodiac
		compatibility_score = compatibility.compatibility_score
		if login_user_gender == 'Male':
			matching_users = SeerUserSignDetail.objects.filter(seer_user__gender='Female',chinese_zodiac__chinese_zodiac=female_chinese_zodiac).exclude(seer_user_id=uid)
		else:
			matching_users = SeerUserSignDetail.objects.filter(seer_user__gender='Male',chinese_zodiac__chinese_zodiac=male_chinese_zodiac).exclude(seer_user_id=uid)
		# matching_users = SeerUserSignDetail.objects.filter(chinese_zodiac__chinese_zodiac=male_chinese_zodiac).exclude(seer_user_id=uid)

		for user_signs in matching_users:
			user = user_signs.seer_user
			if user.id not in compatibility_data:
				compatibility_data[user.id] = {
				   'user':SeerUserSerializer(user).data,
					'chinese_zodiac_compatibility_score': compatibility_score,
				}
			else:
				compatibility_data[user.id]['chinese_zodiac_compatibility_score'] = compatibility_score

	# Get compatibility scores from Five Elements compatibility table
	# five_elements_compatibility = CompatibilityFiveElements.objects.filter(female_element_name=login_user_element_name)
	for compatibility in five_elements_compatibility:
		male_element_name = compatibility.male_element_name
		female_element_name = compatibility.female_element_name
		compatibility_score = compatibility.compatibility_score

		if login_user_gender == 'Male':
			matching_users = SeerUserSignDetail.objects.filter(seer_user__gender='Female',five_element__element_name=female_element_name).exclude(seer_user_id=uid)
		else:
			matching_users = SeerUserSignDetail.objects.filter(seer_user__gender='Male',five_element__element_name=male_element_name).exclude(seer_user_id=uid)
		# matching_users = SeerUserSignDetail.objects.filter(five_element__element_name=male_element_name).exclude(seer_user_id=uid)

		for user_signs in matching_users:
			user = user_signs.seer_user
			if user.id not in compatibility_data:
				compatibility_data[user.id] = {
					'user':SeerUserSerializer(user).data,
					'five_elements_compatibility_score': compatibility_score,
				}
			else:
				compatibility_data[user.id]['five_elements_compatibility_score'] = compatibility_score

	# Get compatibility scores from MBTI compatibility table
	# mbti_compatibility = CompatibilityMBTI.objects.filter(female_mbti_name=login_user_mbti_name)
	for compatibility in mbti_compatibility:
		male_mbti_name = compatibility.male_mbti_name
		female_mbti_name = compatibility.female_mbti_name
		compatibility_score = compatibility.compatibility_score
		# if login_user_mbti_name is not None:
		if login_user_gender == 'Male':
			matching_users = SeerUserSignDetail.objects.filter(seer_user__gender='Female',mbti__mbti_name=female_mbti_name).exclude(seer_user_id=uid)
		else:
			matching_users = SeerUserSignDetail.objects.filter(seer_user__gender='Male',mbti__mbti_name=male_mbti_name).exclude(seer_user_id=uid)
		# matching_users = SeerUserSignDetail.objects.filter(mbti__mbti_name=male_mbti_name).exclude(seer_user_id=uid)

		for user_signs in matching_users:
			user = user_signs.seer_user
			if user.id not in compatibility_data:
				compatibility_data[user.id] = {
					'user':SeerUserSerializer(user).data,
					'mbti_compatibility_score': compatibility_score,
				}
			else:
				compatibility_data[user.id]['mbti_compatibility_score'] = compatibility_score

	# Convert compatibility_data dictionary to a list
	# compatibility_scores = list(compatibility_data.values())

	# Calculate average compatibility score and compatibility percentage for each user
	for user_id, data in compatibility_data.items():
		compatibility_score_total = 0
		compatibility_percentage_total = 0

		if 'mbti_compatibility_score' in data:
			mbti_weight = 0.5
			horoscope_weight = 0.3
			chinese_zodiac_weight = 0.1
			element_weight = 0.1
		else:
			mbti_weight = 0 
			horoscope_weight = 0.6
			chinese_zodiac_weight = 0.2
			element_weight = 0.2

		if 'horoscope_compatibility_score' in data:
			compatibility_score_total += data['horoscope_compatibility_score'] * horoscope_weight
			compatibility_percentage_total += data['horoscope_compatibility_score'] * horoscope_weight

		if 'chinese_zodiac_compatibility_score' in data:
			compatibility_score_total += data['chinese_zodiac_compatibility_score'] * chinese_zodiac_weight
			compatibility_percentage_total += data['chinese_zodiac_compatibility_score'] * chinese_zodiac_weight
		if 'five_elements_compatibility_score' in data:
			compatibility_score_total += data['five_elements_compatibility_score'] * element_weight
			compatibility_percentage_total += data['five_elements_compatibility_score'] * element_weight

		if 'mbti_compatibility_score' in data:
			compatibility_score_total += data['mbti_compatibility_score'] * mbti_weight
			compatibility_percentage_total += data['mbti_compatibility_score'] * mbti_weight

		 # Calculate the final compatibility score

		data['average_compatibility_score'] = compatibility_score_total
		data['compatibility_percentage'] = compatibility_percentage_total 

		compatibility_scores.append(data)


	return compatibility_scores


class MyMatches(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			
			# Retrieve login user's sign details
			login_user_signs = SeerUserSignDetail.objects.filter(seer_user_id=uid).first()
			if not login_user_signs:
				return Response({'message': 'Sign details not found for the user'}, status=status.HTTP_404_NOT_FOUND)

			login_user_horoscope = login_user_signs.horoscope.horoscope
			login_user_chinese_zodiac = login_user_signs.chinese_zodiac.chinese_zodiac
			login_user_element_name = login_user_signs.five_element.element_name
			if login_user_signs.mbti:
				login_user_mbti_name = login_user_signs.mbti.mbti_name
			else:
				login_user_mbti_name = None
			login_user_gender = login_user_signs.seer_user.gender


			compatibility_data = get_compatibility_scores(uid,login_user_gender,login_user_horoscope,login_user_chinese_zodiac,login_user_element_name,login_user_mbti_name)
			filtered_compatibility_data = [compatibility for compatibility in compatibility_data if compatibility["compatibility_percentage"] >= 70]

			'''===== By Lamda function ====='''
			# filtered_compatibility_data = filter(lambda compatibility: compatibility["compatibility_percentage"] >= 70, compatibility_data)
			# filtered_compatibility_data = list(filtered_compatibility_data)  # Convert the filter object to a list

			
			return Response({'message': 'Success','data': filtered_compatibility_data})

		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		
class SeerUserProfileDetail(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user = SeerUser.objects.filter(id=uid).first()
			if not seer_user:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			data = request.query_params
			matching_user_user = data.get('id')
			if not matching_user_user:
				return Response({'message':'seer user id is required'},status=status.HTTP_400_BAD_REQUEST)
			matching_user_obj = SeerUser.objects.filter(id=matching_user_user).first()
			if not matching_user_user:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			allData=SeerUserCompatibilitySerializer(matching_user_obj,context={'seer_user_id': seer_user.id}).data
			return Response({'message':'Success','data':allData})
		except Exception as e:
			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)

#  This code is basic sample for get all compatibility score from all tables 

"""
class MyMatches(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			
			# Retrieve login user's sign details
			login_user_signs = SeerUserSignDetail.objects.filter(seer_user_id=uid).first()
			if not login_user_signs:
				return Response({'message': 'Sign details not found for the user'}, status=status.HTTP_404_NOT_FOUND)

			login_user_horoscope = login_user_signs.horoscope.horoscope
			login_user_chinese_zodiac = login_user_signs.chinese_zodiac.chinese_zodiac
			login_user_element_name = login_user_signs.five_element.element_name
			login_user_mbti_name = login_user_signs.mbti.mbti_name

			# Retrieve all other users' sign details
			other_users_signs = SeerUserSignDetail.objects.exclude(seer_user_id=uid)
			allData = []
			# Get all table compatibility table
			horoscope_compatibility = CompatibilityHoroscope.objects.all()
			chinese_zodiac_compatibility = CompatibilityChineseZodiac.objects.all()
			five_element_compatibility = CompatibilityFiveElements.objects.all()
			mbti_compatibility = CompatibilityMBTI.objects.all()

			# main code for get compatibility score from all tables.
			for other_users in other_users_signs:
				compatibility_data = {}
				user = other_users.seer_user
				# Get horoscope compatibility score
				other_users_horoscope = other_users.horoscope.horoscope
				for compatibility in horoscope_compatibility:
					if login_user_horoscope == compatibility.female_horoscope:
						if other_users_horoscope == compatibility.male_horoscope:
							horoscope_compatibility_score  = compatibility.compatibility_score
							compatibility_data['user'] = SeerUserSerializer(user).data,
							compatibility_data['horoscope_compatibility_score'] = horoscope_compatibility_score
						
				# Get chinese zodiac compatibility score
				other_users_chinese_zodiac = other_users.chinese_zodiac.chinese_zodiac
				for chinese_compatibility in chinese_zodiac_compatibility:
					if login_user_chinese_zodiac == chinese_compatibility.female_chinese_zodiac:
						if other_users_chinese_zodiac == chinese_compatibility.male_chinese_zodiac:
							chinese_zodiac_compatibility_score  = chinese_compatibility.compatibility_score
							compatibility_data['user'] = SeerUserSerializer(user).data,
							compatibility_data['chinese_zodiac_compatibility_score'] = chinese_zodiac_compatibility_score
			
				# Get five element compatibility score
				other_users_element_name = other_users.five_element.element_name
				for element_compatibility in five_element_compatibility:
					if login_user_element_name == element_compatibility.female_element_name:
						if other_users_element_name == element_compatibility.male_element_name:
							five_element_compatibility_score  = element_compatibility.compatibility_score
							compatibility_data['user'] = SeerUserSerializer(user).data,
							compatibility_data['five_element_compatibility_score'] = five_element_compatibility_score

				# Get mbti compatibility score
				if other_users.mbti:
					other_users_mbti_name = other_users.mbti.mbti_name
					for mbti_compat in mbti_compatibility:
						if login_user_mbti_name == mbti_compat.female_mbti_name:
							if other_users_mbti_name == mbti_compat.male_mbti_name:
								mbti_compatibility_score  = mbti_compat.compatibility_score
								compatibility_data['user'] = SeerUserSerializer(user).data,
								compatibility_data['mbti_compatibility_score'] = mbti_compatibility_score

				allData.append(compatibility_data)

			
			return Response({'message': 'Success','login_user_horoscope':login_user_horoscope,'compatibility_data':allData})

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


class RatingReviewFrotuneteller(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			fortune_teller_id = request.data.get('fortune_teller_id')
			if not fortune_teller_id:
				return Response({'message': 'fortune_teller_id is required'}, status=status.HTTP_404_NOT_FOUND)
			fortune_obj = FortuneTeller.objects.filter(id= fortune_teller_id).first()
			if not fortune_obj:
				return Response({'message': 'No fortune teller found'}, status=status.HTTP_404_NOT_FOUND)
			rating_data = request.data.get('rating_data')
			if not rating_data:
				return Response({'message': 'rating_data is required'}, status=status.HTTP_404_NOT_FOUND)
			review_data = request.data.get('review_data')
			if not review_data:
				return Response({'message': 'review_data is required'}, status=status.HTTP_404_NOT_FOUND)
			FortunetellerRatingReviews.objects.create(seer_user=seer_user_obj,fortune_teller=fortune_obj,rating=rating_data,review=review_data)
			
			# save fortune rating
			total_count = FortunetellerRatingReviews.objects.filter(fortune_teller=fortune_obj).count()
			all_rating = [float(fortune_teller.rating) for fortune_teller in FortunetellerRatingReviews.objects.filter(fortune_teller=fortune_obj)]
			final_rating = sum(all_rating)
			average=float(final_rating)/float(total_count)
			fortune_obj.rating = average
			fortune_obj.save()
			return Response({'message': 'Success'})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		


class referAFriend(APIView):
	def get(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			my_refer_code = seer_user_obj.referal_code
			return Response({'message': 'Success','referal_code':my_refer_code})
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class SeerUserInMyContact(APIView):
	def post(self, request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			data = request.data
			contact_numbers = data.get('contact_numbers', [])
			print('contact_numbers',list(contact_numbers))
			seer_users = SeerUser.objects.filter(phone_number__in=list(contact_numbers))
			user_data = SeerUserSerializer(seer_users, many=True).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 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)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user 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 = SeerUser.objects.get(id=friend_id)
			except SeerUser.DoesNotExist:
				return Response({'message': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

			friendship_request = FriendRequest.objects.filter(from_user=seer_user_obj, to_user=friend).first()
			if not friendship_request:
				friendship_request = FriendRequest.objects.create(from_user=seer_user_obj, to_user=friend, accepted=False)
				

				# push notification
				if friend.notification_status:
					registration_id = friend.fcm_token
					server_key = str(settings.FIREBASE_SERVER_KEY)
					if friend.device_type == 'Android':

						data_message = {		'type': 'friend_request_received',
												'title' : 'NEW FRIEND REQUEST RECEIVED',
												"message" : seer_user_obj.first_name+' '+seer_user_obj.last_name+' sent you a friend request.'
											}
						
						result = FCMNotification(api_key=server_key).notify_single_device(registration_id=registration_id,  data_message=data_message)
					if friend.device_type == 'Ios':
						message_title = 'NEW FRIEND REQUEST RECEIVED',
						message_body =  seer_user_obj.first_name+' '+seer_user_obj.last_name+' sent you a friend request.'
						data_message = {		'type': 'friend_request_received',
												'title' : 'NEW FRIEND REQUEST RECEIVED',
												"message" :  seer_user_obj.first_name+' '+seer_user_obj.last_name+' sent you a friend request.'
											}
						result = FCMNotification(api_key=server_key).notify_single_device(registration_id=registration_id, message_title=message_title, 
						message_body=message_body, data_message=data_message)
				
				# end

				# system notification
				SeerUserNotifications.objects.create(message=seer_user_obj.first_name+' '+seer_user_obj.last_name+' sent you a friend request.',notification_type="friend_request_received",seer_user=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)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user 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 = FriendRequest.objects.get(id=request_id, accepted=False)
			except FriendRequest.DoesNotExist:
				return Response({'message': 'Friendship request not found or already accepted'}, status=status.HTTP_404_NOT_FOUND)

			if status_type == 'Accepted':
				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':

						data_message = {		'type': 'friend_request_accepted',
												'title' : 'REQUEST ACCEPTED',
												"message" : seer_user_obj.first_name+' '+seer_user_obj.last_name+' accepted your friend request.'
											}
						
						result = FCMNotification(api_key=server_key).notify_single_device(registration_id=registration_id,  data_message=data_message)
					if friendship_request.from_user.device_type == 'Ios':
						message_title = 'REQUEST ACCEPTED',
						message_body =  seer_user_obj.first_name+' '+seer_user_obj.last_name+' sent you a friend request.'
						data_message = {		'type': 'friend_request_accepted',
												'title' : 'REQUEST ACCEPTED',
												"message" :  seer_user_obj.first_name+' '+seer_user_obj.last_name+' accepted your friend request.'
											}
						result = FCMNotification(api_key=server_key).notify_single_device(registration_id=registration_id, message_title=message_title, 
						message_body=message_body, data_message=data_message)
				
				# end

				# system notification
				SeerUserNotifications.objects.create(message=seer_user_obj.first_name+' '+seer_user_obj.last_name+' accepted your friend request.',notification_type="friend_request_accepted",seer_user=friendship_request.from_user)

				return Response({'message': 'Friend request accepted'})
			elif status_type == 'Declined':
				friendship_request.delete()
				return Response({'message': 'Friend request rejected'})
			else:
				return Response({'message':'Status type must be Accepted/Declined '},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)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			friendship_request = FriendRequest.objects.filter(from_user=seer_user_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)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			received_friendlist = FriendRequest.objects.filter(to_user=seer_user_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)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			friends = FriendRequest.objects.filter(
				(models.Q(from_user=seer_user_obj) | models.Q(to_user=seer_user_obj)) & models.Q(accepted=True)
			).select_related('from_user', 'to_user')

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

			all_data = SeerUserFriendSerializer(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)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			data = request.query_params
			search = data.get('search')
			if not search:
				return Response({'message':'search is required'},status=status.HTTP_400_BAD_REQUEST)
			search_friend = SeerUser.objects.filter(Q(phone_number__icontains=search)|Q(first_name__icontains=search)|Q(email__icontains=search), end_date__isnull=True).exclude(id=seer_user_obj.id)
			user_data = SeerUserFriendSerializer(search_friend,many=True,context={'login_user': seer_user_obj}).data
			# friend = CheckIsFriendSerializer(search_friend,many=True).data
			# allData =  {
			# 	'user':user_data,
			# 	'friend':friend,
			# }
			return Response({'message': 'success','seer_user_obj':seer_user_obj.id,'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)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user 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 = FriendRequest.objects.get(id=request_id, accepted=False)
			except FriendRequest.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 cancel'})
		except Exception as e:
			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)



"""=============================== CronJob functions ===================================="""

class AppointmentReminderMessage(APIView):
	def get(self,request):
		try:
			now = datetime.now()
			current_time = now.strftime("%I:%M %p")
			today = date.today()
			today_date = today.strftime("%d %b %Y")
			appoint_obj = FortuneAppointmentBook.objects.filter(appointment_status='Accepted')

			for appoint in appoint_obj:
				if appoint.appointment_date == today_date:
					appoint_time = appoint.appointment_time
					new_time = appoint_time.split("-")[0]
					appointment_datetime = datetime.strptime(new_time, "%I:%M %p")
					current_datetime = datetime.strptime(current_time, "%I:%M %p")
					time_difference = appointment_datetime - current_datetime
					if time_difference == timedelta(hours=1):
						message = client.messages.create(
							body=f"Hello {appoint.seer_user.first_name},\n Your today appointment timing {appoint.appointment_time} with {appoint.fortune_teller.first_name} fortune teller, Please join on time.\n Thank you \n Seer Team.",
							from_=from_mobile_number,
							to=appoint.seer_user.phone_number
						)

						message = client.messages.create(
							body=f"Hello {appoint.fortune_teller.first_name},\n You have an appointment at {appoint.appointment_time}. Please be prepared for the session.\n Thank you \n Seer Team.",
							from_=from_mobile_number,
							to=appoint.fortune_teller.phone_number
						)

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


class AppointmentReminderMessagePushNotification(APIView):
	def get(self,request):
		try:
			now = datetime.now()
			current_time = now.strftime("%I:%M %p")
			today = date.today()
			today_date = today.strftime("%d %b %Y")
			appoint_obj = FortuneAppointmentBook.objects.filter(appointment_status='Accepted')

			for appoint in appoint_obj:
				if appoint.appointment_date == today_date:
					appoint_time = appoint.appointment_time
					new_time = appoint_time.split("-")[0]
					appointment_datetime = datetime.strptime(new_time, "%I:%M %p")
					current_datetime = datetime.strptime(current_time, "%I:%M %p")
					time_difference = appointment_datetime - current_datetime
					if time_difference == timedelta(hours=1):
						# message = client.messages.create(
						# 	body=f"Hello {appoint.seer_user.first_name},\n Your today appointment timing {appoint.appointment_time} with {appoint.fortune_teller.first_name} fortune teller, Please join on time.\n Thank you \n Seer Team.",
						# 	from_=from_mobile_number,
						# 	to=appoint.seer_user.phone_number
						# )

						# message = client.messages.create(
						# 	body=f"Hello {appoint.fortune_teller.first_name},\n You have an appointment at {appoint.appointment_time}. Please be prepared for the session.\n Thank you \n Seer Team.",
						# 	from_=from_mobile_number,
						# 	to=appoint.fortune_teller.phone_number
						# )
						"==============Seer user push notification reminder======================"

						seer_user_registration_id = appoint.seer_user.fcm_token
						server_key = str(settings.FIREBASE_SERVER_KEY)
						if appoint.seer_user.device_type == 'Android':

							data_message = {		'type': 'appointment_reminder',
													'title' : 'APPOINTMENT REMINDER',
													"message" : "Hello" + appoint.seer_user.first_name + ",\n Your today appointment timing" + appoint.appointment_time + "with" + appoint.fortune_teller.first_name +  "fortune teller, Please join on time.\n Thank you \n Seer Team."
												}
							
							result = FCMNotification(api_key=server_key).notify_single_device(registration_id=seer_user_registration_id,  data_message=data_message)
						if appoint.seer_user.device_type == 'Ios':
							message_title = 'APPOINTMENT REMINDER',
							message_body =  appoint.seer_user.first_name+' '+appoint.seer_user.last_name+' its your appointment reminder.'
							data_message = {		'type': 'appointment_reminder',
													'title' : 'APPOINTMENT REMINDER',
													"message" :  "Hello" + appoint.seer_user.first_name + ",\n Your today appointment timing" + appoint.appointment_time + "with" + appoint.fortune_teller.first_name +  "fortune teller, Please join on time.\n Thank you \n Seer Team."
												}
							result = FCMNotification(api_key=server_key).notify_single_device(registration_id=seer_user_registration_id, message_title=message_title, 
							message_body=message_body, data_message=data_message)

						"==============End of Seer user push notification reminder======================"

						"==============Fortune teller push notification reminder======================"

						fortune_teller_registration_id = appoint.fortune_teller.fcm_token
						server_key = str(settings.FIREBASE_SERVER_KEY)
						if appoint.fortune_teller.device_type == 'Android':

							data_message = {		'type': 'appointment_reminder',
													'title' : 'APPOINTMENT REMINDER',
													"message" : "Hello" + appoint.fortune_teller.first_name + ",\n You have an appointment at" + appoint.appointment_time + "Please be prepared for the session.\n Thank you \n Seer Team."
												}
							
							result = FCMNotification(api_key=server_key).notify_single_device(registration_id=fortune_teller_registration_id,  data_message=data_message)
						if appoint.fortune_teller.device_type == 'Ios':
							message_title = 'APPOINTMENT REMINDER',
							message_body =  appoint.fortune_teller.first_name+' '+appoint.fortune_teller.last_name+' its your appointment reminder.'
							data_message = {		'type': 'appointment_reminder',
													'title' : 'APPOINTMENT REMINDER',
													"message" :  "Hello" + appoint.fortune_teller.first_name + ",\n You have an appointment at" + appoint.appointment_time + "Please be prepared for the session.\n Thank you \n Seer Team."
												}
							result = FCMNotification(api_key=server_key).notify_single_device(registration_id=fortune_teller_registration_id, message_title=message_title, 
							message_body=message_body, data_message=data_message)
						
						"==============End of Fortune teller push notification reminder======================"

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


"""=============================== End of CronJob functions ===================================="""


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

			"==============Seer user push notification reminder======================"

			seer_user_registration_id = seer_user_obj.fcm_token
			server_key = str(settings.FIREBASE_SERVER_KEY)
			if seer_user_obj.device_type == 'Android':

				data_message = {		'type': 'appointment_reminder',
										'title' : 'APPOINTMENT REMINDER',
										"message" : "Hello seer_user_obj.first_name Your today appointment timing 7:79 with Rahul fortune teller, Please join on time.\n Thank you \n Seer Team."
									}
				
				result = FCMNotification(api_key=server_key).notify_single_device(registration_id=seer_user_registration_id,  data_message=data_message)
			if seer_user_obj.device_type == 'Ios':
				message_title = 'APPOINTMENT REMINDER',
				message_body =  seer_user_obj.first_name+' '+seer_user_obj.last_name+' its your appointment reminder.'
				data_message = {		'type': 'appointment_reminder',
										'title' : 'APPOINTMENT REMINDER',
										"message" :  "Hello seer_user_obj.first_name Your today appointment timing 7:79 with Rahul fortune teller, Please join on time.\n Thank you \n Seer Team."
									}
				result = FCMNotification(api_key=server_key).notify_single_device(registration_id=seer_user_registration_id, message_title=message_title, 
				message_body=message_body, data_message=data_message)

			"==============End of Seer user push notification reminder======================"

			"==============Fortune teller push notification reminder======================"

			# fortune_teller_registration_id = appoint.fortune_teller.fcm_token
			# server_key = str(settings.FIREBASE_SERVER_KEY)
			# if appoint.fortune_teller.device_type == 'Android':

			# 	data_message = {		'type': 'appointment_reminder',
			# 							'title' : 'APPOINTMENT REMINDER',
			# 							"message" : "Hello" + appoint.fortune_teller.first_name + ",\n You have an appointment at" + appoint.appointment_time + "Please be prepared for the session.\n Thank you \n Seer Team."
			# 						}
				
			# 	result = FCMNotification(api_key=server_key).notify_single_device(registration_id=fortune_teller_registration_id,  data_message=data_message)
			# if appoint.fortune_teller.device_type == 'Ios':
			# 	message_title = 'APPOINTMENT REMINDER',
			# 	message_body =  appoint.fortune_teller.first_name+' '+appoint.fortune_teller.last_name+' its your appointment reminder.'
			# 	data_message = {		'type': 'appointment_reminder',
			# 							'title' : 'APPOINTMENT REMINDER',
			# 							"message" :  "Hello" + appoint.fortune_teller.first_name + ",\n You have an appointment at" + appoint.appointment_time + "Please be prepared for the session.\n Thank you \n Seer Team."
			# 						}
			# 	result = FCMNotification(api_key=server_key).notify_single_device(registration_id=fortune_teller_registration_id, message_title=message_title, 
			# 	message_body=message_body, data_message=data_message)
			
			"==============End of Fortune teller push notification reminder======================"
			return Response({'message': 'Success'})
		except Exception as e:
			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		

class CancelAppointment(APIView):
	def post(self,request):
		try:
			try:
				uid = authenticated(request)
			except Exception as e:
				return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
			seer_user_obj = SeerUser.objects.filter(id=uid).first()
			if not seer_user_obj:
				return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
			data = request.data
			appointment_id = data.get('id')
			if not appointment_id:
				return Response({'message':'appointment id is required'},status=status.HTTP_400_BAD_REQUEST)
			cancellation_reason = request.data.get('cancellation_reason')
			if not cancellation_reason:
				return Response({'message': 'Cancellation reason is required'}, status=status.HTTP_400_BAD_REQUEST)
			appointment_obj = FortuneAppointmentBook.objects.filter(id=appointment_id).first()
			if not appointment_obj:
				return Response({'message': 'Appointment not found'}, status=status.HTTP_404_NOT_FOUND)
			
			# Calculate time difference in hours

			appointment_time = appointment_obj.appointment_time
			appointment_date = appointment_obj.appointment_date
			booked_start, booked_end = map(str.strip, appointment_time.split('-'))
			appointment_datetime_start = datetime.strptime(appointment_date + ' ' + booked_start, "%d %B %Y %I:%M %p")
			current_time = datetime.now()
			time_difference = (appointment_datetime_start - current_time).total_seconds()
			difference_hours = time_difference / 3600 
			cancellation_charges = 0
			if difference_hours >= 24:
				refund_percentage = 0.9
				cancellation_charges = 10
			elif difference_hours >= 6:
				refund_percentage = 0.5
				cancellation_charges = 50
			elif difference_hours >= 1:
				refund_percentage = 0.1
				cancellation_charges = 90
			else:
				return Response({'message': 'Sorry, you cannot cancel this appointment. It is too close to the appointment time.'},status=status.HTTP_400_BAD_REQUEST)

			appointment_obj.cancellation_reason = cancellation_reason
			appointment_obj.cancelled_by = 'User'
		
			total_amount = appointment_obj.price
			refund_amount = total_amount * refund_percentage
			if appointment_obj.appointment_status == 'Pending':
				transaction_obj = SeerUserTranscation.objects.filter(booking=appointment_obj).first()
				if not transaction_obj.charge_id:
					AdminRefundRequest.objects.create(appointment=appointment_obj,refund_amount=refund_amount,cancellation_charges=cancellation_charges)
				appointment_obj.appointment_status = 'Canceled'
				appointment_obj.save()
			else:
				appointment_obj.appointment_status = 'Canceled'
				AdminRefundRequest.objects.create(appointment=appointment_obj,refund_amount=refund_amount,cancellation_charges=cancellation_charges)
				appointment_obj.save()
			return Response({'message':'Success'})
		except Exception as e:
			return Response({'message':str(e)},status=status.HTTP_500_INTERNAL_SERVER_ERROR)
		


class DeleteUserAccountView(generics.DestroyAPIView):
	def destroy(self, request):
		try:
			uid = authenticated(request)
		except Exception as e:
			return Response({'message': str(e)}, status=status.HTTP_401_UNAUTHORIZED)
		seer_user_obj = SeerUser.objects.filter(id=uid).first()
		if not seer_user_obj:
			return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
		user_id = uid
		if user_id is None:
			return Response({'message': 'user_id is required'}, status=status.HTTP_404_NOT_FOUND)
		try:
			user = SeerUser.objects.get(id=user_id)
		except user.DoesNotExist:
			return Response({'message': 'user not found'}, status=status.HTTP_404_NOT_FOUND)
		user.account_deleted = True
		user.save()
		return Response({"message": "User deleted successfully"}, status=200)