-- version 20210322 from master @cawiki

local p = {}

local claim = require('Module:Wikidata.Ca').claim
local i18n = {
	["categoryprop"] = "تصنيف:صفحات تستخدم خاصية $1", -- Category:Pages using Wikidata property $1 
}

function p.main(frame)
	local args = frame.args or frame -- via invoke or require
	local pargs = frame.args and frame:getParent().args or {}
	local id = args.item or pargs.item
	if id == nil or id == '' then
		id = mw.wikibase.getEntityIdForCurrentPage()
	end
	local unit = args.unit or pargs.unit; if unit == "" then unit = nil end
	local blacklist = {}
	for qid in mw.text.gsplit(args.blacklist or "", "/", true) do
		blacklist[qid] = true
	end
	local lang = args.lang or pargs.lang
	
	-- Fetch all data and fill a table
	local data = {}
	local labels = {}
	local cats = ''
	
	local function fillData(prop, dimension, value)
		if type(value) == 'string' then
			if mw.ustring.match(value, '[%a]+') then
				data[#data + 1] = {}
				data[#data].dimension = dimension
				data[#data].amount = mw.ustring.match(value, '[^%a]+')
				data[#data].unit = mw.ustring.match(value, '[%a]+')
				for p in mw.text.gsplit(prop, ' OR ', true) do
					labels[dimension] = mw.wikibase.getLabel(p) or id
					break
				end
				return
			end
		end
		local fetch = claim{
			item = id, lang = lang, editicon = false,
			formatting = 'table', separator = '<and>',
			property = prop, colformat0 = 'unitcode', convert0 = unit,
			qualifier = 'P518 OR P1013', colformat1 = 'raw',
			qualifier2 = 'P518 OR P1013', colformat2 = 'label',
			rowformat = '$0$1', rowsubformat1 = '($1=$2)'
		}
		if fetch then 
			for p in mw.text.gsplit(prop, ' OR ', true) do
				if #mw.wikibase.getAllStatements(id, p) > 0 then
					labels[dimension] = mw.wikibase.getLabel(p) or id
					cats  = cats .. "[[" .. string.gsub(i18n.categoryprop, '$1', p) .. "]]"
					break
				end
			end
			for dim in mw.text.gsplit(fetch, '<and>', true) do
				if mw.ustring.match(dim, '[%a]+') then -- units constraint
					data[#data + 1] = {}
					data[#data].dimension = dimension
					local group = mw.ustring.match(dim, '%b()')
					if group then
						group_parts = mw.text.split(mw.ustring.sub(group, 2, -2), '=', true)
						data[#data].group = group_parts[2]
						if blacklist[group_parts[1]] then
							blacklist[group_parts[2]] = true
						end
					end
					data[#data].amount = mw.ustring.match(dim, '[^%a]+')
					data[#data].unit = mw.ustring.match(dim, '[%a]+')
				end
			end
		end
	end
	
	-- diameter
	fillData('P2386', 'diameter',args['diameter'])
	-- height and alike
	fillData('P2048', 'height',args['height'])
	fillData('P2262', 'draft',args['draft'])
	fillData('P2793', 'clearance',args['clearance'])
	-- width or beam
	fillData('P2049 OR P2261', 'width',args['width'])
	-- length or depth and alike
	fillData('P2043 OR P5524', 'length',args['length'])
	fillData('P2787', 'span',args['span'])
	fillData('P2610', 'thickness',args['thickness'])
	
	-- group by qualifier
	local dimensions = {}
	local global_unit
	for i, v in ipairs(data) do
		local index = v.group or 1
		if blacklist[index] == nil then
			if dimensions[index] == nil then
				dimensions[index] = {}
			end
			table.insert(dimensions[index], {["dimension"]=v.dimension, ["amount"]=v.amount, ["unit"]=v.unit})
			-- global unit
			if i == 1 then
				global_unit = v.unit
			elseif global_unit and global_unit ~= v.unit then
				global_unit = nil
			end
		end
	end
	
	-- format output
	local icons = {
		["diameter"] = "[[File:Durchschnittszeichen.png|10px|link=|",
		["height"] = "[[File:Chess uat45.svg|15px|link=|",
		["draft"] = "[[File:Breezeicons-actions-22-draw-halfcircle4.svg|15px|link=|",
		["clearance"] = "[[File:Breezeicons-actions-22-format-align-vertical-top.svg|15px|link=|",
		["width"] = "[[File:Chess lrt45.svg|15px|link=|",
		["length"] = "[[File:Chess urt45.svg|15px|link=|",
		["span"] = "[[File:Breezeicons-actions-22-draw-halfcircle3.svg|15px|link=|",
		["thickness"] = "[[File:Breezeicons-actions-22-format-align-vertical-center.svg|15px|link=|",
	}
	local dim_sort = {["diameter"]=1, ["height"]=2, ["draft"]=3, ["clearance"]=4, ["width"]=5, ["length"]=6, ["span"]=7, ["thickness"]=8}
	local out = {}
	for q, t in pairs(dimensions) do
		if type(q) == "string" then
			table.insert(out, q .. ":")
		end
		table.sort(t, function(a, b) return dim_sort[a.dimension] < dim_sort[b.dimension] end)
		for i, v in ipairs(t) do
			local suffix = " (" .. icons[v.dimension] .. labels[v.dimension] .. "]])"
			if i == #t or not global_unit then
				suffix = suffix .. " " .. v.unit
			end
			if i < #t then
				suffix = suffix .. " ×"
			end
			table.insert(out, '<span style="white-space:nowrap;">' .. v.amount .. suffix .. '</span>')
		end
		table.insert(out, "<br />")
	end

    if mw.title.getCurrentTitle().namespace == 0 and cats ~='' then table.insert(out, cats)   end
	
	local ans = mw.text.trim(table.concat(out, " "))
    if(ans == '') then return nil else return ans end
    
end

return p