local p = {}

--similar to javascript's Array.map(), see https://stackoverflow.com/a/11671820
local function map(tbl, f)
    local t = {}
    for k,v in pairs(tbl) do
        t[k] = f(v)
    end
    return t
end

p.createTable = function(frame)
	local entityId = frame.args[1] or mw.wikibase.getEntityIdForCurrentPage() 
	if (entityId == nil) then return "" end
	
	local noError, result = pcall(createTable, entityId)
	if (noError) then 
		return result
	else 
		return ""
	end
	
end

createTable = function(entityId)
	local items = map(mw.wikibase.getAllStatements( entityId, "P958" ), function(item)
		if (item["qualifiers"]["P1545"][1]["datavalue"] == nil) then error("Series ordinal (P1545) not found") end
		if (item["qualifiers"] == nil) then error("No qualifiers") end
		
		return {
			title = item["qualifiers"]["P1476"][1]["datavalue"] and item["qualifiers"]["P1476"][1]["datavalue"]["value"]["text"] or "",
			order = item["qualifiers"]["P1545"][1]["datavalue"]["value"],
			nameShort = item["qualifiers"]["P1813"][1]["datavalue"] and item["qualifiers"]["P1813"][1]["datavalue"]["value"]["text"] or nil
		}
	end)
	
	--sorting function, see https://stackoverflow.com/a/68685466
	local function padnum(d) return ("%03d%s"):format(#d, d) end
	table.sort(items, function(a,b)
    	return tostring(a.order):gsub("%d+",padnum) < tostring(b.order):gsub("%d+",padnum) 
    end)

	function findDuplicates(t)
    	seen = {} --keep record of elements we've seen
    	for i = 1, #t do
    	    element = t[i].nameShort
    	    if (seen[element] or 0)>=1 then  --check if we've seen the element before
    	    	t[i].link = t[i].nameShort .. "_" .. seen[element]
    	    	seen[element] = seen[element] + 1
    	    else
    	        seen[(element or "")] = 1 -- set the element to seen
    	    end
    	end 
    	return t
	end 

	return table.concat(
		map(findDuplicates(items), function(item)
			return "<span style='margin-left:" .. select(2, string.gsub(item.order, "%.", ""))*2 .. "em;display:table;'>[[#" .. (item.link or item.nameShort or item.title) .. "|<span class=PHLawHeadingTocSec>" .. (item.nameShort or "") .. "</span> <span class=PHLawHeadingTocLabel>" ..item.title.."</span>]]</span>"
		end)
	, "")
	
end

return p