from django.contrib import admin
from django.forms import ModelForm
from django.core.exceptions import ValidationError
from django.urls import reverse

from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin, PolymorphicChildModelFilter
from django.utils.safestring import mark_safe

# Todo: reversion

import soustredeni.models

from tvorba.models import Rocnik, ZmrazenaVysledkovka, Deadline, Uloha, Problem, Tema, Clanek, Cislo # tvorba

admin.site.register(Rocnik)
admin.site.register(ZmrazenaVysledkovka)

@admin.register(Deadline)
class DeadlineAdmin(admin.ModelAdmin):
	actions = ['pregeneruj_vysledkovku']

	# Nikomu nezobrazovat, ale superuživatelům se může hodit :-)
	@admin.action(permissions=['bazmek'], description= 'Přegeneruj výsledkovky vybraných deadlinů')
	def pregeneruj_vysledkovku(self, req, qs):
		for deadline in qs:
			deadline.vygeneruj_vysledkovku()

	def has_bazmek_permission(self, request):
		# Boilerplate: potřebujeme nějakou permission, protože nějaká haluz v Djangu…
		return request.user.is_superuser


class DeadlineAdminInline(admin.TabularInline):
	model = Deadline
	extra = 0


class CisloForm(ModelForm):
	class Meta:
		model = Cislo
		fields = '__all__'

	def clean(self):
		if self.cleaned_data.get('verejne_db') == False:
			return self.cleaned_data
		# cn = CisloNode.objects.get(cislo=self.instance)
		# errors = []
		# for ch in tl.all_children(cn):
		# 	if isinstance(ch, TemaVCisleNode):
		# 		if ch.tema.stav not in \
		# 			(Problem.STAV_ZADANY, Problem.STAV_VYRESENY):
		# 			errors.append(ValidationError('Téma %(tema)s není zadané ani vyřešené', params={'tema':ch.tema}))
		#
		# 	if isinstance(ch, UlohaZadaniNode) or isinstance(ch, UlohaVzorakNode):
		# 		if ch.uloha.stav not in \
		# 			(Problem.STAV_ZADANY, Problem.STAV_VYRESENY):
		# 			errors.append(ValidationError('Úloha %(uloha)s není zadaná ani vyřešená', params={'uloha':ch.uloha}))
		# 	if isinstance(ch, ReseniNode):
		# 		for problem in ch.reseni.problem_set:
		# 			if problem not in \
		# 				(Problem.STAV_ZADANY, Problem.STAV_VYRESENY):
		# 				errors.append(ValidationError('Problém %s není zadaný ani vyřešený', code=problem))

		errors = []
		for ch in Uloha.objects.filter(cislo_zadani=self.instance):
			if ch.stav not in (Problem.STAV_ZADANY, Problem.STAV_VYRESENY):
				errors.append(
					ValidationError('Úloha %(uloha)s není zadaná ani vyřešená', params={'uloha': ch}))
		if errors:
			errors.append(ValidationError(mark_safe(
				'<b>Pokud chceš učinit všechny problémy, co nejsou zadané ani vyřešené, zadanými a číslo zveřejnit, můžeš to udělat pomocí akce v <a href="' +  reverse('admin:tvorba_cislo_changelist') + '">seznamu čísel</a></b>')))
		if self.cleaned_data.get('datum_vydani') == None:
			self.add_error('datum_vydani','Číslo určené ke zveřejnění nemá nastavené datum vydání')

		if errors:
			raise ValidationError(errors)

		return self.cleaned_data


@admin.register(Cislo)
class CisloAdmin(admin.ModelAdmin):
	form = CisloForm
	actions = ['force_publish', 'pregeneruj_vysledkovky']
	inlines = (DeadlineAdminInline,)

	def force_publish(self,request,queryset):
		for cislo in queryset:
			# cn = CisloNode.objects.get(cislo=cislo)
			# for ch in tl.all_children(cn):
			# 	if isinstance(ch, TemaVCisleNode):
			# 		if ch.tema.stav not in (Problem.STAV_ZADANY, Problem.STAV_VYRESENY):
			# 			ch.tema.stav = Problem.STAV_ZADANY
			# 			ch.tema.save()
			#
			# 	if isinstance(ch, UlohaZadaniNode) or isinstance(ch, UlohaVzorakNode):
			# 		if ch.uloha.stav not in (Problem.STAV_ZADANY, Problem.STAV_VYRESENY):
			# 			ch.uloha.stav = Problem.STAV_ZADANY
			# 			ch.uloha.save()
			# 	if isinstance(ch, ReseniNode):
			# 		for problem in ch.reseni.problem_set:
			# 			if problem not in (Problem.STAV_ZADANY, Problem.STAV_VYRESENY):
			# 				problem.stav = Problem.STAV_ZADANY
			# 				problem.save()

			for ch in Uloha.objects.filter(cislo_zadani=cislo):
				if ch.stav not in (Problem.STAV_ZADANY, Problem.STAV_VYRESENY):
					ch.stav = Problem.STAV_ZADANY
					ch.save()

					hp = ch.hlavni_problem
					if hp.stav not in (Problem.STAV_ZADANY, Problem.STAV_VYRESENY):
						hp.stav = Problem.STAV_ZADANY
						hp.save()

			# TODO Řešení, vzoráky?
			# TODO Konfera/Článek?

			cislo.verejne_db = True
			cislo.save()

	force_publish.short_description = 'Zveřejnit vybraná čísla a všechny návrhy úloh v nich učinit zadanými'

	# Jen pro superuživatele
	@admin.action(permissions=['bazmek'], description='Přegenerovat výsledkovky všech deadlinů vybraných čísel')
	def pregeneruj_vysledkovky(self, req, qs):
		for cislo in qs:
			for deadline in cislo.deadline_v_cisle.all():
				deadline.vygeneruj_vysledkovku()

	def has_bazmek_permission(self, request):
		# Boilerplate: potřebujeme nějakou permission, protože nějaká haluz v Djangu…
		return request.user.is_superuser


@admin.register(Problem)
class ProblemAdmin(PolymorphicParentModelAdmin):
	base_model = Problem
	child_models = [
		Tema,
		Clanek,
		Uloha,
		soustredeni.models.Konfera,
	]
	# Pokud chceme orezavat na aktualni rocnik, musime do modelu pridat odkaz na rocnik. Zatim bere vse.
	search_fields = ['nazev']


# V ProblemAdmin to nejde, protoze se to nepropise do deti
class ProblemAdminMixin(object):
	show_in_index = True
	autocomplete_fields = ['nadproblem','autor','garant']
	filter_horizontal = ['opravovatele']


@admin.register(Tema)
class TemaAdmin(ProblemAdminMixin,PolymorphicChildModelAdmin):
	base_model = Tema


@admin.register(Clanek)
class ClanekAdmin(ProblemAdminMixin,PolymorphicChildModelAdmin):
	base_model = Clanek


@admin.register(Uloha)
class UlohaAdmin(ProblemAdminMixin,PolymorphicChildModelAdmin):
	base_model = Uloha


@admin.register(soustredeni.models.Konfera)
class KonferaAdmin(ProblemAdminMixin,PolymorphicChildModelAdmin):
	base_model = soustredeni.models.Konfera

# admin.site.register(m.Pohadka)