# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import ListView, CreateView, UpdateView, DetailView, View
import weasyprint
from io import StringIO, BytesIO
import re
from markdown import markdown
import asciimathml
from xml.etree.ElementTree import tostring

from .models import Subject, Argument


class SubjectList(LoginRequiredMixin, ListView):
    model = Subject
    context_object_name = 'subjects_list'
    template_name = 'subjects/list.html'

    def get_context_data(self, **kwargs):
        context = super(SubjectList, self).get_context_data(**kwargs)

        queryset = self.get_queryset()
        for subject in queryset:
            subject.arguments_count = subject.argument_set.count()
        context[self.context_object_name] = queryset

        return context


class SubjectDetail(LoginRequiredMixin, ListView):
    model = Argument
    context_object_name = 'arguments_list'
    template_name = 'subjects/detail.html'

    def get_queryset(self):
        subject = Subject.objects.get(name=self.kwargs['slug'])
        return subject.argument_set.all()

    def get_context_data(self, **kwargs):
        context = super(SubjectDetail, self).get_context_data(**kwargs)
        subject = Subject.objects.get(name=self.kwargs['slug'])
        context['subject'] = subject
        return context


class InsertArgument(LoginRequiredMixin, CreateView):
    model = Argument
    template_name = 'arguments/form.html'
    fields = ['name','description',]

    def form_valid(self, form):
        form.instance.subject = Subject.objects.get(name=self.kwargs['slug'])
        return super(InsertArgument, self).form_valid(form)

    def get_context_data(self, **kwargs):
        context = super(InsertArgument, self).get_context_data(**kwargs)
        subject = Subject.objects.get(name=self.kwargs['slug'])
        context['subject'] = subject
        return context

    def get_success_url(self):
        return reverse('archive:subject_detail', args=(self.object.subject.name,))


class UpdateArgument(LoginRequiredMixin, UpdateView):
    model = Argument
    context_object_name = 'argument'
    template_name = 'arguments/form.html'
    fields = ['name', 'description', ]

    def get_object(self, queryset=None):
        try:
            arg = Argument.objects.get(pk=self.kwargs['id_argument'])
        except Argument.DoesNotExist:
            arg = None
        return arg

    def get_context_data(self, **kwargs):
        context = super(UpdateArgument, self).get_context_data(**kwargs)
        subject = Subject.objects.get(name=self.kwargs['slug'])
        context['subject'] = subject
        return context

    def get_success_url(self):
        return reverse('archive:subject_detail', args=(self.object.subject.name,))


class RemoveArgument(LoginRequiredMixin, View):

    def get(self, request, slug, id_argument):
        argument = Argument.objects.get(pk=id_argument)
        subject = argument.subject

        argument.delete()
        return HttpResponseRedirect(reverse('archive:subject_detail', kwargs={
            'slug': subject.name
        }))


class DownloadPdfArgument(LoginRequiredMixin, View):
    def get(self, request, slug, id_argument):
        arg = Argument.objects.get(pk=id_argument)
        pdf = BytesIO()
        html = markdown(arg.description)
        filename = str(arg.subject).lower() + '-' + str(arg.name).lower()

        weasyprint.HTML(string=html).write_pdf(target=pdf,
                                               stylesheets=[weasyprint.CSS(
                                                   string='body {font-family: DejaVu Sans;font-size: 12px;color: #212121;line-height: 1.5;}h2, h3, h4, h5, h6 {margin-top: 2.5em;}')])

        response = HttpResponse(pdf.getvalue(), content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename=%s' % (str(filename) + '.pdf')
        response['Content-Length'] = pdf.tell()
        return response


class DownloadMdArgument(LoginRequiredMixin, View):
    def get(self, request, slug, id_argument):
        arg = Argument.objects.get(pk=id_argument)
        md = StringIO(arg.description)
        filename = str(arg.subject).lower() + '-' + str(arg.name).lower()

        response = HttpResponse(md.getvalue(), content_type='text/markdown')
        response['Content-Disposition'] = 'attachment; filename=%s' %(str(filename)+'.md')
        response['Content-Length'] = len(md.getvalue())
        return response


class DetailArgument(LoginRequiredMixin, DetailView):
    model = Argument
    context_object_name = 'argument'
    template_name = 'arguments/detail.html'

    def subsitute_formulas(self, string):
        final_string = string
        formula = re.search('(\$[^$]*\$)', final_string)

        while formula is not None:
            formula = str(formula.groups(0)[0])
            asciimath = str(formula.replace('$', ''))
            mathml = tostring(asciimathml.parse(asciimath)).decode('utf-8')
            final_string = final_string.replace(formula, mathml)
            formula = re.search('(\$[^$]*\$)', final_string)

        return final_string

    def get_object(self, queryset=None):
        arg = Argument.objects.get(pk=self.kwargs['id_argument'])
        arg.description = markdown(arg.description)
        arg.description = self.subsitute_formulas(arg.description)
        return arg