from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.template import Context, loader
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout
import os,sys
from django.conf import settings
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.db.models import Q

from .models import *
from .Util import *
from datetime import *

from django.urls import reverse
from .forms import JobUploadForm

from datetime import datetime


# Create your views here.

#HomePage Views
def HomePage(request):
    util = Util()

    context = util.getQuota(request.user)

    context['FeaturedPrint'] = list(FeaturedPrint.objects.all())

    for i in range(0, len(context.get('FeaturedPrint'))):
        for j in range(0, len(context.get('FeaturedPrint')) - i - 1):
            if(context.get('FeaturedPrint')[j].votes < context.get('FeaturedPrint')[j + 1].votes):
                temp = context.get('FeaturedPrint')[j]
                context.get('FeaturedPrint')[j] = context.get('FeaturedPrint')[j + 1]
                context.get('FeaturedPrint')[j + 1] = temp

    for i in range(3, len(context.get('FeaturedPrint'))):
        context.get('FeaturedPrint').pop()

    if(len(context['FeaturedPrint']) < 3):
        context['Featured'] = False
    else:
        context['Featured'] = True
    if(len(context.get('FeaturedPrint')) > 2):
        context['FeaturedPrint0'] = context.get('FeaturedPrint')[0]
        context['FeaturedPrint1'] = context.get('FeaturedPrint')[1]
        context['FeaturedPrint2'] = context.get('FeaturedPrint')[2]

    #profiles = list(Profile.objects.all())
    #context['TopPrints'] = {'Profiles': [],
                            #'Numbers' : [],
                            #}
    #for i in range(1, len(profiles) + 1):
    #    context['TopPrints']['Profiles'].append(profiles[i - 1])
    #    context['TopPrints']['Numbers'].append(i + 1)

    context['TopPrints'] = list(Profile.objects.all())

    context['BestPrintMonth'] = list(Job.objects.filter(job_id = 20))
    context['BestPrintYear' ] = list(Job.objects.filter(job_id = 20))

    return render(request, 'HomePage.html', context)



#Schedule Views
@login_required(login_url='/login/')
def Schedule(request):
    util = Util()

    prints = []
    inQueueList=[]
    printingList=[]
    printed = []
    if request.user.is_superuser:
        inQueue  = list(Job.objects.filter(status = "in Queue").select_related("fk_profile"))
        printing = list(Job.objects.filter(status = "Printing").select_related("fk_profile"))

        for i in range(0, len(inQueue)):
            inQueueList.append(inQueue[i])

        for i in range(0, len(printing)):
            printingList.append(printing[i])

        printed  = list(Job.objects.filter(Q(status="Printed")|Q(status="Failed")))

    else:
        inQueue  = list(Job.objects.filter(status = "in Queue").filter(fk_profile = util.getProfile(request.user)))
        printing = list(Job.objects.filter(status = "Printing").filter(fk_profile = util.getProfile(request.user)))

        for i in range(0, len(inQueue)):
            inQueueList.append(inQueue[i])

        for i in range(0, len(printing)):
            printingList.append(printing[i])

        printed  = list(Job.objects.filter(Q(status="Printed")|Q(status="Failed")).filter(fk_profile = util.getProfile(request.user)))

    

    #Formatting dates correctly
    for i in range(0, len(inQueueList)):       
        
        inQueueList[i].endDate = inQueueList[i].print_end_time.strftime("%d %b %Y")

    for i in range(0, len(printingList)):
        printingList[i].endDate = printingList[i].print_end_time.strftime("%d %b %Y")
    for i in range(0, len(printed)):
        printed[i].endDate = printed[i].print_end_time.strftime("%d %b %Y")

    util = Util()

    context = util.getQuota(request.user)

    context['Jobs'] = prints
    context['inQueueContextObject'] = inQueueList
    context['PrintingContextObject'] = printingList
    context['Printed'] = printed

    #for i in range(0, len(prints)):
        #context["Job"    + str(i)] = prints[i].__str__()
        #context["Status" + str(i)] = prints[i].status

    if(len(printed) >= 3):
        context['Recent']       = True
        context['RecentPrints0'] = printed[0]
        context['RecentPrints1'] = printed[1]
        context['RecentPrints2'] = printed[2]
    else :
        context['Recent'] = False

    return render(request, 'SchedulePage.html', context)



#Submit Views
@login_required(login_url='/login/')
def Submission(request):
    util = Util()

    context = util.getQuota(request.user)

    #return render(request, 'SubmitFile.html', context)

    if request.method == 'POST':
        form = JobUploadForm(request.POST, request.FILES)

        if form.is_valid():
            
            newJob=form.save()        
            newJob.status           = 'in Queue'
            newJob.upload_time      = datetime.now()
            newJob.print_start_time = util.getPrintStartTime()
            newJob.print_end_time   = util.getPrintEndTime(request.FILES['file_path_stl'])
            newJob.fk_profile       = util.getProfile(request.user)
            newJob.printer_name     = util.getPrinterName();
            newJob.save()
            return redirect("request/success/")
    else:
        form = JobUploadForm()

    return render(request, 'SubmitFile.html', {'form': form})


def created(request):
    return render(request, 'thanks.html')
    

@login_required(login_url='/login/')
def Preview(request):
    return HttpResponse("Preview your model")

@login_required(login_url='/login/')
def SubmissionRequest(request):
    try:
        if request.method == 'POST':

            newJob = Job()
            util   = Util()

            newJob.job_title = request.POST['printName']
            newJob.colour    = request.POST['colour']

            #pathSTL, pathOBJ = util.handle_file(request.FILES['file'], request.POST.get('printName'), request.user)
            #newJob.file_path_stl = pathSTL
            #newJob.file_path_obj = pathOBJ

            newJob.status           = 'in Queue'
            newJob.upload_time      = datetime.now()
            newJob.print_start_time = util.getPrintStartTime()
            newJob.print_end_time   = util.getPrintEndTime(request.FILES['file'])
            newJob.fk_profile       = util.getProfile(request.user)
            newJob.printer_name     = util.getPrinterName();


            newJob.save()

            pathSTL, pathOBJ = util.handle_file(request.FILES['file'], request.POST['printName'], request.user, newJob.job_id)
            newJob.file_path_stl = pathSTL
            newJob.file_path_obj = pathOBJ

            newJob.save()

            #return HttpResponse("Submission Form")
            return redirect("success/")
        else:
            return redirect('fail/')
    except Exception as e:
        sys.stdout.write(e)
        return redirect('fail/')

@login_required(login_url='/login/')
def Success(request):
    util = Util()

    context = util.getQuota(request.user)
    #return HttpResponse("Submission Success")
    return render(request, 'SubmissionSuccess.html', context)

@login_required(login_url='/login/')
def Fail(request):
    util = Util()

    context = util.getQuota(request.user)
    return HttpResponse("Submission Fail")

@login_required(login_url='/login/')
def PrintData(request, jobid):
    printData = list(Job.objects.filter(job_id=jobid))

    for i in range(0, len(printData)):
        printData[i].uploadDate = str(printData[i].upload_time.day)      + ' / ' + str(printData[i].upload_time.month)      + ' / ' + str(printData[i].upload_time.year)
        printData[i].startDate  = str(printData[i].print_start_time.day) + ' / ' + str(printData[i].print_start_time.month) + ' / ' + str(printData[i].print_start_time.year)
        printData[i].endDate    = str(printData[i].print_end_time.day)   + ' / ' + str(printData[i].print_end_time.month)   + ' / ' + str(printData[i].print_end_time.year)

    util = Util()

    context = util.getQuota(request.user)
    context['JobData'] = printData

    printData = list(Job.objects.filter(job_id=jobid))

    context['filePath'] = printData[0].file_path_stl
    context['jobid']    = jobid

    return render(request, 'PrintData.html', context)

def PrintDownload(request, jobid):
    #context = {}
    printData = list(Job.objects.filter(job_id=jobid))
    file_name = printData[0].file_path_stl

    response = HttpResponse(open(file_name, 'rb').read())
    response['Content-Type'] = 'application/sla'
    response['Content-Disposition'] = 'attachment;filename=%s' % file_name

    return(response)




#Account Views
@login_required(login_url='/login/')
def AccountData(request):
    util = Util()

    context = util.getQuota(request.user)
    context['name']  = util.getProfile(request.user).__str__()
    context['class'] = str(util.getProfile(request.user).grade) + util.getProfile(request.user).section

    #if request.user.is_superuser:
    #    printed  = list(Job.objects.filter(status = "Printed"))
    #else:
    #    printed  = list(Job.objects.filter(status = "Printed").filter(fk_profile = util.getProfile(request.user)))
    if(not(request.user.is_superuser)):
        printed  = list(Job.objects.filter(status = "Printed").filter(fk_profile = util.getProfile(request.user)))
        if(len(printed) >= 3):
            context['Recent']       = True
            context['RecentPrints0'] = printed[0]
            context['RecentPrints1'] = printed[1]
            context['RecentPrints2'] = printed[2]
        else:
            context['Recent'] = False

    return render(request, 'AccountData.html', context)

@login_required(login_url='/login/')
def EditAccount(request):
    return HttpResponse("Account Editor")

@login_required(login_url='/login/')
def Login(request):
    return HttpResponse("Login to Account")

#@login_required(login_url='/login/')
#def layout(request):
#    context = {'Quota' : '00:31:23'}

#    if request.user.is_authenticated():
#        context['LogButton'] = 'LOGOUT'
#    else:
#        context['LogButton'] = 'LOGIN'

#    return render(request, 'layout.html', context)



def UserGuidePage(request):
    util = Util()

    context = util.getQuota(request.user)
    return render(request, 'UserGuidePage.html', context)


#Login views
def Login(request):
    util = Util()

    context = util.getQuota(request.user)
    context['next'] = request.GET.get('next')

    return render(request, 'Login.html', context)


def Authenticate(request):
    username = request.POST['username']
    password = request.POST['password']

    user = authenticate(request, username = username, password = password)

    next = request.POST['next']

    if user is not None:
        login(request, user)
        return redirect(next)
    else:
        return redirect('/login/?next=/home/')
    #return HttpResponse("Auth")

def Logout(request):
    logout(request)
    return redirect('/login/')

#Featured Prints
def Featured(request):
    util = Util()

    context = util.getQuota(request.user)
    context['Jobs'] = list(FeaturedPrint.objects.all())

    for i in range(0, len(context.get('Jobs'))):
        for j in range(0, len(context.get('Jobs')) - i - 1):
            if(context.get('Jobs')[j].votes < context.get('Jobs')[j + 1].votes):
                temp = context.get('Jobs')[j]
                context.get('Jobs')[j] = context.get('Jobs')[j + 1]
                context.get('Jobs')[j + 1] = temp

    context['num'] = len(context.get('Jobs'))

    context['hiddenVar'] = []#{'prints':[],
                             #'ids'   :[],}

    for i in range(1, len(context.get('Jobs')) + 1):
        var = {}
        #context.get('hiddenVar').get('ids').append('ModelName' + str(i))
        #context.get('hiddenVar').get('prints').append(context.get('Jobs')[i - 1])
        var['ids']    = 'modelName' + str(i)
        var['prints'] = context.get('Jobs')[i - 1]

        context.get('hiddenVar').append(var)



    return render(request, 'FeaturedPrints.html', context)


#Layout
def Layout(request):
    util = Util()

    context = util.getQuota(request.user)

    return render(request, 'Layout.html', context)


#ADMIN
@login_required(login_url='/infidel/')
def AdminHome(request):
    if(request.user.is_superuser):
        context = {}
        return render(request, 'Admin.html', context)
    else:
        return redirect('/infidel/')
        #return HttpResponse("This is the grown up's table! It's not for sneaky idiots like you!")

@login_required(login_url='/infidel/')
def IncreaseGrade(request):
    if(request.user.is_superuser):
        util = Util()
        util.changeGrade(1)
        return redirect('/ADMIN/')
    else:
        return redirect('/infidel/')

@login_required(login_url='/infidel/')
def DecreaseGrade(request):
    if(request.user.is_superuser):
        util = Util()
        util.changeGrade(-1)
        return redirect('/ADMIN/')
    else:
        return redirect('/infidel/')

def AdminExcel(request):
    if(request.user.is_superuser):
        util = Util()
        context= util.getQuota(request.user)
        return render(request, 'AdminExcel.html', context)
    else:
        return redirect('/infidel/')


def ReturnStudentList(request):
    if(request.user.is_superuser):
        file_name = "Students.xls"

        util = Util()
        students = list(Profile.objects.all())

        studentData = []
        #print("Num Students:")
        #print(len(students))

        for i in range(0, len(students)):
            s = []
            s.append(str(i + 1))
            s.append(students[i].user.first_name)
            s.append(students[i].user.last_name)
            s.append(students[i].user.username)
            s.append(students[i].grade)
            s.append(students[i].section)
            s.append(students[i].quota)
            studentData.append(s)

        util.writeTo(file_name, studentData)

        #response = HttpResponse(content_type='application/ms-excel')
        #response['Content-Disposition'] = 'attachment;filename=%s' % file_name
        #response['X-sendfile'] = os.path.join(os.path.dirname(__file__), file_name)
        #print(response)
        #print(os.path.join(os.path.dirname(__file__), file_name))

        response = HttpResponse(open(file_name, 'rb').read())
        response['Content-Type'] = 'application/ms-excel'
        response['Content-Disposition'] = 'attachment;filename=%s' % file_name

        return(response)

    else:
        return redirect('/infidel/')

def ReturnJobList(request):
    if(request.user.is_superuser):
        file_name = "Jobs.xls"

        util = Util()
        jobs = list(Job.objects.all())

        jobData = []
        #print("Num Students:")
        #print(len(students))

        for i in range(0, len(jobs)):
            j = []
            j.append(str(i + 1))
            j.append(jobs[i].job_id)
            j.append(jobs[i].job_title)
            j.append(jobs[i].colour)
            j.append(jobs[i].upload_time)
            j.append(jobs[i].print_start_time)
            j.append(jobs[i].print_end_time)
            j.append(jobs[i].printer_name)
            j.append(jobs[i].fk_profile.user.username)
            j.append(jobs[i].file_path_stl)
            j.append(jobs[i].file_path_obj)
            j.append(jobs[i].special_marker)
            jobData.append(j)

        util.writeTo(file_name, jobData)

        #response = HttpResponse(content_type='application/ms-excel')
        #response['Content-Disposition'] = 'attachment;filename=%s' % file_name
        #response['X-sendfile'] = os.path.join(os.path.dirname(__file__), file_name)
        #print(response)
        #print(os.path.join(os.path.dirname(__file__), file_name))

        response = HttpResponse(open(file_name, 'rb').read())
        response['Content-Type'] = 'application/ms-excel'
        response['Content-Disposition'] = 'attachment;filename=%s' % file_name

        return(response)

    else:
        return redirect('/infidel/')


@login_required(login_url='/infidel/')
def Printer(request, name):
    if(request.user.is_superuser):
        context = {'name':name,}

        current = list(Job.objects.filter(printer_name = name).filter(status = 'Printing'))
        if(len(current) > 0):
            context['current'] = current

            if(len(current) > 1):
                context['currentLen']  = len(current)

        inQueue = list(Job.objects.filter(printer_name = name).filter(status = 'in Queue'))
        context['inQueue'] = inQueue

        return render(request, 'Printer.html', context)
    else:
        return redirect('/infidel/')

@login_required(login_url='/infidel/')

def Printed(request, jobid):
    if(request.user.is_superuser):
        jobs = list(Job.objects.filter(job_id = jobid))
        if(len(jobs) == 1):

            job = jobs[0]
            job.status = "Printed"
            time = int(request.GET['job_time'])
            job.print_time = str(time)

            profile = job.fk_profile# -= time
            profile.quota = profile.quota - time

            if(profile.quota < 0):
                profile.quota = 0

            job.save()

            profile.save()

            return HttpResponse('success')

    else:
        return redirect('/infidel/')

def Printing(request, jobid):
    if(request.user.is_superuser):
        jobs = list(Job.objects.filter(job_id = jobid))
        if(len(jobs) == 1):

            job = jobs[0]
            job.status = "Printing"
            job.save()

            #path = '/printer/' + job.printer_name
            return redirect('/printData/download/' + str(jobid))

    else:
        return redirect('/infidel/')

#Errors
#def error_404_view(request, exception):
#    context = {'Quota' : '00:31:23',}
#    return render(request, '404.html', context)

#def error_500_view(request, exception):
#    context = {'Quota' : '00:31:23',}
#    return render(request, '500.html', context)

def Infidel(request):
    return HttpResponse("This is the grown up's table! It's not for sneaky idiots like you!<br>I've got to say though, nice try!<br>But now it's time for bed.<br><br>GO <a href='/home'>Home</a>!!!")


@login_required(login_url='/login/')
def viewSTL(request, jobid):
    printData = list(Job.objects.filter(job_id=jobid))    
    util = Util()

    context = util.getQuota(request.user)
    context['JobData'] = printData    
    context['filePath'] = printData[0].file_path_stl
    context['jobid']    = jobid
    
    return render(request, 'CustomView.html', context)
