from http import HTTPStatus

from django.core.exceptions import ValidationError
from django.db import transaction
from django.forms import Form, CharField, IntegerField
from django.views.generic import FormView

from tvorba.models import Cislo, Problem, Uloha, Tema
from django.shortcuts import render, get_object_or_404

def problemView(request, pk):
	# Pokud problém neexistuje, hodíme obyčejnou 404
	# Taktéž v případě, že takový problém nemá být vidět
	problem = get_object_or_404(Problem, id=pk, stav__in=[Problem.STAV_ZADANY, Problem.STAV_VYRESENY])
	# Problém existuje, neumíme ho zobrazit, renderujeme nějakou haluz
	template = 'universal.html'
	ctx = {
		'raw_html': f'<h2>Obsah nelze zobrazit</h2><p>Požadovaný problém {problem.nazev} sice existuje, ale aktuálně jej nelze zobrazit. Omlouváme se za potíže</p>',
		}
	status_code = HTTPStatus.NOT_FOUND
	return render(request, template, context=ctx, status=status_code)


# FIXME Tohle možná patří do forms.py
# FIXME Chyby se ve formuláři zobrazují nějak divně
class HromadnePridaniForm(Form):
	""" Formulář pro hromadné přidání úložek a problémů """

	tema = CharField(label="Název tématu:")
	dil = IntegerField(label="Díl:", min_value=1)
	body = CharField(label="Počty bodů (0 pro problém) oddělené čárkami:")

	def clean_tema(self):
		""" Kontrola, že `tema` je název právě jednoho tématu """
		if Tema.objects.filter(
				nazev__exact=self.cleaned_data['tema'],
				nadproblem=None).count() != 1:
			raise ValidationError("Špatný nebo nepřesně zadaný název témátka")
		return self.cleaned_data['tema']

	def clean_body(self):
		""" Kontrola, že `body` je seznam čísel """
		try:
			list(map(int, self.cleaned_data["body"].split(",")))
		except ValueError:
			raise ValidationError("Špatný formát bodů")
		return self.cleaned_data['body']


class HromadnePridaniView(FormView):
	""" View pro hromadné přidání úložek a problémů """
	form_class = HromadnePridaniForm
	template_name = "generic_form.html"
	success_url = 'hromadne_pridani'

	def get_context_data(self, **kwargs):
		""" Přidání nadpisu stránky a url, kam se má poslat formulář. """
		context = super().get_context_data()
		context["nadpis"] = "Hromadné přidání úloh"
		context["form_url"] = "hromadne_pridani"
		return context

	def form_valid(self, form):
		""" Upravený Pavlův skript na hromadné přidání úložek a problémů. """
		cd = form.cleaned_data
		tema = cd["tema"]
		dil = cd["dil"]
		body = list(map(int, cd["body"].split(",")))

		t = Problem.objects.get(nazev__exact=tema, nadproblem=None)
		with transaction.atomic():
			pfx = f"{t.nazev}, díl {dil}, "

			for k, b in enumerate(body, 1):
				u = Uloha.objects.create(
					nadproblem=t,
					nazev=pfx + f"{'úloha' if b > 0 else 'problém'} {k}",
					autor=t.autor,
					garant=t.garant,
					max_body=b,
					cislo_zadani=Cislo.get(t.rocnik.rocnik, dil),
					kod=k,
					stav=Problem.STAV_ZADANY,
				)
				u.opravovatele.set(t.opravovatele.all())
		return super().form_valid(form)