from django.db import models

from soustredeni.models import Soustredeni
from personalni.models import Organizator, Osoba


class Seznam(models.Model):
	"""
		Spojuje :py:class:`Přednášky <prednasky.models.Prednaska>` a :py:class:`Znalosti <prednasky.models.Znalost>
		se :py:class:`Soustředěními <soustredeni.models.Soustredeni>`,
		kde by mohly zaznít, nebo zazní/zazněly.
	"""

	class Meta:
		db_table = "prednasky_seznam"
		verbose_name = "Seznam přednášek"
		verbose_name_plural = "Seznamy přednášek"
		ordering = ["soustredeni", "stav"]

	class Stav(models.IntegerChoices):
		""" Stav seznamu přednášek (NAVRH se používá k hlasování viz :py:func:`daný view <prednasky.views.newPrednaska>`). """
		NAVRH = 1, "Návrh" #: odpovídá před-soustřeďkové představě o tom, jaké přednášky dělat (dá se o nich třeba hlasovat ap.)
		BUDE = 2, "Bude" #: odpovídá definitivní představě o tom, co bude/bylo a dá se porovnávat s novými návrhy

	id = models.AutoField(primary_key=True)
	soustredeni = models.ForeignKey(Soustredeni, null=True, default=None, on_delete=models.PROTECT)
	stav = models.IntegerField("Stav", choices=Stav.choices, default=Stav.NAVRH) #: :py:class:`Stav <prednasky.models.Seznam.Stav>` Seznamu

	def __str__(self):
		return f"Seznam {'návrhů ' if self.stav == Seznam.Stav.NAVRH else ''}přednášek na {self.soustredeni}"


class Prednaska(models.Model):
	"""
		Reprezentuje přednášku, kterou si org může vypsat a účastník o ní hlasovat.
		(Viz :py:class:`Hlasování <prednasky.models.Hlasovani>`.)
	"""
	class Meta:
		db_table = "prednasky_prednaska"
		verbose_name = "Přednáška"
		verbose_name_plural = "Přednášky"
		ordering = ["org", "nazev"]

	class Obtiznost(models.IntegerChoices):
		LEHKA = 1, "Lehká"
		STREDNI = 2, "Střední"
		TEZKA = 3, "Těžká"

	id = models.AutoField(primary_key=True)
	nazev = models.CharField("Název", max_length=300)
	org = models.ForeignKey(Organizator, on_delete=models.PROTECT)
	popis = models.TextField("Popis pro orgy", null=True, blank=True, help_text="Neveřejný popis pro ostatní orgy")
	anotace = models.TextField("Anotace", null=True, blank=True, help_text="Veřejná anotace v hlasování")
	obtiznost = models.IntegerField("Obtížnost", choices=Obtiznost.choices) #: :py:class:`Obtížnost <prednasky.models.Prednaska.Obtiznost>` Přednášky
	obor = models.CharField("Obor", max_length=5, help_text="Podmnožina MFIOB")
	klicova = models.CharField("Klíčová slova", max_length=200, null=True, blank=True)
	seznamy = models.ManyToManyField(Seznam)

	def __str__(self):
		return f"{self.nazev} ({self.org})"


class Hlasovani(models.Model):
	"""
		Reprezentuje hlasování jednoho účastníka
		o jedné :py:class:`Přednášce <prednasky.models.Prednaska>`
		v jednom :py:class:`Seznamu <prednasky.models.Seznam>` (účastníkův pohled se totiž mezi sousy změnit)
	"""
	class Meta:
		db_table = "prednasky_hlasovani"
		verbose_name = "Hlasování"
		verbose_name_plural = "Hlasování"
		ordering = ["ucastnik", "prednaska"]

	class Body(models.IntegerChoices):
		""" Ohodnocení přednášky v daném Hlasování (větší číslo = víc chci) """
		NECHCI = -1, "rozhodně nechci"
		JEDNO = 0, "je mi to jedno"
		CHCI = 1, "rozhodně chci"

	id = models.AutoField(primary_key=True)
	prednaska = models.ForeignKey(Prednaska, on_delete=models.CASCADE)
	#: Příslušné hlasování: :py:class:`Body <prednasky.models.Hlasovani.Body>`
	body = models.IntegerField("Body", default=Body.JEDNO, choices=Body.choices)

	#: Účastník, který hlasoval. Pouze string:
	#: *(přechod z jména na objekt Osoby nějak kape na tom,
	#: že všechna předchozí hlasování zde mají náhodný string…)
	#: TODO Změnit to na Osobu*
	ucastnik = models.CharField("Účastník", max_length=100)
	ucastnik_osoba = models.ForeignKey(Osoba, on_delete=models.CASCADE, blank=False, null=True)
	seznam = models.ForeignKey(Seznam, null=True, on_delete=models.SET_NULL)

	def __str__(self):
		return f"{self.ucastnik} dal {self.body} bodů {self.prednaska} v seznamu {self.seznam}"


class Znalost(models.Model):
	"""
		Reprezentuje znalost, na kterou se můžeme účastníka ptát (nechat je hlasovat).
		(Viz :py:class:`HlasováníOZnalostech <prednasky.models.HlasovaniOZnalostech>`.)

		(V podstatě :py:class:`Přednáška <prednasky.models.Prednaska>, jen neobsahuje
		tolik detailů a v hlasování má jiné odpovědi.)
	"""
	class Meta:
		db_table = "prednasky_znalost"
		verbose_name = "Znalost k přednáškám"
		verbose_name_plural = "Znalosti k přednáškám"

	nazev = models.CharField("Nadpis", max_length=200, blank=False, null=False, help_text="Např. Neuronové sítě")
	text = models.TextField("Detailní popis", blank=True, null=True, help_text="Např. Perceptron, vrstevnatá síť, forward a backward propagation")
	seznamy = models.ManyToManyField(Seznam)

	def __str__(self):
		return self.nazev


class HlasovaniOZnalostech(models.Model):
	"""
		Reprezentuje hlasování jednoho účastníka
		o jedné :py:class:`Znalosti <prednasky.models.Znalost>`
		v jednom :py:class:`Seznamu <prednasky.models.Seznam>` (účastníkův pohled se totiž mezi sousy změnit)

		(V podstatě totéž, co :py:class:`Hlasování <prednasky.models.Hlasovani>`, jen má jiné komentáře
		u odpovědí a místo přednášky odkazuje na znalost.)
	"""
	class Odpoved(models.IntegerChoices):
		""" Na kolik danou znalost účastník ovládá v daném Hlasování (větší číslo = víc zná) """
		UMIM = 1, "Tohle celkem umím"
		CIRCA = 0, "Už jsem o tom slyšel, ale neřekl bych, že to úplně umím"
		NEUMIM = -1, "Tohle vůbec neznám"

	odpoved = models.IntegerField(u"odpověď", choices=Odpoved.choices, blank=False, null=False) #: :py:class:`Odpověď <prednasky.models.Prednaska.Odpoved>` na HlasováníOZnalostech
	znalost = models.ForeignKey(Znalost, on_delete=models.CASCADE, blank=False, null=False)
	ucastnik = models.ForeignKey(Osoba, on_delete=models.CASCADE, blank=False, null=False)
	seznam = models.ForeignKey(Seznam, on_delete=models.SET_NULL, blank=True, null=True)

	def __str__(self):
		return f"{self.ucastnik} dal {self.znalost} bodů {self.znalost} v seznamu {self.seznam}"