from django.shortcuts import render
from django.http import HttpResponse
from django.core.paginator import Paginator
from django.http import HttpResponseRedirect
from django.db.models import Max
from django.shortcuts import redirect
from .forms import UploadFileForm
from . newQuiz import readCSV
from . models import Questions
from . models import quiz
from .models import submission
from .models import cribs
from .models import result as results
from .models import cribs as crib
from .models import Permission
from .models import log
import collections
from django.db import connection, transaction
import numpy as np
import math
import pandas as pd
import scipy.stats as stats
import csv
from prettytable import PrettyTable
#for login
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login
from django.contrib.auth.decorators import login_required
from django.db.models import Count
import matplotlib.pyplot as plt, mpld3
import json
import random
import string 
from datetime import datetime
from django.views.decorators.clickjacking import xframe_options_exempt
from django.core.files import File
from django.utils import timezone
from django.core.files.storage import default_storage

startedquiz = dict()

def index(request):
    quiz_id = int(request.GET['q'])
    quizInstance = quiz.objects.get(pk=quiz_id)
    obj = Questions.objects.filter(quizId=quizInstance).all().order_by('questionId')
    endtime = quizInstance.end_datetime
    endtime = json.dumps(endtime.isoformat())
    count = len(obj)
    return render(request,'index.html',{'questions':obj,'count':count, 'endtime': endtime, 'quizId': quiz_id})

@login_required
def result(request):
    if request.user.is_authenticated and request.method =="POST":
        quizId=int(request.POST['quizId'])
        quizInstance = quiz.objects.get(pk=quizId)
        prev_subm = submission.objects.all().filter(quizId=quizInstance, studentId=request.user)
        score = 0
        if len(prev_subm)==0:
            for questionno in request.POST:
                if questionno.startswith('question_'):
                    questionId = int(questionno[9:])
                    questionInstance = Questions.objects.get(pk=questionId)
                    q=Questions.objects.all().filter(quizId=quizInstance,questionId=questionId).values()
                    if(request.POST[questionno]==q[0]['answer']):
                        score+=q[0]['marks']
                    else:
                        score-=q[0]['negative']
                    t=submission(questionId=questionInstance, option=request.POST[questionno], studentId=request.user, quizId=quizInstance)
                    t.save()
            t=results(quizId=quizInstance,studentId=request.user,marks=int(score))
            t.save()
            return redirect('/view_submission/?q='+str(quizId))
        else:
            return HttpResponse("You have already submitted this quiz")
                

    
    
def save_ans(request):
    ans = request.GET['ans']
    quizId=request.GET['quizId']
    questionId=request.GET['questionId']
    studentId=1# initialize here student id
    t=submission(questionId=questionId,option=ans,quizId=quizId,studentId=studentId)
    t.save()
    return HttpResponse('')

def save_cribs(request):
    crib=request.GET.get('cribs')
    quizId=int(request.GET.get('quiz'))
    quizInstance = quiz.objects.get(pk=quizId)
    questionId=int(request.GET.get('question'))
    questionInstance = Questions.objects.get(pk=questionId)
    t=cribs(cribs=crib,studentId=request.user,questionId=questionInstance,quizId=quizInstance)
    t.save()
    return HttpResponse('Suuuuuccess')  
    
def upload(request):
    return render(request,'upload.html')

@login_required
def student(request):
    role = Permission.objects.all().filter(userId=request.user).values('role')[0]['role'];
    quizzes=quiz.objects.all().values('quizId','quizCode')
    quizId=list()
    quizCode=list()
    for q in quizzes:
        quizId.append((q['quizId'],q['quizCode']))

    if role:
        if role == "S":
            return render(request,'student.html',{'quizId':quizId})
        else:
            quizzes=quiz.objects.all().filter(quizInstructor=request.user.id).values('quizId','quizCode','quizInstructor')
            quizId=list()
            for q in quizzes:
                quizId.append((q['quizId'],q['quizCode']))
            return render(request,'professor.html',{'quizId':quizId})
    return HttpResponse('Role not configured in Permission table')

def ongoing_quiz(request):
    quizzes = quiz.objects.all().values('quizId', 'quizCode')
    quizId = list()
    quizCode = list()
    for q in quizzes:
        quizId.append((q['quizId'], q['quizCode']))
    return render(request, 'ongoing_quiz.html', {'quizId': quizId})

def upload_file(request):
    uploaded=False
    temp1='test'
    random_code = ''.join(random.choices(string.ascii_uppercase + string.digits, k = 6)) 
    q= quiz(length=request.POST.get('length'),quizCode=random_code,quizInfo=request.POST.get('quiz_name'),date=request.POST.get('date'),
    quizInstructor=request.user,startTime =request.POST.get('startTime'),quizDone=False)
    q.save()
    form = UploadFileForm(request.POST, request.FILES)
    if request.method == 'POST' and form.is_valid():
        handle_uploaded_file(request.FILES['file'],q)
        uploaded=True
        return HttpResponse('success')

    else :
        return render(request,'upload.html',{temp1:'invalid File'})
    
    
def instructor(request):
    q_id = request.GET.get('quiz_id')
    quizId = 0
    allquizs = quiz.objects.all().filter(quizInstructor=request.user).order_by('-date', '-startTime')
    if q_id:
        quizId = int(q_id)
    else:
        #quizId = quiz.objects.all().filter(quizInstructor=request.user)[0]
        if True:
            quizId = allquizs[0].quizId
        else:
            print(quizId)

    quizInstance = quiz.objects.all().filter(quizId=quizId, quizInstructor=request.user)[0]
    students = results.objects.all().filter(quizId=quizId).values('studentId')
    marks = results.objects.all().filter(quizId=quizId).values('marks')
    cribs=crib.objects.all().filter(quizId=quizId).select_related()
   
    fig, ax = plt.subplots()
    allMarks=list()
    for mark in marks:
        allMarks.append(mark['marks'])
    allStudents=list()
    for student in students:
        allStudents.append(student['studentId'])
    std=np.std(allMarks)
    mean=np.mean(allMarks)
    data =allMarks
    c = collections.Counter(data)
    c = sorted(c.items())
    score_num = [i[0] for i in c]
    freq = [i[1] for i in c]
    plt.barh(score_num, freq)
    plt.title("Score V/S N.O of Students")
    plt.xlabel("N.O of Students")
    plt.ylabel("Scores")
    ax.set_xticks(range(1,len(allMarks)+1))
    #ax.set_xticklabels(months)
    html_graph = mpld3.fig_to_html(fig) 
    fig1, ax1 = plt.subplots()
    mu = mean
    variance = np.std(allMarks)
    sigma = math.sqrt(variance)
    x = np.linspace(mu - 3*sigma, mu + 3*sigma, 100)
    ax1.plot(x, stats.norm.pdf(x, mu, sigma))
    ax1.set_title('Normal Distribution for Scores to Students')
    ax1.set_xlabel('Score')
    ax1.set_ylabel('PDF')
    html_graph1 = mpld3.fig_to_html(fig1)
    quizDone = False
    if quizInstance.end_datetime < datetime.now():
        quizDone = True
    return render(request, 'instructor.html',{"graph": html_graph, "graph1": html_graph, "graph2": html_graph1,'quiz':quizInstance,'cribs':cribs, 'all_quizes': allquizs, 'quizDone':quizDone})

def quizTable(request):
    quizs = quiz.objects.filter(quizInstructor=request.user).all()
    return render(request,'quizTable.html',{'quiz':quizs})

def handle_uploaded_file(f,q1):
    with open('name.csv', 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)
    destination=open("name.csv","r") 
    rows=readCSV(destination)
    for row in rows:
        
        q=Questions(question=row[0],option1=row[1],option2=row[2],option3=row[3],option4=row[4],answer=row[5],type=row[6],marks=int(row[7]),negative=float(row[8]),explainations=row[9],quizCode=q1.quizCode,quizId=q1)#hardcoded quizid
        q.save()

def create_quiz(request):
    return render(request, 'quiz_create.html')


#login functionality
def sign_up(request):
    context = {}
    form = UserCreationForm(request.POST or None)
    if request.method == "POST":
        if form.is_valid():
            user = form.save()
            login(request.user)
            return render(request,'student.html')
    context['form']=form
    return render(request,'registration/signup.html',context)



@login_required
def submissions(request):
    #prev_subm = submission.objects.all().filter(studentId=request.user)
    prev_subm = submission.objects.all().filter(studentId=request.user).values('quizId').annotate(dcount=Count('quizId'))
    return render(request,'submissions.html', { 'submissions' : prev_subm })


@login_required
def view_sub(request):
    if request.method == "GET":
        quizId = int(request.GET.get('q'))
        quizInstance = quiz.objects.get(pk=quizId)
        subs = submission.objects.filter(quizId=quizInstance, studentId=request.user).select_related().all()
        score = 0
        total = 0
        message = ''
        for sub in subs:
            if sub.option == sub.questionId.answer:
                score = score + sub.questionId.marks
            else:
                score = score - sub.questionId.negative
            total = total + sub.questionId.marks
        return render(request,'view_submissions.html', { 'submissions' : subs , 'score': round(score,2), 'total': total, 'quizId': quizId })
        

def add_quiz(request):
    vals=list()
    for req in request.POST.values():
        vals.append(req)
    i=1
    quizName= vals[i]
    i+=1
    date=vals[i]
    i+=1
    startTime=vals[i]
    i+=1
    length=vals[i]
    i+=1
    random_code = ''.join(random.choices(string.ascii_uppercase + string.digits, k = 6)) 
    q= quiz(length=length,quizCode=random_code,quizInfo=quizName,date=date,
    quizInstructor=request.user,startTime =startTime,quizDone=False)
    q.save()

    while(i<len(vals)):
        
        row=(vals[i],vals[i+1],vals[i+2],vals[i+3],vals[i+4],vals[i+5],vals[i+6],vals[i+7],vals[i+8])
        q1=Questions(question=row[0],option1=row[1],option2=row[2],option3=row[3],option4=row[4],
        answer=row[7],marks=int(row[5]),negative=float(row[6]),explainations=row[7],quizCode=q.quizCode,quizId=q)
        q1.save()
        i=i+9
    return HttpResponse('success')#(request,'success')

def monitor(request):
    q_id = request.GET.get('quiz')
    allquizs = quiz.objects.all().filter(quizInstructor=request.user).order_by('-date', '-startTime')

    if q_id:
        quizId = int(q_id)
        quizInstance = quiz.objects.get(pk=quizId)
        startedquiz[quizId] = dict()
        return render(request, 'monitor.html', { 'quiz': quizInstance , 'all': allquizs })
    else:
        quizId = allquizs[0].quizId
        startedquiz[quizId] = dict()
        return render(request, 'monitor.html', { 'quiz': allquizs[0] , 'all': allquizs })
    

@xframe_options_exempt
def getbeat(request):
    quizId = int(request.GET.get('quiz'))
    test = startedquiz.get(quizId)
    return render(request,'student_activity.html', {'activity': test })

def view_logs(request):
    quizId = int(request.GET.get('quiz'))
    quizInstance = quiz.objects.get(pk=quizId)
    quiz_logs = log.objects.all().filter(quizId=quizInstance)
    return render(request,'log.html', {'logs': quiz_logs })

def heartbeat(request):
    quizId = int(request.GET.get('quiz'))
    quizInstance = quiz.objects.get(pk=quizId)
    if quizId in startedquiz:
        question = int(request.GET.get('question'))
        fs = request.GET.get('fullscreen')
        db = request.GET.get('log')
        time = timezone.now()
        jtime = json.dumps(time.isoformat())
        startedquiz[quizId][request.user] = (question, fs, jtime)
        if db == "true":
            if fs == "true":
                fstext="Entered Fullscreen"
            else:
                fstext="Left Fullscreen"
            l=log(quizId=quizInstance, studentId=request.user, fullscreen=fstext, questions=str(question))
            l.save()
            print("Log saved!")
            
    return HttpResponse('')