require('Modulo:No globals')

local wikidata = require('Modulo:Wikidata')
local navbox = require('Modulo:Navbox')
local mNumeroRomano = require('Modulo:Numero romano')
local getArgs = require('Modulo:Arguments').getArgs
local errorCategory = '[[Categoria:Errori di compilazione del template Stagioni televisive]]'
local p = {}

local function ordinalefemminile(num)
	return mw.getCurrentFrame():expandTemplate {
		title = 'Ordinale femminile',
		args = { num }
	}
end

function p.main(frame)
	local args = getArgs(frame)
	return p._main(args)
end

function p._main(args)
	local template, sfondo, categoria, target, stagioneoedizione, preposizione, links, errore
	local id, localID, localID2, tipo, titolo, etichetta, nome, sitelink, stagioni
	local pageTitle = args[1] or args.titolo

-- Rileva l'identificativo della scheda wikidata collegata alla fiction o al programma TV,
-- se nessun titolo è specificato prova a recuperlo dalla voce della stagione/edizione, se questa ha una sua scheda su wikidata	
	if not args[1] or args.titolo then
		if string.find(mw.title.getCurrentTitle().text, '^Episodi d[ei]') then
			localID = wikidata._getProperty({ 'P361', n = 1, from = mw.wikibase.getEntityIdForCurrentPage(), formatting = 'raw' })
			localID2 = wikidata._getProperty({ 'P179', n = 1, from = mw.wikibase.getEntityIdForCurrentPage(), formatting = 'raw' })
		end
		if localID ~= nil then
			id = localID
		elseif localID2 ~= nil then
			id = localID2	
		end
	else
		id = mw.wikibase.getEntityIdForTitle( pageTitle )
	end

-- Identifica il tipo di programma (serie televisiva, serie animata o programma TV generico)
-- ed estrae gli altri dati fondamentali da Wikidata (etichetta in italiano, numero stagioni, sitelink)
-- se uno di essi non è presente è generato un messaggio di errore
	if wikidata._instanceOf({ 'Q581714', from = id }) then
		tipo = 'animata'
	elseif wikidata._instanceOf({ 'Q5398426', from = id }) then
		tipo = 'serie TV'
	else
		tipo = 'programma'
	end
	
	if id then
		titolo = wikidata._getLink({ id })
		etichetta = wikidata._getLabel({ id, 'it'})
		sitelink = mw.wikibase.sitelink( id )
		stagioni = wikidata._getProperty({ 'P2437', n = 1, from = id, formatting = 'raw' })
	else
		errore = 'Template non compilato correttamente, controlla le [[Template:Stagioni televisive|istruzioni]]'
	end

-- Questa parte del codice genere i collegamenti alle singole edizioni/stagioni e la relativa categoria
	if not etichetta or not sitelink or not stagioni then
		errore = 'Template non compilato correttamente, controlla le [[Template:Stagioni televisive|istruzioni]]'
	else
	
		local tbl = {}
		local lang = mw.language.getContentLanguage()
		local sep = '&nbsp;<b>&middot;</b>&#32;'

---- per rendere l'uso del template più leggero prova a estrarre il nome del programma e la preposizione usata nei link direttamente
---- dalle voci in cui è usato, altrimenti verifica l'esistenza della voce della prima stagione con la sintassi standard
		if tipo == 'programma' then
			if args[2] ~= 'elenco' and string.find(mw.title.getCurrentTitle().text, '^.+%(%a+edizione%)$') then
				nome = string.match(mw.title.getCurrentTitle().text, '^(.+) %(%a+edizione%)$')
				preposizione = mw.title.new(string.format('Categoria:Edizioni de %s', nome)).exists and 'de' or 'di'
			elseif mw.title.new(string.format('%s (prima edizione)', etichetta)).exists then
				nome = etichetta
				preposizione = mw.title.new(string.format('Categoria:Edizioni de %s', etichetta)).exists and 'de' or 'di'
			else
				nome = sitelink
				preposizione = mw.title.new(string.format('Categoria:Edizioni de %s', sitelink)).exists and 'de' or 'di'
			end
		elseif tipo == 'serie TV' or tipo == 'animata' then
			if args[2] ~= 'elenco' and string.find(mw.title.getCurrentTitle().text, '^Episodi d[ei] ') then
				if string.find(mw.title.getCurrentTitle().text, '^Episodi d[ei].+stagione%)$') then
					nome = string.match(mw.title.getCurrentTitle().text, '^Episodi d[ei] (.+) %(%a+ stagione%)$')
					preposizione = string.match(mw.title.getCurrentTitle().text, '^Episodi (d[ei])')
				elseif string.find(mw.title.getCurrentTitle().text, '^Episodi d[ei].+$') then
					nome = string.match(mw.title.getCurrentTitle().text, '^Episodi d[ei] (.+)$')
					preposizione = string.match(mw.title.getCurrentTitle().text, '^Episodi (d[ei])')
				end
			elseif mw.title.new(string.format('Episodi di %s (prima stagione)', etichetta)).exists then
				nome = etichetta
				preposizione = 'di'
			elseif mw.title.new(string.format('Episodi de %s (prima stagione)', etichetta)).exists then
				nome = etichetta
				preposizione = 'de'
			else
				nome = sitelink
				preposizione = mw.title.new(string.format('Episodi de %s (prima stagione)', sitelink)).exists and 'de' or 'di'
			end
		end

---- qui vengono generati i link alle stagioni/edizioni e la categoria appropriata
		for i = 1, stagioni do
			
			local ordinaleF = ordinalefemminile(i)
		
			if tipo == 'programma' then 
				target = string.format('%s (%s edizione)', nome, ordinaleF)
			else
				target = string.format('Episodi %s %s (%s stagione)', preposizione, nome, ordinaleF)
			end
		
			if tipo == 'programma' then
				stagioneoedizione = 'edizione'
			else
				stagioneoedizione = 'stagione'
			end
			
			local label = args.formato == 'numeri romani' and mNumeroRomano.main({ i }) or (args.formato == 'forma breve' and string.format('%dª', i) or string.format('%s %s', lang:ucfirst(ordinaleF), stagioneoedizione))
			
			table.insert(tbl, string.format('[[%s|%s]]', target, label))
		
			if (target == mw.title.getCurrentTitle().text and mw.title.getCurrentTitle().namespace == 0) or (mw.title.getCurrentTitle().text == string.format('Episodi %s %s', preposizione, nome) and mw.title.getCurrentTitle().namespace == 0) or args.debugcat then
				if stagioni == '1' or stagioni == '1±0' then
					if tipo == 'programma' then
						categoria = string.format('[[Categoria:Edizioni di programmi televisivi|%s]]', nome)
					elseif tipo == 'animata' then
						categoria = string.format('[[Categoria:Liste di episodi di serie animate|%s]]', nome)
					else
						categoria = string.format('[[Categoria:Liste di episodi di serie televisive|%s]]', nome)
					end
				elseif tipo == 'programma' then
					categoria = string.format('[[Categoria:Edizioni %s %s|%02d]]', preposizione, nome, i)
				else
					categoria = string.format('[[Categoria:Stagioni %s %s|%02d]]', preposizione, nome, i)
				end 
			end
		end
	
		local catsp
		if mw.title.getCurrentTitle().text == string.format('Episodi speciali %s %s', preposizione, nome) then
			catsp = string.format('[[Categoria:Stagioni %s %s|Episodi speciali]]', preposizione, nome)
		end
		
		local speciali = (args[2] == 's' or args[3] == 's' or args[4] == 's') and sep..string.format('[[Episodi speciali %s %s|Episodi speciali]]', preposizione, nome)..(catsp or '')
		
		links = mw.text.listToText(tbl, sep, sep) .. (speciali or '') .. (categoria or '')
	end

-- Infine è generato il navbox con i dati su estratti e formattati

---- con sfondo del titolo del template diverso a seconda del tipo di programma
	if tipo == 'animata' then
		sfondo = 'background:#ab110c;'
	elseif tipo == 'serie TV' then
		sfondo = 'background:#206600;'
	elseif tipo == 'programma' then
		sfondo = 'background:#2e2eff;'
	end

---- evitando il corsivo per il titolo del template se il titolo della serie usa caratteri speciali/non latini
	local titolotemplate, charval, len, pos
	
	if etichetta ~= nil then
		len = mw.ustring.len(etichetta)
		pos = 1
		
		while ( pos <= len ) do
        	charval = mw.ustring.codepoint(mw.ustring.sub(etichetta, pos))
        	if charval>=370 and charval<2000 then
        		titolotemplate = string.format("[[%s|<span style=\"color:white;\">%s</span>]]", sitelink, etichetta)
        	elseif charval>=2100 and charval~=8364 then
        		titolotemplate = string.format("[[%s|<span style=\"color:white;\">%s</span>]]", sitelink, etichetta)
        	else
        		titolotemplate = string.format("[[%s|<span style=\"color:white;\">''%s''</span>]]", sitelink, etichetta)
        	end 
        	pos = pos + 1;
    	end
    end
	
---- se sono presenti più di una stagione/edizione genera il navbox, altrimenti solo la categoria
---- se è richiesto solo l'elenco dei collegamenti genera solo i link, utile per l'inclusione in altri template
	if not id or not etichetta or not stagioni then
		template = mw.title.getCurrentTitle().namespace == 0 and errorCategory or nil
	elseif args[2] == 'elenco' then
		template = links
	elseif stagioni == '1' or stagioni == '1±0' then
		template = categoria
	else
		template = navbox._navbox({
			name = 'Stagioni televisive',
			title = titolotemplate,
			titlestyle = sfondo,
			image = string.format("[[File:Blue pencil.svg |frameless |12px |alt=Modifica su Wikidata|link=https://www.wikidata.org/wiki/%s#P2437|Modifica su Wikidata]]", id),
			list1 = links
		})
	end

	return template, errore
end


return p