require "Амодуль:No globals"

local p = {}

local lib = require 'Амодуль:Wikidata/lib'
local cache = {}

p.props = {
	accessdate = { 'P813' },
	-- archivedate = { 'P2960' }, TODO
	-- archiveurl = { 'P1065' }, TODO
	author = { 'P50' },
	date = { 'P577' },
	doi = { 'P356' },
	-- editor = { 'P90' }, TODO
	-- illustration = { 'P110' }, TODO
	isbn = { 'P212', 'P957' },
	-- lang = { 'P364', 'P407' }, TODO
	-- pages = { 'P304' }, TODO
	place = { 'P291' },
	published = { 'P1433' },
	-- publisher = { 'P123' }, TODO
	title = { 'P1476' },
	-- type = { 'P31' }, TODO
	url = { 'P854', 'P953', 'P2699' },
	work = { 'P248' },
}

local function dataToContent(data)
	local content = {}
	local Formatters = require 'Амодуль:Wikidata/Formatters'
	if data.author then
		local authors = {}
		for _, snak in ipairs(data.author) do
			table.insert(authors, Formatters.getFormattedValue(snak, {}))
		end
		table.insert(content, table.concat(authors, ', ') .. ':')
	end
	if data.title or data.work then
		local title
		if data.title then
			title = Formatters.getFormattedValue(data.title[1], {})
		end
		if data.work then
			title = Formatters.getFormattedValue(data.work[1], { text = title }) -- TODO
		end
		table.insert(content, mw.ustring.format("''%s''.", title))
	end
	if data.published then
		local published = Formatters.getFormattedValue(data.published[1], {})
		table.insert(content, mw.ustring.format("In: %s.", published))
	end
	if data.place then
		local places = {}
		for _, snak in ipairs(data.place) do
			table.insert(places, Formatters.getFormattedValue(snak, {}))
		end
		table.insert(content, table.concat(places, ', ') .. '.')
	end
	if data.date then
		local date = Formatters.getFormattedValue(data.date[1], { nolink = true }) .. '.'
		table.insert(content, date)
	end
	if data.isbn then
		local isbn = Formatters.getFormattedValue(data.isbn[1], { pattern = '[[Цастәи:Источники_книг/$1|$1]]' })
		table.insert(content, '[[International Standard Book Number|ISBN]] ' .. isbn .. '.')
	end
	if data.doi then
		local doi = Formatters.getFormattedValue(data.doi[1], {
			autoformat = true, property = data.doi[1].property,
		})
		table.insert(content, '[[Digital object identifier|DOI]] ' .. doi .. '.')
	end
	if data.url then
		local url = Formatters.getFormattedValue(data.url[1], { ['value-formatter'] = 'url', text = 'Онлаин' }) .. '.'
		table.insert(content, url)
	elseif data.external then
		local url = Formatters.getFormattedValue(data.external[1], {
			autoformat = true, property = data.external[1].property, text = 'Азхьарԥш онлаин' -- todo: i18n
		}) .. '.'
		table.insert(content, url)
	end
	if #content > 0 and data.accessdate then
		local date = Formatters.getRawValue(data.accessdate[1], {}):toString()
		table.insert(content, mw.ustring.format('[cit. %s]', date))
	end
	return table.concat(content, ' ')
end

local function dataFromItem(id, data)
	for key, props in pairs(p.props) do
		if not data[key] then
			local array = {}
			for _, prop in ipairs(props) do
				for _, statement in ipairs(mw.wikibase.getBestStatements(id, prop)) do
					if lib.IsSnakValue(statement.mainsnak) then
						table.insert(array, statement.mainsnak)
					end
				end
				if #array > 0 then
					break
				end
			end
			if #array > 0 then
				data[key] = array
			end
		end
	end
end

function p.formatReferences(references, options)
	local frame = mw.getCurrentFrame()
	local Formatters = require 'Амодуль:Wikidata/Formatters'
	local valid_refs = {}
	local limit = tonumber(options.max_ref)
	for _, ref in ipairs(references) do
		if cache[ref.hash] then
			table.insert(valid_refs, frame:extensionTag('ref', '', { name = ref.hash }))
		else
			local data = {}
			for key, props in pairs(p.props) do
				local array = {}
				for _, prop in ipairs(props) do
					if ref.snaks[prop] then
						for _, snak in ipairs(ref.snaks[prop]) do
							if lib.IsSnakValue(snak) then
								table.insert(array, snak)
							end
						end
					end
					if #array > 0 then
						break
					end
				end
				if #array > 0 then
					data[key] = array
				end
			end
			for prop, snaks in pairs(ref.snaks) do
				if snaks[1].datatype == 'external-id' or prop == 'P627' then --fixme
					data.external = { snaks[1] }
					break
				end
			end
			if data.work then -- P248
				local id = Formatters.getRawValue(data.work[1], {})
				dataFromItem(id, data)
			end
			local ref_content = dataToContent(data)
			if ref_content ~= '' then
				if lib.IsOptionTrue(options, 'addlink') then
					-- TODO
				end
				ref_content = lib.addWdClass(ref_content)
				table.insert(valid_refs, frame:extensionTag('ref', ref_content, { name = ref.hash }))
				cache[ref.hash] = true
			end
		end
		if limit and #valid_refs == limit then
			break
		end
	end
	return table.concat(valid_refs)
end

return p