from __future__ import print_function

from django.shortcuts import render
from django.shortcuts import get_object_or_404

from django.urls import reverse

from django.http import HttpResponse
from django.http import HttpResponseRedirect

from django.contrib.auth.decorators import login_required

from django import template
from django.template.defaultfilters import stringfilter

# Class Based Views (CBV)
from django.views.generic import View
from django.views.generic import ListView


from .models import Course
from .models import Section
from .models import Slide
from .models import UserCourse
from .models import UserSolution

import sys
import json

class ListCourseView(ListView):
    model = Course


###############################################################################
def index(request):
    data = {}
    return render(request, 'courses/index.html')

###############################################################################
def course(request, cid):
    course = get_object_or_404(Course, pk=cid)
    first_section = course.sections.first()
    first_slide = first_section.slides.first()

    if request.user.is_authenticated:
        try:
            # when the user is merely opening the course, jump the last active section (better: last incomplete?)
            user_course = UserCourse.objects.get(course=course, user=request.user)
            return HttpResponseRedirect(reverse('courses:slide', args=(course.id, user_course.progress_section.id, user_course.progress_slide.id)))
        except UserCourse.DoesNotExist:
            # usfrom django import template
            # also redirect to course beginning
            user_course = UserCourse.objects.create(course=course, user=request.user, progress_section=first_section, progress_slide=first_slide)
            return HttpResponseRedirect(reverse('courses:slide', args=(course.id, first_section.id, first_slide.id)))
    else:
        return HttpResponseRedirect(reverse('courses:slide', args=(course.id, first_section.id, first_slide.id)))


    data = {'course': course}
    return render(request, 'courses/course.html', data)


###############################################################################
def section(request, cid, seid):
    course = get_object_or_404(Course, pk=cid)
    section = get_object_or_404(Section, pk=seid)
    first_slide = section.slides.first()
    #print(section.slides, file=sys.stderr)
    #print(first_slide, file=sys.stderr)

    if request.user.is_authenticated:
        try:
            user_course = UserCourse.objects.get(course=course, user=request.user)

            if section.id == user_course.progress_section.id:
                # only redirect if progress was made in this sections
                return HttpResponseRedirect(reverse('courses:slide', args=(course.id, user_course.progress_section.id, user_course.progress_slide.id)))
            else:
                # otherwise switch to first slide in section
                first_slide = section.slides.first()
                return HttpResponseRedirect(reverse('courses:slide', args=(course.id, section.id, first_slide.id)))

        except UserCourse.DoesNotExist:
            # TODO how are direct visitors handled?
            pass
    else:
        return HttpResponseRedirect(reverse('courses:slide', args=(course.id, section.id, first_slide.id)))

    data = {'course': course}
    return render(request, 'courses/course.html', data)


###############################################################################
def slide(request, cid, seid, slid):
    """ The slide view serves the smallest servable unit of material to the
    user. In principle a single slide is meant to provide
    """
    course = get_object_or_404(Course, pk=cid)
    section = get_object_or_404(Section, pk=seid)
    slide = get_object_or_404(Slide, pk=slid)

    if request.user.is_authenticated:
        try:
            user_course = UserCourse.objects.get(course=course, user=request.user)
            # simply update last user_course action
            user_course.progress_section = section
            user_course.progress_slide = slide
            user_course.save()

        except UserCourse.DoesNotExist:
            # TODO Should direct visitors get a special treatment?
            pass



    user_solution = None
    if request.user.is_authenticated:
        try:
            user_solution = UserSolution.objects.get(slide=slide, user=request.user)

        except UserSolution.DoesNotExist:
            # TODO Should direct visitors get a special treatment?
            pass


    #print(user_solution, file=sys.stderr)

    result = request
    #print(result, file=sys.stderr)
    #print(dir(result), file=sys.stderr)

    # determine next slide, as necessary for the navigation
    next_slide = {'course': course, 'section': None, 'slide': None}
    matched_slide = False
    slides = section.slides.all()
    for s in slides:
        if matched_slide:
            next_slide['slide'] = s
            next_slide['section'] = section
            break;

        if slide.id == s.id:
            matched_slide = True

    # looks like the slide was the last for this section find next section
    if next_slide['slide'] == None:
        matched_section = False
        sections = course.sections.all()
        for sec in sections:
            if matched_section:
                next_slide['slide'] = sec.slides.first()
                next_slide['section'] = sec
                break;

            if section.id == sec.id:
                matched_section = True

    try:
        slide_data = json.loads(slide.data)
    except:
        slide_data = "Exception!"


    try:
        user_solution_data = json.loads(user_solution.data)
    except:
        user_solution_data = "Exception!"




    data = {'course': course, 'section': section, 'slide': slide, 'next_slide': next_slide, 'slide_data': slide_data, 'user_solution_data': user_solution_data}
#    return render(request, 'courses/course.html', data)

    try:
        template_path = 'generated_exercises/%s/template.html' % (slide.slide_type)
        print(template_path, file=sys.stderr)
        template.loader.get_template(template_path)
        return render(request, template_path, data)
    except template.TemplateDoesNotExist:
        return render(request, 'courses/course.html', data)
