from django.core.exceptions import ObjectDoesNotExist

import personalni.models

import tvorba.models as m


def resi_v_rocniku(rocnik, cislo=None):
	""" Vrátí seznam řešitelů, co vyřešili nějaký problém v daném ročníku, do daného čísla.
	Parametry:
		rocnik (typu Rocnik)	ročník, ze kterého chci řešitele, co něco odevzdali
		cislo (typu Cislo)	číslo, do kterého včetně se počítá, že v daném
					ročníku řešitel něco poslal.
					Pokud není zadané, počítají se všechna řešení z daného ročníku.
	Výstup:
		QuerySet objektů typu Resitel """

	if cislo is None:
		# filtrujeme pouze podle ročníku
		return personalni.models.Resitel.objects.filter(
			rok_maturity__gte=rocnik.druhy_rok(),
			reseni__hodnoceni__deadline_body__cislo__rocnik=rocnik
		).distinct()
	else:  # filtrujeme podle ročníku i čísla
		return personalni.models.Resitel.objects.filter(
			rok_maturity__gte=rocnik.druhy_rok(),
			reseni__hodnoceni__deadline_body__cislo__rocnik=rocnik,
			reseni__hodnoceni__deadline_body__cislo__poradi__lte=cislo.poradi
		).distinct()


def aktivniResitele(cislo, pouze_letosni=False):
	""" Vrací QuerySet aktivních řešitelů, což jsou ti, co ještě neodmaturovali
	a letos něco poslali (anebo loni něco poslali, pokud jde o první tři čísla).
	Parametry:
		cislo (typu Cislo)	číslo, o které se jedná
		pouze_letosni		jen řešitelé, kteří tento rok něco poslali

	"""
	letos = cislo.rocnik

	# detekujeme, zda jde o první tři čísla či nikoli (tj. zda spamovat řešitele z minulého roku)
	zacatek_rocniku = True
	try:
		if int(cislo.poradi) > 3:
			zacatek_rocniku = False
	except ValueError:
		# if cislo.poradi != '7-8':
		# 	raise ValueError(f'{cislo} je neplatné číslo čísla (není int a není 7-8)')
		zacatek_rocniku = False

	# nehledě na číslo chceme jen řešitele, kteří letos něco odevzdali
	if pouze_letosni:
		zacatek_rocniku = False

	try:
		loni = m.Rocnik.objects.get(rocnik=letos.rocnik - 1)
	except ObjectDoesNotExist:
		# Pro první ročník neexistuje ročník předchozí
		zacatek_rocniku = False

	if not zacatek_rocniku:
		return resi_v_rocniku(letos, cislo).filter(rok_maturity__gte=letos.druhy_rok())
	else:
		# spojíme querysety s řešiteli loni a letos do daného čísla
		return (resi_v_rocniku(loni) | resi_v_rocniku(letos, cislo))\
			.distinct().filter(rok_maturity__gte=letos.druhy_rok())


# Pozor: zarovnáno velmi netradičně pro přehlednost
roman_numerals = zip((1000, 900, 500, 400,  100, 90,   50,  40,   10,  9,    5,   4,    1),  # noqa
					 ('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'))  # noqa


def roman(num):
	res = ""
	for i, n in roman_numerals:
		res += n * (num // i)
		num %= i
	return res


def from_roman(rom):
	if not rom:
		return 0
	for i, n in roman_numerals:
		if rom.upper().startswith(n):
			return i + from_roman(rom[len(n):])
	raise Exception('Invalid roman numeral: "%s"', rom)