local p = {}

if nil ~= string.find(mw.getCurrentFrame():getTitle(), "ملعب", 1, true) then -- did the {{#invoke:}} use sandbox version?
	wikidata = require("وحدة:Wikidata2/ملعب").formatStatementsFromLua
else -- otherwise
	wikidata = require("وحدة:Wikidata2").formatStatementsFromLua
end

local quall = require("Module:Cite/quall")
local functions = require("Module:Cite/functions")

local Options = {}

local function getentityprop(entity, p, pattern)
	-- get automatically url
	local addTracking = ""
	local Pattern = pattern or "autourl4" --autourl3
	if p == "P345" then
		Pattern = ""
		addTracking = ""
	end	

	local tot = wikidata({ textformat = "text", property = p, pattern = Pattern, numval = 5, noref = "true", conjunction = " & ", enlabelcate = "true", addTrackingCat = addTracking, noicon = "t", raw2 = Options.raw or ""})
	if not tot or tot == "" then
		tot = wikidata({ textformat = "text", entityId = entity, property = p, pattern = Pattern, noref = "true", conjunction = " & ", enlabelcate = "true", addTrackingCat = addTracking, noicon = "t", raw2 = Options.raw or "", numval = 5})
	end

	local tot2 = ""
	if p == "P345" then
		tot2 = functions.make_P345_link_o(tot)
	end
	if tot2 and tot2 ~= "" then
		tot = "[" .. tot2 .. " " .. tot2 .. "]"
	end
	if tot and tot ~= "" then
		tot = "وصلة : " .. tot
	end
	return tot
end

--[[
   يجلب خواص معينة عند وجود مراجع محددة مسبقاً
--]]
local function getsomequall(entity, snak, property)
	if
		snak[property] and snak[property][1] and snak[property][1].datavalue and
			snak[property][1].datavalue.value["numeric-id"]
	 then
		id = snak[property][1].datavalue.value["numeric-id"]
		local l10n = quall[id]
		if l10n then
			local q = {}
			for _, v in pairs(l10n) do
				mw.log("Module:Cite finding " .. v[1] .. ", id:" .. id .. ",3:" .. (v[3] or ""))
				b = getentityprop(entity, v[1], v[3])
				if b and b ~= "" then
					table.insert(q, b)
					mw.log("Module:Cite b " .. b)
				end
			end
			t = table.concat(q)
			if t and t ~= "" then
				return t
			end
		end
	end
end

local function ValueFromItem(items, property, firstvalue)
	local pattern = "autourl"
	if property == "P212" or property == "P957" then
		pattern = nil
	end -- no automatic link for ISBN
	for i, item in pairs(items) do
		ednumber = wikidata({ textformat = "text", entityId = item, property = property, firstvalue = firstvalue, pattern = pattern, noref = "true", modifytime = "longdate", enlabelcate = "true", numval = 5})
	end
	return ednumber
end

local function ValueFromEntityId(entity, property, firstvalue)
	local pattern = "autourl"
	val = wikidata({ textformat = "text", entityId = entity, property = property, firstvalue = firstvalue, pattern = pattern, noref = "true", modifytime = "longdate", enlabelcate = "true", numval = 5})
	if val then
		return val
	end
end

--local function GetValueFromEntityId(snak,entity, property, firstvalue)
local function GetValueFromEntityId(snak, property, firstvalue)
	--local A = wikidata({ textformat = "text",property = "P1629", entityId=property,enlabelcate="true", firstvalue="true", noref="true", label = functions.get_property_label( property )})
	local A = functions.get_property_label(property)
	local Pattern = "autourl"
	if property == "P345" then
		Pattern = ""
	end
	local prop = wikidata({ textformat = "text", property = property, firstvalue = firstvalue, noref = "true", pattern = Pattern, modifytime = "longdate", numval = 5}, snak)
	--mw.log("prop" .. prop )
	if property == "P345" then
		url = functions.make_P345_link_o(prop)
		if url and url ~= "" then
			prop = "[" .. url .. " " .. url .. "]"
		end
	end
	--mw.log('Module:Cite property:"' .. property .. '"' )
	--mw.log('Module:Cite prop:"' .. prop .. '"' )
	--if not prop then prop = ValueFromEntityId(entity, property,firstvalue) end
	if prop and prop ~= "" then
		if A and A ~= "" then
			return A .. ": " .. prop
		else
			return prop
		end
	end
end

local function GetValueFromItem(items, snak, property, text, firstvalue)
	if property == "P50" then
		for i, item in pairs(items) do
			if item == "Q36578" then
				return ""
			end
		end
	end
	
	local pattern = "autourl"
	if property == "P212" or property == "P957" then
		pattern = nil
	end -- no automatic link for ISBN
	local prop = wikidata({ textformat = "text", property = property, firstvalue = firstvalue, pattern = pattern, numval = 5, noref = "true", modifytime = "longdate", enlabelcate = "true"}, snak)
	if not prop then
		prop = ValueFromItem(items, property, firstvalue)
	end
	if prop and prop ~= "" then
		if text and text ~= "" then
			prop = text .. ": " .. prop
		end
	end
	return prop
end

local function get_number_from_item(items, property)
	for i, item in pairs(items) do
		ednumber = wikidata({ textformat = "text", entityId = item, property = property, firstvalue = "yes", enlabelcate = "true", numval = 5})
		if ednumber then
			return ednumber
		end
	end
end

local function getnumber(items, snak, property, text)
	local tex = functions.get_property_label(property)

	local number = wikidata({ textformat = "text", property = property, firstvalue = "true", enlabelcate = "true", numval = 5}, snak)
	if not number then
		number = get_number_from_item(items, property)
	end
	if not text then
		text = tex
	else
	end

	if number and number ~= "" then
		if text then
			return text .. ": " .. number
		else
			return number
		end
	end
end

local function GetItemValue(items, snak, property, text, firstvalue)
	local pattern = "autourl"
	--	if property =="P212" or property =="P957" then pattern = nil end -- no automatic link for ISBN
	local prop = wikidata({ textformat = "text", property = property, firstvalue = (firstvalue or ""), pattern = pattern, noref = "true", modifytime = "longdate", separator = "، و", conjunction = "، و", numval = 5 }, snak)
	if not prop then
		prop = ValueFromItem(items, property, (firstvalue or ""))
	end

	if prop and prop ~= "" then
		if text and text ~= "" then
			prop = text .. ": " .. prop
		end
	end
	return prop
end

local function GetNumberFromItem(items, snak, property, text, firstvalue)
	local prop = wikidata({ textformat = "text", property = property, firstvalue = "t", numval = 5}, snak)
	for i, item in pairs(items) do
		ednumber = wikidata({ textformat = "text", entityId = item, property = property, firstvalue = "true", noref = "true", numval = 5}
		)
	end
	if not prop then
		prop = ednumber
	end
	if prop and prop ~= "" then
		if text and text ~= "" then
			prop = text .. prop
		end
	end
	return prop
end

--[[
  جلب أي وصلة مرجع من الخواص مثل
	 P1065,P854
--]]
local function getLink(items, snak, property, text)
	-- local tex = functions.labeel(property,text)
	local links = wikidata({ textformat = "text", property = property, pattern = "true", noref = "true", firstvalue = "true", numval = 5}, snak)
	if links and links ~= "" then
		if text and text ~= "" then
			return functions.geturl(links, text)
		else
			return links
		end
	end
end
local function get_Link_from_item(items, snak, property, text)
	local links = ValueFromItem(items, property, "true")
	local tex = functions.labeel(property, text)
	if links and links ~= "" then
		if tex and tex ~= "" then
			return tex .. ": " .. links
		else
			return links
		end
	end
end
--[[
  جلب أي تاريخ من الخواص مثل
	 P813,P577
--]]
local function getdate(snak, property, text)
	-- local tex = functions.labeel(property,text)
	if snak[property] then
		local dat = wikidata({ textformat = "text", property = property, pattern = "true", noref = "true", modifytime = "longdate", numval = 5 }, snak)
		if dat and dat ~= "" then
			if text and text ~= "" then
				return text .. ": " .. dat
			else
				return dat
			end
		end
	end
end

local function getdate1(items, snak, property, text)
	for i, item in pairs(items) do
		local datetime1 = wikidata({ textformat = "text", entityId = item, property = property, noref = "true", enlabelcate = "true", modifytime = "longdate", numval = 5})
	end
	if text then
		return text .. ": " .. datetime1
	else
		return datetime1
	end
end

local function getedition(items, snak)
	for i, item in pairs(items) do
		if item == "Q36578" then
			return ""
		end
	end
	local ordning = {
		"الأول",
		"الثاني",
		"الثالث",
		"الرابع",
		"الخامس",
		"السادس",
		"السابع",
		"الثامن",
		"التاسع",
		"العاشر",
		"الحادي عشر",
		"الثاني عشر"
	}
	local ednumber
	if snak["P393"] then
		ednumber = wikidata({ textformat = "text", property = "P393", firstvalue = "true", enlabelcate = "true", numval = 5}, snak)
	else
		ednumber = get_number_from_item(items, "P393")
	end
	if not ednumber then
		return nil
	end
	if not tonumber(ednumber) then
		return " الاصدار " .. ednumber
	end
	if ordning[tonumber(ednumber)] then
		return " الاصدار " .. ordning[tonumber(ednumber)]
	end
	local sist = string.sub(ednumber, string.len(ednumber))
	if sist == "1" or sist == "2" then
		return " : الاصدار " .. ednumber
	else
		return " : الاصدار " .. ednumber
	end
end

local function getsubtitle(items, snak) -- needs i18n some languages do not use this format
	local s = {}
	if snak["P1680"] then
		dd = wikidata({textformat = "text", property = "P1680", firstvalue = "true", enlabelcate = "true", numval = 5}, snak)
		table.insert(s,dd)
	else
		for i, item in pairs(items) do
			local lab = wikidata({ textformat = "text", property = "P1680", enlabelcate = "true", entityId = item, firstvalue = "true", noref = "true", numval = 5})
			local sitelink = mw.wikibase.sitelink(item)
			if sitelink and lab then
				table.insert(s, "[[:" .. sitelink .. "|" .. lab .. "]]")
			elseif sitelink then
				table.insert(s, "[[:" .. sitelink .. "]]")
			elseif lab then
				table.insert(s, lab)
			end
		end
	end
	tot = table.concat(s, " — ")
	if tot and tot ~= "" then
		return tot
	else
		return nil
	end
end

local function gettitle(items, snak)
	local link = getLink(items, snak, "P854") or getLink(items, snak, "P1065", "") -- the title will be with the link
	local title = GetItemValue(items, snak, "P1476", "العنوان ", " ")
	local subtitle = GetItemValue(items, snak, "P1680", "العنوان ", " ")
	if not title or title == "" then
		title = subtitle
	end
	if link and link ~= "" then
		return ""
	else
		return title
	end
end

local function getwhatever(snak, property)
	if snak[property] then
		--mw.log("Module:Cite getwhatever property " .. property)
		local a = functions.get_property_label(property)
		--local a = wikidata({ textformat = "text",property = "P1629", entityId=property, firstvalue="true", noref="true", enlabelcate="true", label =	functions.get_property_label(property)})

		local s = {}
		--local items = {}
		--mw.log("Module:Cite find snak.property " .. property)
		for j, prop in pairs(snak[property]) do
			if prop.snaktype == "value" then
				item = "Q" .. prop.datavalue.value["numeric-id"]
				--table.insert(items, item)
				faso = wikidata({ textformat = "text", entityId = item, property = property, noref = "true", conjunction = ", ", enlabelcate = "true", numval = 5})
				table.insert(s, faso)
			end
		end
		if property == "P143" then
			a = "مستورد من "
		end
		if property == "P248" then
			a = "'''مذكور في'''"
		end
		--table.insert(s, wikidata({textformat = "text",property=property, conjunction=', ', enlabelcate="true"}, snak))
		if #s > 0 then
			return (a or "") .. "''':''' " .. table.concat(s, ", ")
		end
	end
end

--local function gettherest(snak, entity)
local function gettherest(snak)
	local s = {}
	for property, j in pairs(snak) do
		Known = false
		for k, l in pairs(functions.Known_properties) do
			if property == l then
				Known = true
			end
		end
		if not Known then
			local entity1 = mw.wikibase.getEntityObject(property)
			if entity1.claims and (entity1.datatype == "string" or entity1.datatype == "external-id") then
				--local vaa =  GetValueFromEntityId(snak, entity, property, "true" )
				local vaa = GetValueFromEntityId(snak, property, "true")
				--mw.log("Module:Cite gettherest property:" .. property )
				table.insert(s, vaa)
			end
		end
	end
	if #s > 0 then
		return table.concat(s, " — ")
	end
end

function numbers(items, snak)
	local section = GetNumberFromItem(items, snak, "P958", "الباب: ")
	local volume = GetNumberFromItem(items, snak, "P478", "المجلد: ")
	local page = GetNumberFromItem(items, snak, "P304", "الصفحة: ")
	local issue = GetNumberFromItem(items, snak, "P433", "العدد: ")

	field = {}
	if section and section ~= "" then
		table.insert(field, section)
	end
	if volume and volume ~= "" then
		table.insert(field, volume)
	end
	if page and page ~= "" then
		table.insert(field, page)
	end
	if issue and issue ~= "" then
		table.insert(field, issue)
	end
	return table.concat(field, " — ")
end

local function getISBN(items, snak)
	local ISBN13 = GetNumberFromItem(items, snak, "P212", "ISBN ", "yes") --ISBN 13
	local ISBN10 = GetNumberFromItem(items, snak, "P957", "ISBN ", "yes") --ISBN 10
	if not ISBN13 or ISBN13 == "" then
		ISBN13 = ISBN10
	end
	return ISBN13
end

function doipmid(items, snak)
	local doi = GetValueFromItem(items, snak, "P356")
	 -- Digital Object Identifier
	local pmid = GetValueFromItem(items, snak, "P698")
	 -- Identifier for journal
	local pmc = GetValueFromItem(items, snak, "P932")
	 -- identifier issued by PubMed Central
	field = {}
	if doi and doi ~= "" then
		table.insert(field, doi)
	end
	if pmid and pmid ~= "" then
		table.insert(field, pmid)
	end
	if pmc and pmc ~= "" then
		table.insert(field, pmc)
	end
	return table.concat(field, " — ")
end

local function Getquall(snak, entity)
	local quall = getsomequall(entity, snak, "P143")
	local quall1 = getsomequall(entity, snak, "P248")
	if not quall or quall == "" then
		quall = quall1
	end
	return quall
end

function getMultiLink(items, snak, entity)
	local title = GetItemValue(items, snak, "P1476", "", "")
	local link = getLink(items, snak, "P854", title)
	 --,"وصلة مرجع"
	local link1 = get_Link_from_item(items, snak, "P854") --
	--local therest = gettherest(snak, entity)
	local therest = gettherest(snak)
	local quall = Getquall(snak, entity)
	local fulltext = get_Link_from_item(items, snak, "P953") --
	local accessdate = getdate(snak, "P813", "تاريخ الاطلاع")
	local archive = getLink(items, snak, "P1065", "")
	field = {}
	if link and link ~= "" then
		newtab = link --We don't need to search for some links if they here already
	elseif therest and therest ~= "" then
		newtab = therest
	elseif quall and quall ~= "" then
		newtab = quall
	elseif link1 and link1 ~= "" then
		newtab = link1 -- last thing we want to see
	elseif fulltext and fulltext ~= "" then
		newtab = fulltext
	end
	if link and link ~= "" then
		if archive and archive ~= "" then
			archiveandlink = "t"
		end
	end
	if newtab and newtab ~= "" then
		table.insert(field, newtab)
		if accessdate and accessdate ~= "" then
			table.insert(field, accessdate)
		end
	end
	if archiveandlink and archiveandlink ~= "" then
		return ""
	else
		return table.concat(field, " — ")
	end
end

function getarchiveLink(items, snak, entity)
	local title = GetItemValue(items, snak, "P1476", "", "")
	local link = getLink(items, snak, "P854", "")

	local archive = getLink(items, snak, "P1065", "")
	local archive1 = getLink(items, snak, "P1065", "وصلة ارشيفية")
	local archivedate = getdate(snak, "P2960", "")
	 -- تاريخ الأرشفة
	local accessdate = getdate(snak, "P813", "تاريخ الاطلاع")
	local aa = functions.geturl((archive or link), title)

	field = {}
	if archive and archive ~= "" then
		if aa and aa ~= "" then
			table.insert(field, aa)
		end
		if link and link ~= "" then
			org = functions.geturl(link, "الأصل")
			if accessdate and accessdate ~= "" then
				table.insert(field, accessdate)
			end
		end
		a = " مؤرشف من " .. (org or "الأصل")
		if archivedate and archivedate ~= "" then
			a = a .. " في " .. archivedate
		end
		table.insert(field, a)
	end
	return table.concat(field, " — ")
end

function getreftable(items, snak, hash, options)
	local entity = options.entityId
	local rows = {
		GetValueFromItem(items, snak, "P50", "المؤلف"), --author
		GetValueFromItem(items, snak, "P98", "المحرر"), --editor
		gettitle(items, snak), --title
		GetValueFromItem(items, snak, "P123", "الناشر"), --publisher
		GetValueFromItem(items, snak, "P170", "المخترع"), --creator
		GetValueFromItem(items, snak, "P1433", "نشر في"), --publishedin
		getdate(snak, "P577", "تاريخ النشر"), --publishdate
		getedition(items, snak), --edition
		numbers(items, snak), --number
		doipmid(items, snak), --doipmid
		getISBN(items, snak), --isbn
		(getwhatever(snak, "P143") or getwhatever(snak, "P248")), --import
		getMultiLink(items, snak, entity), --MultiLink
		getarchiveLink(items, snak, entity), --archiveLink
		GetItemValue(items, snak, "P1683", "إقتباس", " ") --quote
	}

	local field = {}

	for _, line in pairs(rows) do
		if line and line ~= "" then
			table.insert(field, line)
		end
	end

	local license = GetItemValue(items, snak, "P275", "الرخصة")
	if license and license ~= "" and #field > 0 then
		table.insert(field, license)
	end

	local doo = table.concat(field, " — ")

	if doo and doo ~= "" then
		return doo --mw.getCurrentFrame():extensionTag( "ref", doo, {name = hash} )
	end
end

local function findblacklist(items)
	-- function to ignore Sister projects
	local val = "false"
	local s = {}
	for i, item in pairs(items) do
		function qoo(item, property)
			return wikidata({textformat = "text", entityId = item, property = property, noref = "true", firstvalue = "1", formatting = "raw", numval = 5})
		end
		local wiki = qoo(item, "P1800") or qoo(item, "P1566") or qoo(item, "P21") -- all wikimedia site, GeoNames ,gender
		local wik2 = qoo(item, "P31")
		local blackk = {
			"Q20651139",
			"Q465",
			"Q15241312",
			"Q30069253", -- ظهور مشكلة غير معروفة السبب في كريستوفر_تولكين [[موضوع:Veus9rhajrejwaho]]
			"Q52" -- Wikipedia
		}
		for k, b in pairs(blackk) do
			if item == b then
				val = "true"
			end
		end
		if wiki and wiki ~= "" then
			val = "true"
		elseif
			wik2 == "Q5" or -- Human is not a direct reference
				wik2 == "Q184188" or -- Also Canton
				wik2 == "Q1250464"
		 then
			val = "true" -- Also places
		end
	end
	return val
end

local ref_cash = {}

function p.citeitem(items, snak, hash, options, notag)
	Options = options
	if hash and hash ~= "" and ref_cash[hash] then
		--mw.log("Module:Cite ref_cash[hash] = " .. hash)
		return ref_cash[hash]
	end
	if not items and not snak then
		return nil
	end
	if type(items) == "string" then
		items = {items}
	end
	items = {}
	if snak.P248 then
		for j, prop in pairs(snak.P248) do
			if prop.snaktype == "value" then
				table.insert(items, "Q" .. prop.datavalue.value["numeric-id"])
			end
		end
	elseif snak.P143 then
		for j, prop in pairs(snak.P143) do
			if prop.snaktype == "value" then
				table.insert(items, "Q" .. prop.datavalue.value["numeric-id"])
			end
		end
	end
	local blacklist1 = findblacklist(items)
	if blacklist1 == "true" then
		return nil
	end
	--local findtype = FindTypeOfRefrence(items, snak, options)
	local refrence = getreftable(items, snak, hash, options)
	if refrence and refrence ~= "" then
		if notag and notag ~= "" then
			refrence = refrence
		else
			refrence = mw.getCurrentFrame():extensionTag("ref", refrence, {name = hash})
		end
	end
	if hash and hash ~= "" then
		ref_cash[hash] = refrence
	end
	return refrence
end

function p.citeitem2(ref, options, notag)
	Options = options
	if not ref then
		return nil
	end
	local hash = ref.hash
	local snak = ref.snaks
	local snnaks = ""
	if hash and hash ~= "" and ref_cash[hash] then
		--mw.log("Module:Cite ref_cash[hash] = " .. hash)
		return ref_cash[hash]
	end
	for Px, prope in pairs(snak) do
		snnaks = snnaks .. "," .. Px
	end
	--mw.log( "Module:Cite Citeitem2 hash: " ..	 hash )
	--mw.log( "Module:Cite *snnaks : " ..  snnaks )
	items = {}
	if snak.P248 then
		for j, prop in pairs(snak.P248) do
			if prop.snaktype == "value" then
				table.insert(items, "Q" .. prop.datavalue.value["numeric-id"])
			end
		end
	elseif snak.P143 then
		for j, prop in pairs(snak.P143) do
			if prop.snaktype == "value" then
				table.insert(items, "Q" .. prop.datavalue.value["numeric-id"])
			end
		end
	end
	local blacklist1 = findblacklist(items)
	if blacklist1 == "true" then
		return nil
	end
	--local findtype = FindTypeOfRefrence(items, snak, options)
	local refrence = getreftable(items, snak, hash, options)
	if refrence and refrence ~= "" then
		if notag and notag ~= "" then
			refrence = refrence
		else
			refrence = mw.getCurrentFrame():extensionTag("ref", refrence, {name = hash})
		end
	end
	if hash and hash ~= "" then
		ref_cash[hash] = refrence
	end
	return refrence
end

function p.reflist(frame)
	local list = mw.text.split(frame.args.item, " ")
	local s = {}
	for i, j in pairs(list) do
		local item = mw.wikibase.getEntityObject(mw.text.trim(j))
		local str = p.citeitem({mw.text.trim(j)}, item.claims, mw.text.trim(j) .. i, frame.args, "t")
		if str then
			table.insert(s, "*" .. str)
		end
	end
	return table.concat(s, "\n")
end

function p.cite(frame)
	local item = mw.wikibase.getEntityObject(frame.args.item)
	if not item then
		return "no item"
	end
	return p.citeitem({frame.args.item}, item.claims, frame.args.item, frame.args, "t")
end

return p