--[[
* Modulo a supporto del template Stagione squadra.
]]--

require('strict')

local getArgs = require('Modulo:Arguments').getArgs
local mWikidata = require('Modulo:Wikidata')
local ns0 = mw.title.getCurrentTitle().namespace == 0

-- Ritorna il valore di una proprietà se esiste uno e un solo claim per quella proprietà e per l'eventuale qualificatore specificato.
--
-- @param {table} args
-- @return {string}
local function getPropertyIfUnique(args)
	local results = mWikidata._getProperty(args, true)
	
	-- Se non ci sono risultati, potrebbe essere perché sono stati trovati dei claim classificati come 'preferred',
	-- ma fra questi non è stato trovato quello con il qualificatore specificato.
	-- Quindi riprova cercando esclusivamente tra i claim classificati come 'normal'.
	if (not results or #results == 0) and args.rank ~= 'normal' and args.qualifier then
		args.rank = 'normal'
		return getPropertyIfUnique(args)
	end
	
	if results and #results == 1 then
		return results[1]
	end
end

-- Ritorna una categoria di errore.
--
-- @param {string} obj
-- @return {string}
local function getErrorCat(obj)
	if ns0 then
		local sortkey = mw.title.getCurrentTitle().text
		return string.format('[[Categoria:Voci con template Stagione squadra senza %s|%s]]', obj, sortkey)
	else
		return ''
	end
end

-- Ricava lo sport da Wikidata.
--
-- @return {string}
local function getSportFromWikidata()
	return getPropertyIfUnique({ 'P641', formatting='label' })
end

-- Cerca di indovinare lo sport dal nome della pagina che invoca il modulo.
--
-- @return {string}
local function guessSportFromParentName(frame)
	local parent = frame:getParent()
	if parent then
		if parent:getTitle() == "Template:Stagione squadra football americano" then
			return "football americano"
		end
	end
end

-- Ricava il nome del template stemmino da Wikidata a partire dall'ID Wikidata di una squadra.
--
-- @param {string} clubID
-- @return {string}
local function getNomeStemminoFromWikidata(clubID)
	return getPropertyIfUnique({ 'P1424', from=clubID, formatting='title', qualifier='P3831', qualifiervalue='Q115707333' })
end

-- Ricava l'ID dell'elemento Wikidata della società sportiva.
--
-- @return {string}
local function getClubIDFromWikidata()
	return getPropertyIfUnique({ 'P5138', formatting='id' })
end

local function getSport(frame)
	local args = getArgs(frame, { parentOnly = true })
	local sport = args.sport or guessSportFromParentName(frame) or getSportFromWikidata()
	return sport and sport:lower() or nil
end

local function extractClubAndYearsFromTitle()
	local title = mw.title.getCurrentTitle().text
	title = title:gsub(' %([^()]*%)$', '') -- rimuovi eventuale disambiguazione
	
	for _, regex in ipairs({
		'^(.*) (%d%d%d%d%-%d%d%d%d)$',
		'^(.*) (%d%d%d%d)$'
	}) do
		local club, years = title:match(regex)
		if years then return club, years end
	end
end

local function getAnnata(args)
	if args.stagione and args.stagione ~= '' then return args.stagione end
	local club, years = extractClubAndYearsFromTitle()
	return years or ''
end

local function getClub(args)
	if args.club and args.club ~= '' then return args.club end
	local club, years = extractClubAndYearsFromTitle()
	return club or ''
end

local function getStemmino(frame)
	local args = getArgs(frame, { parentOnly = true })
	
	-- L'annata viene passata al template stemmino nell'eventualità in cui usi MultiBand
	local years = getAnnata(args)
	local startYear = years:match("^%d%d%d%d")
	local nomeStemmino = args['template club']
	
	if not nomeStemmino or nomeStemmino == '' then
		local clubID = getClubIDFromWikidata()
		-- TODO: lo sport potrebbe servire a ricavare il template corretto da Wikidata, nel caso di di società polisportive 
		--local sport = getSport(frame)
		nomeStemmino = getNomeStemminoFromWikidata(clubID)
	end
	
	if nomeStemmino and nomeStemmino ~= '' then
		-- chiamata protetta per verificare l'esistenza del template
		local success, stemmino = pcall(frame.expandTemplate, frame, {
			title = nomeStemmino,
			args = { 'S', startYear or '' }
		})
		if success then return stemmino end
	end
	return false
end

-- =============================================================================
--                            Funzioni esportate
-- =============================================================================

local p = {}

-- Funzione da chiamare come {{#invoke:Stagione squadra|sport}}
function p.sport(frame)
	return getSport(frame)
end

-- Funzione da chiamare come {{#invoke:Stagione squadra|annata}}
function p.annata(frame)
	--TODO: l'annata può essere anche ricavata da Wikidata tramite P2348
	local args = getArgs(frame, { parentOnly = true })
	return getAnnata(args)
end

-- Funzione da chiamare come {{#invoke:Stagione squadra|club}}
function p.club(frame)
	local args = getArgs(frame, { parentOnly = true })
	return getClub(args)
end

-- Funzione da chiamare come {{#invoke:Stagione squadra|stemmino}}
function p.stemmino(frame)
	return getStemmino(frame) or getPropertyIfUnique({ 'P5138' })
end

-- Funzione da chiamare come {{#invoke:Stagione squadra|categorie_tracciamento_stemmino}}
function p.categorie_tracciamento_stemmino(frame)
	local stemmino = getStemmino(frame)
	return stemmino and stemmino ~= '' and ''
		or getClubIDFromWikidata() and getErrorCat("stemmino")
		or getErrorCat("stemmino") .. getErrorCat("squadra")
end

-- Funzione da chiamare come {{#invoke:Stagione squadra|categoria_annata_sport}}
function p.categoria_annata_sport(frame)
	local args = getArgs(frame, { parentOnly = true })
	local years = getAnnata(args)
	local sport = getSport(frame)
	local sortkey = mw.title.getCurrentTitle().text
	
	local error_cat = ''
	if not sport then error_cat = error_cat .. getErrorCat("sport") end
	if not years then error_cat = error_cat .. getErrorCat("annata") end
	return not ns0 and ''
		or error_cat ~='' and error_cat
		or string.format('[[Categoria:Stagione %s delle squadre di %s|%s]]', years, sport, sortkey)
end

return p