---@diagnostic disable: undefined-global
local p = {}
local options = {}
local Frame
local RTL = "‏"
local Category = {}
Category["remove"] = " [[تصنيف:صفحات بها وصلات للإزالة]]"
Category["review"] = " [[تصنيف:وصلات إنترويكي بحاجة لمراجعة|%s]]"
Category["nositelinks"] = " [[تصنيف:صفحات بها قالب:Ill-WD2 دون وصلات لغات|%s]]"
Category["add"] = "[[تصنيف:صفحات بها وصلات إنترويكي|%s]]"

function isvalid(x)
	if x and x ~= "" then
		return x
	end
	return nil
end

function debug(msg)
	if isvalid(options.debug) then
		mw.log("Module:Ill-WD2: " .. msg)
	end
end

function countSiteLinks()
	local numb = 0
	local entity = mw.wikibase.getEntityObject(options.id)
	if entity and entity.sitelinks then
		for i, v in pairs(entity.sitelinks) do
			numb = numb + 1
		end
	end
	return numb
end

function sitelink(site)
	local site = site or "arwiki"
	local link = mw.wikibase.sitelink(options.id, site) or ""
	debug("mw.wikibase.sitelink : " .. link)
	return link
end

function labelIn(langcode)
	local label, lange = mw.wikibase.getLabelWithLang(options.id)
	if lange == langcode then
		return label
	end
	debug("label = " .. (label or "") .. "lange = " .. (lange or "") .. "langcode = " .. langcode)
	return ""
end

function makeCategory(key)
	if key ~= "add" and isvalid(options.nocat) then
		return ""
	end
	return Category[key]
end

function make_noy_text(str, langcode)
	if not isvalid(options.noy) then
		return str
	end

	local prefix = langcode == "ar" and "" or "^"
	local suffix = langcode == "ar" and "$" or ""

	local ca = str:gsub(prefix .. "%d%d%d%d[–-]%d%d%d%d%s*" .. suffix, "")
	ca = ca:gsub(prefix .. "%d%d[–-]%d%d%d%d%s*" .. suffix, "")
	ca = ca:gsub(prefix .. "%d%d%d%d[–-]%d%d%s*" .. suffix, "")
	ca = ca:gsub(prefix .. "%d%d%d%d%s*" .. suffix, "")

	debug("ca: " .. ca)
	return ca
end

function maketext(String)
	if isvalid(options.text) then
		debug("text: " .. options.text)
		return options.text
	end

	local String2 = mw.ustring.gsub(String, "–", "-")

	if isvalid(options.year) then
		return mw.ustring.match(String2, "%d%d%d%d[%–-]%d%d%d%d%s*$", 1) or
			mw.ustring.match(String2, "%d%d[%–-]%d%d%d%d%s*$", 1) or
			mw.ustring.match(String2, "%d%d%d%d[%–-]%d%d%s*$", 1) or
			mw.ustring.match(String2, "%d%d%d%d%s*$", 1) or
			mw.ustring.match(String2, "^%d%d%d%d[%–-]%d%d%d%d%s", 1) or
			mw.ustring.match(String2, "^%d%d[%–-]%d%d%d%d%s", 1) or
			mw.ustring.match(String2, "^%d%d%d%d[%–-]%d%d%s", 1) or
			mw.ustring.match(String2, "^%d%d%d%d%s", 1) or
			String
	end

	if isvalid(options.noy) then
		local ca = make_noy_text(String, "ar")
		return ca == String and make_noy_text(String, "en") or ca
	end

	return String
end

function make_suffix(target_Site, target_Link, sitelinks_count)
	if sitelinks_count == 0 and not isvalid(options.from_lua) then
		return string.format(makeCategory("nositelinks"), options.id)
	end

	local other_lang = """ .. options.id .. "" في لغات أخرى"
	other_lang = '<sup class=reference title="' .. other_lang .. '">[لغات أخرى]</sup>'

	local other_lang_text = "&nbsp;[[d:" .. options.id .. "#sitelinks-wikipedia|" .. other_lang .. "]]"

	local suff =
		mw.text.tag(
		"span",
		{
			class = "noprint",
			style = "font-size: smaller; font-style: normal; font-weight: normal;"
		},
		other_lang_text
	)

	if isvalid(target_Link) and isvalid(target_Site) then
		local language = Frame:callParserFunction("#language", target_Site, "ar")
		suff =
			"[[:" ..
			target_Site ..
				":" .. target_Link .. '|<sup class=reference title="' .. target_Link .. '">[' .. language .. "]</sup>]]"
	end

	local suffe = "&nbsp;" .. suff
	local text = isvalid(options.from_lua) and string.format(makeCategory("add"), options.id) or ""

	return suffe .. text
end

function make_ar_link(title, suffix, sitelinks_count)
	local text = maketext(title)
	local link
	local tit = mw.title.new(title)
	local cate = isvalid(options.from_lua) and string.format(makeCategory("review"), options.id) or ""

	if sitelinks_count == 0 then
		link = text .. suffix
	elseif tit and tit.exists then
		debug(cate)
		link = text .. suffix .. cate
		mw.log('review "' .. title .. '", id: ' .. options.id)
	else
		title = mw.ustring.gsub(title, "^تصنيف:", "")
		text = mw.ustring.gsub(text, "^تصنيف:", "")
		link = "[[" .. title .. "|" .. text .. "]]" .. suffix
	end

	debug("link: " .. link)
	return link
end

function argument_wrapper(frame)
	local args = frame.args
	-- merge args with frame:getParent().args
	for k, v in pairs(frame:getParent().args) do
		if args[k] == nil or args[k] == "" then
			args[k] = v
		end
	end

	local origin = {}
	local aliases = {
		["debug"] = {"debug"},
		["en_label"] = {"enlabel"},
		["use_en_target"] = {"en"},
		["id"] = {"المعرف", "id", 2},
		["label"] = {"label", 1},
		["target"] = {"target", "لغ"},
		["nocat"] = {"nocat"},
		["noy"] = {"noy"},
		["year"] = {"y"},
		["text"] = {"text", "نص"},
		["from_lua"] = {"fromlua"}
	}

	-- iterate over the aliases table
	for k, v in pairs(aliases) do
		for _, alias in ipairs(v) do
			if args[alias] and args[alias] ~= "" then
				mw.log("Module:Ill-WD2: alias: " .. alias .. ": for " .. k)
				origin[k] = args[alias]
				break
			end
		end
		origin[k] = origin[k] or ""
	end

	-- return the new table with the original argument names
	return origin
end

function p.link(frame)
	options = argument_wrapper(frame)
	Frame = frame:getParent()

	local id = options.id
	if not isvalid(id) then
		return "No ID"
	end

	local target = options.target
	if isvalid(options.use_en_target) then
		target = "en"
	end
	local en_label = options.en_label or (target == "en" and labelIn("en"))
	local target_SiteLink = isvalid(target) and sitelink(target .. "wiki") or ""
	local SiteLink = mw.wikibase.sitelink(id)
	local sitelinks_count = countSiteLinks()

	if SiteLink then
		local Link = "[[" .. SiteLink .. "|" .. maketext(SiteLink) .. "]]"
		mw.log("remove: " .. id)
		return Link .. makeCategory("remove") .. RTL
	end
	local suffix = make_suffix(target, target_SiteLink, sitelinks_count)

	local ar_label = labelIn("ar")
	local ar_link = isvalid(options.label) and options.label or (isvalid(ar_label) and ar_label)

	if isvalid(ar_link) then
		debug("ar_link : " .. ar_link)
		return make_ar_link(ar_link, suffix, sitelinks_count) .. RTL
	elseif isvalid(en_label) then
		debug("en_label " .. en_label)
		return maketext(en_label) .. make_suffix("", "", sitelinks_count) .. RTL
	elseif isvalid(target) and isvalid(target_SiteLink) then
		debug("target " .. target .. ": " .. target_SiteLink)
		return maketext(target_SiteLink) .. suffix .. RTL
	else
		debug("nothing en_label: " .. en_label)
		return ""
	end
end

return p