"""
Stránky, které se mi nepovedlo lépe zařadit.

Oproti `./pomocne.py` se tyto views používají přímo ve various
a naopak importují spoustu věcí odjinud
"""
import datetime

from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404, render
from django.utils import timezone
from django.views import generic

import novinky.views
import treenode.treelib as t
import tvorba.views

from treenode.models import CisloNode
from personalni.models import Resitel, Osoba
from tvorba.models import Clanek, Deadline

from ..models import Nastaveni


class TitulniStranaView(generic.ListView):
	template_name = 'various/titulnistrana/titulnistrana.html'

	def get_queryset(self):
		return novinky.views.spravne_novinky(self.request)[:3]

	def get_context_data(self, **kwargs):
		context = super(TitulniStranaView, self).get_context_data(**kwargs)
		nastaveni = get_object_or_404(Nastaveni)

		deadline = Deadline.objects.filter(
			deadline__gte=timezone.now()).order_by("deadline").first()
		context['nejblizsi_deadline'] = deadline

		# Aktuální témata
		nazvy_a_odkazy_na_aktualni_temata = []
		akt_temata = tvorba.views.aktualni_temata(nastaveni.aktualni_rocnik)

		for tema in akt_temata:
			# FIXME: netuším, jestli funguje tema.verejne_url(), nemáme testdata na témátka - je to asi url vzhledem k ročníku
			nazvy_a_odkazy_na_aktualni_temata.append({
				'nazev': tema.nazev,
				'url': tema.verejne_url()
			})

		context['aktualni_temata'] = nazvy_a_odkazy_na_aktualni_temata

		return context


class JakResitView(generic.ListView):
	template_name = 'various/jakresit/jak-resit.html'

	def get_queryset(self):
		return None


### Status
def histogram(seznam):
	d = {}
	for i in seznam:
		if i not in d:
			d[i] = 0
		d[i] += 1
	return d


def seznam_problemu():
	"""Funkce pro hledání nekonzistencí v databázi a dalších nežádoucích stavů webu/databáze.

	Nijak nesouvisí s Problémy zadanými řešitelům."""
	# FIXME: přejmenovat funkci?
	problemy = []

	# Pomocna fce k formatovani problemovych hlasek
	def prb(cls, msg, objs=None):
		s = '<b>%s:</b> %s' % (cls.__name__, msg)
		if objs:
			s += ' ['
			for o in objs:
				try:
					url = o.admin_url()
				except:
					url = None
				if url:
					s += '<a href="%s">%s</a>, ' % (url, o.pk,)
				else:
					s += '%s, ' % (o.pk,)
			s = s[:-2] + ']'
		problemy.append(s)

	# Duplicita jmen
	jmena = {}
	for r in Resitel.objects.all():
		j = r.osoba.plne_jmeno()
		if j not in jmena:
			jmena[j] = []
		jmena[j].append(r)
	for j in jmena:
		if len(jmena[j]) > 1:
			prb(Resitel, 'Duplicitní jméno "%s"' % (j,), jmena[j])

	# Data maturity a narození
	for r in Resitel.objects.all():
		if not r.rok_maturity:
			prb(Resitel, 'Neznámý rok maturity', [r])
		if r.rok_maturity and (r.rok_maturity < 1990 or r.rok_maturity > datetime.date.today().year + 10):
			prb(Resitel, 'Podezřelé datum maturity', [r])
		if r.osoba.datum_narozeni and (
				r.osoba.datum_narozeni.year < 1970 or r.osoba.datum_narozeni.year > datetime.date.today().year - 12):
			prb(Resitel, 'Podezřelé datum narození', [r])
	#		if not r.email:
	#			prb(Resitel, u'Neznámý email', [r])

	## Kontroly konzistence databáze a TreeNodů

	# Články
	for clanek in Clanek.objects.all():
		# získáme řešení svázané se článkem a z něj node ve stromě
		reseni = clanek.reseni_set
		if (reseni.count() != 1):
			raise ValueError("Článek k sobě má nejedno řešení!")
		r = reseni.first()
		clanek_node = r.text_cely	# vazba na ReseniNode z Reseni
		# content type je věc pomáhající rozeznávat různé typy objektů v django-polymorphic
		# protože isinstance vrátí vždy jen TreeNode
		# https://django-polymorphic.readthedocs.io/en/stable/migrating.html
		cislonode_ct = ContentType.objects.get_for_model(CisloNode)
		node = clanek_node
		while node is not None:
			node_ct = node.polymorphic_ctype
			if node_ct == cislonode_ct:	# dostali jsme se k CisloNode
				# zkontrolujeme, že stromové číslo odpovídá atributu
				# .cislonode je opačná vazba k treenode_ptr, abychom z TreeNode dostali
				# CisloNode
				if clanek.cislo != node.cislonode.cislo:
					prb(Clanek, "Číslo otištění uložené u článku nesedí s "
								  "číslem otištění podle struktury treenodů.", [clanek])
				break
			node = t.get_parent(node)

	return problemy

def StavDatabazeView(request):
	# nastaveni = Nastaveni.objects.get()
	problemy = seznam_problemu()
	muzi = Resitel.objects.filter(osoba__osloveni=Osoba.OSLOVENI_MUZSKE)
	zeny = Resitel.objects.filter(osoba__osloveni=Osoba.OSLOVENI_ZENSKE)
	return render(request, 'various/stav_databaze.html', {
		# 'nastaveni': nastaveni,
		'problemy': problemy,

		'resitele': Resitel.objects.all(),
		'muzi': muzi,
		'zeny': zeny,
		'jmena_muzu': histogram([r.osoba.jmeno for r in muzi]),
		'jmena_zen': histogram([r.osoba.jmeno for r in zeny]),
	})