from django.shortcuts import get_object_or_404, render
from django.views import generic
from django.conf import settings
from django.http import HttpResponseForbidden
from django.core.mail import EmailMessage
from django.db.models import Count,Q

from .models import Oprava,Komentar,KorekturovanePDF, Organizator
from .forms import OpravaForm

import subprocess
import shutil
import os

class KorekturyListView(generic.ListView):
	model = KorekturovanePDF
	# Nefunguje, filtry se vubec nepouziji
	queryset = KorekturovanePDF.objects.annotate(
		k_oprave_cnt=Count('oprava',distinct=True,filter=Q(oprava__status='k_oprave')),
		opraveno_cnt=Count('oprava',distinct=True,filter=Q(oprava__status='opraveno')),
		neni_chyba_cnt=Count('oprava',distinct=True,filter=Q(oprava__status='neni_chyba')),
		k_zaneseni_cnt=Count('oprava',distinct=True,filter=Q(oprava__status='k_zaneseni')),
		)
	template_name = 'korektury/seznam.html'

class KorekturyAktualniListView(KorekturyListView):
	def get_queryset(self, *args, **kwargs):
		queryset=super().get_queryset()
		queryset=queryset.exclude(status="zastarale")
		return queryset

	def get_context_data(self, **kwargs):
		context = super().get_context_data(**kwargs)
		context['selected'] = 'aktualni'
		return context



class KorekturyZastaraleListView(KorekturyListView):
	def get_queryset(self, *args, **kwargs):
		queryset=super().get_queryset()
		queryset=queryset.filter(status="zastarale").order_by("-cas")
		return queryset

	def get_context_data(self, **kwargs):
		context = super().get_context_data(**kwargs)
		context['selected'] = 'zastarale'
		return context

class KorekturySeskupeneListView(KorekturyAktualniListView):
	template_name = 'korektury/seskupeny_seznam.html'

	# {% regroup %} potřebuje dostat správně setříděné názvy, aby nedělal duplikáty
	def get_queryset(self, *args, **kwargs):
		qs = super().get_queryset(**kwargs)
		return reversed(sorted(qs, key=lambda it: it.cislo_a_tema))

### Korektury
class KorekturyView(generic.TemplateView):
	model = Oprava
	template_name = 'korektury/opraf.html'
	form_class = OpravaForm

	def post(self, request, *args, **kwargs):
		form = self.form_class(request.POST)
		q = request.POST
		scroll = q.get('scroll')

		# prirazeni autora podle prihlaseni
		autor_user = request.user
		# pokud existuje ucet (user), ale neni to organizator = 403
		autor = Organizator.objects.filter(osoba__user=autor_user).first()
		if not autor:
			return HttpResponseForbidden()

		if not scroll:
			scroll = 0

		action = q.get('action')
		if (action == ''):  # Přidej
			x = int(q.get('x'))
			y = int(q.get('y'))
			text = q.get('txt')
			strana = int(q.get('img-id')[4:])
			pdf = KorekturovanePDF.objects.get(id=q.get('pdf'))

			op = Oprava(x=x,y=y, autor=autor, text=text, strana=strana,pdf = pdf)
			op.save()
			self.send_email_notification_komentar(op,autor)
		elif (action == 'del'):
			id = int(q.get('id'))
			op = Oprava.objects.get(id=id)
			op.delete()
		elif (action == 'update'):
			id = int(q.get('id'))
			op = Oprava.objects.get(id=id)
			text = q.get('txt')
			op.autor = autor
			op.text = text
			op.save()
		elif (action == 'undone'):
			id = int(q.get('id'))
			op = Oprava.objects.get(id=id)
			op.status = op.STATUS_K_OPRAVE
			op.save()
		elif (action == 'done'):
			id = int(q.get('id'))
			op = Oprava.objects.get(id=id)
			op.status = op.STATUS_OPRAVENO
			op.save()
		elif (action == 'ready'):
			id = int(q.get('id'))
			op = Oprava.objects.get(id=id)
			op.status = op.STATUS_K_ZANESENI
			op.save()
		elif (action == 'wontfix'):
			id = int(q.get('id'))
			op = Oprava.objects.get(id=id)
			op.status = op.STATUS_NENI_CHYBA
			op.save()
		elif (action == 'comment'):
			id = int(q.get('id'))
			op = Oprava.objects.get(id=id)
			text = q.get('txt')
			kom = Komentar(oprava=op,autor=autor,text=text)
			kom.save()
			self.send_email_notification_komentar(op,autor)
		elif (action == 'update-comment'):
			id = int(q.get('id'))
			kom = Komentar.objects.get(id=id)
			text = q.get('txt')
			kom.text = text
			kom.autor = autor
			kom.save()
		elif (action == 'del-comment'):
			id = int(q.get('id'))
			kom = Komentar.objects.get(id=id)
			kom.delete()
		elif (action == 'set-state'):
			pdf = KorekturovanePDF.objects.get(id=q.get('pdf'))
			if (q.get('state') == 'adding'):
				pdf.status = pdf.STATUS_PRIDAVANI
			elif (q.get('state') == 'comitting'):
				pdf.status = pdf.STATUS_ZANASENI
			elif (q.get('state') == 'deprecated'):
				pdf.status = pdf.STATUS_ZASTARALE
			pdf.save()
		context = self.get_context_data()
		context['scroll'] = scroll
		context['autor'] = autor
		return render(request, 'korektury/opraf.html',context)

	def send_email_notification_komentar(self, oprava, autor):
		''' Rozesle e-mail pri pridani komentare / opravy,
			ktery obsahuje text vlakna opravy.
		'''

		# parametry e-mailu
		#odkaz = "https://mam.mff.cuni.cz/korektury/{}/".format(oprava.pdf.pk)
		from django.urls import reverse
		odkaz = self.request.build_absolute_uri(reverse('korektury', kwargs={'pdf': oprava.pdf.pk}))
		odkaz = f"{odkaz}#op{oprava.id}-pointer"
		from_email = 'korekturovatko@mam.mff.cuni.cz'
		subject = 'Nová korektura od {} v {}'.format(autor, oprava.pdf.nazev)
		texty = [(oprava.autor.osoba.plne_jmeno(),oprava.text)]
		for kom in Komentar.objects.filter(oprava=oprava):
			texty.append((kom.autor.osoba.plne_jmeno(),kom.text))
		optext = "\n\n\n".join([": ".join(t) for t in texty])
		text = u"Text komentáře:\n\n{}\n\n=== Konec textu komentáře ===\n\
				\nodkaz do korekturovátka: {}\n\
				\nVaše korekturovátko\n".format(optext, odkaz)

		# Prijemci e-mailu
		emails = set()
		# e-mail autora korektury
		email = oprava.autor.osoba.email
		if email:
			emails.add(email)

		# nalezeni e-mailu na autory komentaru
		for komentar in oprava.komentar_set.all():
			email_komentujiciho = komentar.autor.osoba.email
			if email_komentujiciho:
				emails.add(email_komentujiciho)

		# zodpovedni orgove
		for org in oprava.pdf.orgove.all():
			email_zobpovedny = org.osoba.email
			if email_zobpovedny:
				emails.add(email_zobpovedny)

		# odstran e-mail autora opravy
		email = autor.osoba.email
		if email:
			emails.discard(email)

		EmailMessage(
			subject=subject,
			body=text,
			from_email=from_email,
			to=list(emails),
		).send()

	def get_context_data(self, **kwargs):
		context = super().get_context_data(**kwargs)
		pdf = get_object_or_404(KorekturovanePDF, id=self.kwargs['pdf'])
		context['pdf'] = pdf
		context['img_prefix'] = pdf.get_prefix()
		context['img_path'] = settings.KOREKTURY_IMG_DIR
		context['img_indexes'] = range(pdf.stran) 
		context['form_oprava'] = OpravaForm()
		opravy = Oprava.objects.filter(pdf=self.kwargs['pdf'])
		zasluhy = {}
		for o in opravy:
			if o.autor in zasluhy:
				zasluhy[o.autor]+=1
			else:
				zasluhy[o.autor]=1
			o.komentare = o.komentar_set.all()
			for k in o.komentare:
				if k.autor in zasluhy:
					zasluhy[k.autor] += 1
				else:
					zasluhy[k.autor] = 1
		zasluhy = [
			{'autor': jmeno, 'pocet': pocet}
			for (jmeno, pocet) in zasluhy.items()
		]
		zasluhy.sort(key=lambda z: z['pocet'], reverse=True)

		strany = set(o.strana for o in opravy)
		opravy_na_stranu = [{'strana': s, 'op_id': opravy.filter(strana=s)} for s in strany]
		context['opravy_strany'] = opravy_na_stranu

		context['k_oprave_cnt'] = opravy.filter(status='k_oprave').count() 
		context['opraveno_cnt'] = opravy.filter(status='opraveno').count() 
		context['neni_chyba_cnt'] = opravy.filter(status='neni_chyba').count() 
		context['k_zaneseni_cnt'] = opravy.filter(status='k_zaneseni').count() 
		
		context['opravy'] = opravy
		context['zasluhy'] = zasluhy
		return context

	def form_valid(self,form):
		return super().form_valid(form)