##
# @file
# File documentation
##
from django.shortcuts import render, redirect  
from discussion.forms import  ThreadForm, TopicForm, SignupForm, SubjectForm, LoginForm
from discussion.models import  Subject_Student, Person, Subject, Topic, Thread, Person, Like
import sys
##
# @brief This function is used for login 
##
def login(request):
	"""This is the function which we call form the login page, here we validate the user for Person table in database ad redirect as 
	per the user that is, if user is proessor we will redirect it to proper webpage"""
	invalid_user = False
	if request.method == "POST":
		form = LoginForm(request.POST)
		
		if form.is_valid():
			try:
				form_pid = form.cleaned_data.get("pid")
				form_pswd = form.cleaned_data.get("password")
				# print (form_pid)
				login = Person.objects.get(pid=form_pid, password=form_pswd)
				# print (login)
				# topic.subject = subject

				# request.session['session_context']['fname'] = login.fname
				# request.session['session_context']['lname'] = login.lname
				request.session['session_context'] = login.pid

				if(login.is_prof == True):
					return redirect('/prof')
					

				return redirect('/')
			except:
				invalid_user = True
		else:

			invalid_user = True
	else:

		form = LoginForm()
	# return render(request,'signup.html',{'form':form})
	
	return render(request, 'login.html', {'form':form, 'invalid_user':invalid_user})
##
# @brief This function is used for logout 
##
def logout(request):
	"""This function is use to logout the current session """
	try:
		del request.session['session_context']
	except:
		pass
	return render(request, 'default.html')
##
# @brief This function is used for signup 
##
def signup(request):
	"""This function is used for signup, here we redirct to the the login page if successfulll done the signup"""
	if request.method == "POST":
		form = SignupForm(request.POST)
		
		if form.is_valid():
			try:
				signup = form.save(commit=False)
				# topic.subject = subject
				form.save()	

				return redirect('/login')
			except:
				pass
	else:
		form = SignupForm()
	return render(request,'signup.html',{'form':form})

##
# @brief This function is used for setting context if the user is professor 
##
def default(request):
	is_prof = False
	try:
		context  = request.session['session_context']
	except:
		context = None

	return render(request, 'default.html' ,{'context':context})


##
# @brief This function is used for rendering the homepage of Professor 
##
def prof_home(request):
	try:
		context  = request.session['session_context']
	except:
		context = None

	return render(request, 'prof_home.html' ,{'context':context})
##
# @brief This function is used for displaying the subject cnd adding new subjects
##
def prof_subjects(request):
	"""This function is used show the corresponding subjects of the Professor and Also provide him option to add  new subjects"""
	context  = request.session['session_context']
	try:
		prof = Person.objects.get(pid=context)
		subjects = Subject.objects.filter(prof = prof)
	except:
		subjects = None

	if request.method == "POST":
		form = SubjectForm(request.POST)
		
		if form.is_valid():
			try:
				subject = form.save(commit=False)
				subject.prof = prof
				form.save()	

				return redirect('/prof/subjects')
			except Exception as e:
				print (e)
	else:
		form = SubjectForm()
	
	
	return render(request,"prof_subjects.html",{'subjects':subjects, 'context':context, 'form':form})
##
# @brief This function is used for displaying the list of students
##
def student_list(request, sub_code):
	"""This list is made availabe to the Professor so that he can see which student's requsts are accepted and, which have pending status"""
	##
	# @param sub_code This varible store the subject code of subject for which Professor has to see the Student List 
	##
	context  = request.session['session_context']
	sub_studs = None
	try:
		prof = Person.objects.get(pid=context)
		subject = Subject.objects.get(prof = prof, sub_code=sub_code)
		sub_studs = Subject_Student.objects.filter(subject = subject)
	except:
		sub_studs = None
	
	
	return render(request,"students_list.html",{'subject':subject, 'context':context, 'sub_studs':sub_studs})
##
# @brief This function is used by Professor to accept student's Requests
##
def accept_student(request, sub_code, pid):
	"""This function update the entry in the Subject_Student table i.e. is_accepted=True"""
	##
	# @param sub_code This varible store the subject code of subject for which students has applied
	# @param pid This contain the id of Person whos has applied for ths course
	##
	context  = request.session['session_context']
	try:	

		sub_stud_to_accept = Subject_Student.objects.get(student = Person.objects.get(pid=pid), subject = Subject.objects.get(sub_code=sub_code))
		sub_stud_to_accept.is_accepted = True
		sub_stud_to_accept.save()

	except Exception as e:
		print (e)
	
	return redirect('/prof/student_list/'+sub_code)
##
# @brief This function is used by Student to request for a Subject
##
def request_subject(request, sub_code):
	"""This function adds a entry in the Subject_Student table with the field is_accepted=False"""
	##
	# @param sub_code This varible store the subject code of subject for which students has applied
	##
	context  = request.session['session_context']
	try:	
		subject = Subject.objects.get(sub_code = sub_code)
		student = Person.objects.get(pid = context)

		sub_stud = Subject_Student(subject = subject, student = student)
		sub_stud.save()

	except Exception as e:
		print (e)
	
	return redirect('/available_subjects')
##
# @brief This function is used by Professor to reject student's Requests or remove the accepted students
##
def reject_student(request, sub_code, pid):
	"""This function deletes the entry in the Subject_Student table i.e. corrosponding to student with given pid and subject code"""
	##
	# @param sub_code This varible store the subject code of subject for which students has applied or get accepted
	# @param pid This contain the id of Person whos has applied for ths course or get accepted in the course
	##
	context  = request.session['session_context']
	try:
		Subject_Student.objects.get(student = Person.objects.get(pid=pid), subject = Subject.objects.get(sub_code=sub_code)).delete()
	except Exception as e:
		print (e)	
	return redirect('/prof/student_list/'+sub_code)
##
# @brief This function is used by Student to reject existing Requests
##
def reject_subject(request, sub_code):
	"""This function deletes the entry in the Subject_Student table i.e. corrosponding to student with given context and subject code"""
	##
	# @param sub_code This varible store the subject code of subject for which students has pending request
	##
	context  = request.session['session_context']
	try:
		Subject_Student.objects.get(student = Person.objects.get(pid=context), subject = Subject.objects.get(sub_code=sub_code)).delete()
	except Exception as e:
		print (e)	
	return redirect('/pending_subjects')
##
# @brief This function is used by Student to withdraw the registered subject
##
def withdraw_subject(request, sub_code):
	"""This function deletes the entry in the Subject_Student table i.e. corrosponding to student with given context and subject code"""
	##
	# @param sub_code This varible store the subject code of subject for which students has been accepted and student wants to withdraw the same
	##
	context  = request.session['session_context']
	try:
		Subject_Student.objects.get(student = Person.objects.get(pid=context), subject = Subject.objects.get(sub_code=sub_code)).delete()
	except Exception as e:
		print (e)	
	return redirect('/subjects')


##
# @brief This function is used by Student to list accepted subjects corresponding to student 
##
def show_subjects(request):
	"""Here in this function we fetch all the requests made by the student and get accepted.
	"""
	context  = request.session['session_context']
	try:
		person = Person.objects.get(pid=context)
	except:
		return redirect('/')
	subject_student = Subject_Student.objects.filter(student = person)
	return render(request,"subjects.html",{'subject_student':subject_student, 'context':context})
##
# @brief This function is used by Student to list all available subjects
##
def show_all_subjects(request):
	"""This function filter the subjects for which student has already requested"""
	context  = request.session['session_context']
	subjects = Subject.objects.all()

	sub_studs = Subject_Student.objects.filter(student = Person.objects.get(pid=context))

	my_subs = []

	for sub_stud in sub_studs:
		my_subs.append(sub_stud.subject.sub_code)

	subjects = subjects.exclude(sub_code__in=my_subs)
	
	return render(request,"available_subjects.html",{'subjects':subjects, 'context':context})
##
# @brief This function is used by Student to list pending subject corresponding to student
##
def show_pending_subjects(request):
	"""Here in this function we fetch all the requests made by the student and requests are pending.
	"""
	context  = request.session['session_context']

	sub_studs = Subject_Student.objects.filter(student = Person.objects.get(pid=context))
	
	return render(request,"pending_subjects.html",{'sub_studs':sub_studs, 'context':context})
##
# @brief This function is used by both Student and Professor to list Topics of corresponding Subject
##
def show_topics(request, id):
	"""In this function we check if the request came from Professor. I yes then we hide the topics in which professor is not included.
	To Students we provide while list.Allow user to add new Topics.
	Again Students have right to exclude the Professor.But Professor doesnot have such option
	"""
	##
	# @param id This varible store the subject code of subject
	##
	context  = request.session['session_context']
	is_prof = False
	try:
		subject = Subject.objects.get(sub_code=id)
	except:
		return redirect('/')

	try:
		person = Person.objects.get(pid=context)
		is_prof = person.is_prof
	except Exception as e:
		print (e)

	if is_prof:
		topics = Topic.objects.filter(subject = subject, is_prof_included=True)
	else:
		topics = Topic.objects.filter(subject = subject)

	if request.method == "POST":
		form = TopicForm(request.POST)
		
		if form.is_valid():
			try:
				topic = form.save(commit=False)
				topic.subject = subject
				if is_prof:
					topic.is_prof_included = True
				form.save()	

				return redirect('/topics/' + str(id))
			except:
				pass
	else:
		form = TopicForm()

	if is_prof:
		return render(request,'prof_discussion_topics.html',{'form':form, 'sub_code':id, 'topics':topics, 'context':context, 'is_prof':is_prof})
	else:
		return render(request,'discussion_topics.html',{'form':form, 'sub_code':id, 'topics':topics, 'context':context, 'is_prof':is_prof})
##
# @brief This function is used by both Student and Professor to list Threads in particular Topics of a Subject
##
def show_threads(request, id):
	"""
	In this function we fetch threads from Thread table filtering as per the Topic 
	"""
	##
	# @param sub_code This varible store the Topic id of Topic for which we wants threads
	##
	context  = request.session['session_context']
	is_prof = False
	try:
		person = Person.objects.get(pid=context)
		is_prof = person.is_prof
	except Exception as e:
		print (e)
	try:
		topic = Topic.objects.get(id=id)
	except:
		return redirect('/')
	threads = Thread.objects.filter(topic = topic)
	if request.method == "POST":
		person = Person.objects.get(pid=context)
		form = ThreadForm(request.POST)
		
		if form.is_valid():
			try:
				thread = form.save(commit=False)
				thread.topic = topic
				thread.person = person
				form.save()

				return redirect('/threads/' + str(id))
			except:
				pass
	else:
		form = ThreadForm()

	if is_prof:
		return render(request,'prof_discussion_threads.html',{'form':form, 'topic_id':id, 'threads':threads, 'context':context, 'is_prof':is_prof}) 
	else:
		return render(request,'discussion_thread.html',{'form':form, 'topic_id':id, 'threads':threads, 'context':context, 'is_prof':is_prof}) 
##
# @brief This function is used by  Student to like a thread
##
def update_thread_like_count(request, thread_id, topic_id):
	"""Here we maintain the like table that stores the like and dislikes per thread, Here we increment the like count 
	and decrement the dislike count if already liked"""
	##
	# @param thread_id This stores the id of thread of which we want to like
	# @param topic_id This stores the id of topic of which the thread belong,This is use to redirect
	##
	"""If already liked then no change occurs"""
	context  = request.session['session_context']
	try:
		thread = Thread.objects.get(id=thread_id)
		person = Person.objects.get(pid=context)
	except Exception as e:
		print (e)
		return redirect('/threads/'+str(topic_id))

	try:
		like = Like.objects.get(thread=thread, person=person)
		if like.is_liked == False :
			like.is_liked = True
			like.save()
			thread.likes = thread.likes + 1
			thread.dislikes = thread.dislikes - 1
			thread.save()
		else:
			pass
	except:
		like = Like(thread=thread, person=person, is_liked = True)
		like.save()
		thread.likes = thread.likes + 1
		thread.save()


	return redirect('/threads/'+str(topic_id))


##
# @brief This function is used by  Studentto dislike a thread
##
def update_thread_dislike_count(request, thread_id, topic_id):
	"""Here we maintain the like table that stores the like and dislikes per thread, Here we increment the disike count 
	and decrement the like count if already disliked"""
	##
	# @param thread_id This stores the id of thread of which we want to dislike
	# @param topic_id This stores the id of topic of which the thread belong,This is use to redirect
	##
	"""If already disliked then no change occurs"""
	context  = request.session['session_context']
	try:
		thread = Thread.objects.get(id=thread_id)
		person = Person.objects.get(pid=context)
	except Exception as e:
		print (e)
		return redirect('/threads/'+str(topic_id))

	try:
		like = Like.objects.get(thread=thread, person=person)
		if like.is_liked == True :
			like.is_liked = False
			like.save()
			thread.likes = thread.likes - 1
			thread.dislikes = thread.dislikes + 1
			thread.save()
		else:
			pass
	except:
		like = Like(thread=thread, person=person, is_liked = False)
		like.save()
		thread.dislikes = thread.dislikes + 1
		thread.save()


	return redirect('/threads/'+str(topic_id))



# def search(request,topic_id):
# 	context  = request.session['session_context']
# 	found_in=[]
# 	value=request.POST['search']
# 	is_prof = False
# 	try:
# 		thread = Thread.objects.filter(topic=topic_id)
# 		person = Person.objects.get(pid=context)
# 		is_prof = person.is_prof
# 		for i in thread:
# 			if value in i.msg or value in i.title or value in i.person.fname or value in i.person.lname:
# 				found_in.append(i) 
# 		for i in found_in:
# 			print(i)

# 	except Exception as e:
# 		print (e)
# 		# print("hello")
# 		return redirect('/threads/'+str(topic_id))

# 	return redirect('/threads/'+str(topic_id))
