local Flags = require( 'Module:Wikidata/Flags' )
local p = {}

-- Get string with dates from qualifiers table
local function datesFromQualifier( context, options, qualifierId )
	local qualifiers = options.qualifiers[ qualifierId ]

	if qualifiers then
		for _, qualifier in pairs( qualifiers ) do
			if qualifier.datatype == 'time' then
				if qualifier.snaktype == 'value' then
					local year = tonumber( string.sub( qualifier.datavalue.value.time, 1, 5 ) )
					if year then
						return year
					end
				elseif qualifier.snaktype == 'novalue' then
					return options.frame:expandTemplate{ title = 'Н. в.' }
				elseif qualifier.snaktype == 'somevalue' then
					return '?'
				end
			end
		end
	end

	return ''
end

-- Get string with dates from statement
local function datesFromStatement( context, options )
	local dates = ''
	if options.qualifiers then
		local startDates = {}
		dates = datesFromQualifier( context, options, 'P580' )
		if dates ~= '' then
			local endDates = datesFromQualifier( context, options, 'P582' )
			if endDates and endDates ~= '' and endDates ~= dates then
				dates = dates .. '—' .. endDates
			end
		else
			dates = datesFromQualifier( context, options, 'P585' )
		end
	end
	return dates
end

-- Get string with score from qualifiers table
local function scoreFromQualifier( context, options, qualifierId )
	local scores = {}
	local qualifiers = options.qualifiers[ qualifierId ]

	if qualifiers then
		for _, qualifier in pairs( qualifiers ) do
			if qualifier.datavalue then
				table.insert( scores, tonumber( qualifier.datavalue.value.amount ) )
			end
		end
	end

	return table.concat( scores, ', ' )
end

-- Get string with score from statement
local function scoreFromStatement( context, options )
	local score = ''
	if options.qualifiers then
		score = scoreFromQualifier( context, options, 'P1350' )
		local goalScore = scoreFromQualifier( context, options, 'P1351' )
		if goalScore ~= '' then
			score = score .. ' (' .. goalScore .. ')'
		end
	end
	return score
end

-- Get string with score from qualifiers table
local function isLoan( context, options )
	if options.qualifiers and options.qualifiers.P1642 then
		for _, qualifier in pairs( options.qualifiers.P1642 ) do
			if qualifier.datavalue and qualifier.datavalue.value.id == 'Q2914547' then
				return true
			end
		end
	end

	return false
end

local function calculateEndDateTimestamp( context, options, statement )
	if not context then error( 'context not specified' ) end;
	if not options then error( 'options not specified' ) end;
	if not options.entity then error( 'options.entity missing' ) end;
	if not statement then error( 'statement not specified' ) end;

	if statement.qualifiers and statement.qualifiers.P582 then
		for i, qualifier in ipairs( statement.qualifiers.P582 ) do
			local parsedTime = context.parseTimeFromSnak( qualifier );
			if parsedTime then
				return parsedTime;
			end
		end
	end

	-- check death day... do we have it at all?
	for h, propertyId in pairs( { "P570", "P577", "P576" } ) do
		local dateClaims = context.selectClaims( options, propertyId );
		if dateClaims then
			for i, statement in ipairs( dateClaims ) do
				local parsedTime = context.parseTimeFromSnak( statement.mainsnak );
				if parsedTime then
					return parsedTime;
				end
			end
		end
	end

	-- TODO: check other "end" properties

	-- no death day
	return os.time() * 1000;
end

local function getClub( context, options, claim )
	local entityId = claim.mainsnak.datavalue.value.id
	local club = context.formatStatement( options, claim )
	
	local countryClaims = mw.wikibase.getBestStatements( entityId, 'P17' )
	for _, countryClaim in ipairs( countryClaims ) do
		local countryEntityId = countryClaim.mainsnak.datavalue.value.id
		local endDateTimestamp = calculateEndDateTimestamp( context, options, claim )
		local flag = Flags.getFlag( context, countryEntityId, endDateTimestamp )
		if flag and flag ~= '' then
			club = flag .. ' ' .. club
			break
		end
	end
	
	if isLoan( context, options ) then
		club = options.frame:expandTemplate{ title = 'Аренда' } .. club
	end
	
	return '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. club .. '</span>'
end

--Property function for [[d:Property:P54]]
function p.formatProperty( context, options )
	if ( not context ) then error( 'context not specified' ); end;
	if ( not options ) then error( 'options not specified' ); end;
	if ( not options.entity ) then error( 'options.entity missing' ); end;

	local claims;
	if options.property then -- TODO: Почему тут может не быть property?
		claims = context.selectClaims( options, options.property .. '[rank:preferred, rank:normal]' );
	end
	if claims == nil then
		return '' --TODO error?
	end

	-- Обход всех заявлений утверждения и с накоплением оформленых
	-- предпочтительных заявлений в таблице.
	local rows = {}
	for i, claim in ipairs( claims ) do
		if ( claim.mainsnak and
			claim.mainsnak and
			claim.mainsnak.datavalue and
			claim.mainsnak.datavalue.type == 'wikibase-entityid'
		) then
			local dates = datesFromStatement( context, options )
			local club = getClub( context, options, claim )
			local score = scoreFromStatement( context, options )
			table.insert( rows, {
				dates = dates,
				fields = { dates, club, score },
			} )
		end
	end

	-- Склейка строк списка в итоговый шаблон спортивной карьеры
	local fields = {}
	for i, row in ipairs( rows ) do
		for i, field in ipairs( row.fields ) do
			table.insert( fields, field )
		end
	end
	return options.frame:expandTemplate{ title = 'Спортивная карьера', args = fields }
end

return p