local titleSelf = mw.title.new(... or mw.getCurrentFrame():getTitle())
local titleCountryData = mw.title.new [[Module:CountryData]]
local sandbox = titleSelf.subpageText:match [[^ملعب]]
--if titleSelf.isSubpage then
--if sandbox then
--titleCountryData = titleCountryData:subPageTitle(sandbox)
--end
--end
local CountryData = require(tostring(titleCountryData))
local p = {}

function p.main(frame)
	--Get input arguments
	local args =
		require("Module:Arguments").getArgs(
			frame,
			{
				valueFunc = function(key, value)
					if value then
						value = mw.text.trim(value)
						--Change empty string to nil for all args except 'image' and 'border'
						if key == "image" or key == "border" or value ~= "" then
							return value
						end
					end
					return nil
				end
			}
		)

	--Call main function
	return p.luaMain(frame, args)
end

function getcachedtable(frame, countryDataCountry, apar)
	-- return CountryData.getcachedtable(frame, countryDataCountry, apar)
	return CountryData.gettable(frame, countryDataCountry, apar)
end

function p.luaMain(frame, args)
	local function emp2nil(x)
		if x == "" then
			return nil
		else
			return x
		end
	end
	local function space2emp(x)
		if string.find(x, "^%s*$") then
			return ""
		else
			return x
		end
	end
	local function nopx(x)
		if x ~= nil and (string.find(x, "^%d+$") or string.find(x, "^%d+px$")) then
			return string.gsub(x, "^(.*)px", "%1")
		else
			return nil
		end
	end

	--Country & mode parameters
	local mode = string.lower(args[1] or "usc")
	local mi = string.sub(mode, 1, 1)
	local ms = string.sub(mode, 2, 2)
	local mn = string.sub(mode, 3, 3)
	local me = string.sub(mode, 4, -1)

	local country = args[2] or ""
	local countryDataCountry = country
	if string.find(me, "i") then
		local titleIocCountryData = mw.title.new [[Module:Country alias/data]]
		local IocCountryData = require(tostring(titleIocCountryData))
		local iocCountryAlias = IocCountryData.countryAliases[country] or country
		countryDataCountry =
			IocCountryData.countries[iocCountryAlias]["countrydata_name"] or
			IocCountryData.countries[iocCountryAlias]["name"]
	end

	local find = require("Module:تحويلات بلدان").red -- Just in Arabic
	country = find(country) or ""

	local avar = args["avar"] or args["altvar"]
	local clink = args["clink"] or args["link"]

	--Get country data & altvar data
	local data, alink, amap, asuf, apre
	if avar then
		local age = args["age"] or ""
		local aalias
		amap, aalias = require("Module:Flagg/Altvar data" .. ((sandbox and "/ملعب") or "")).alttable(age)
		avar = string.gsub(string.lower(avar or ""), "[ -]", "")
		avar = aalias[avar] or avar
		if not amap[avar] then
			error("Unknown avar")
		end
		local apar = {
			altvar = amap[avar].altvar,
			mw = amap[avar].mw,
			age = amap[avar].age,
			variant = args["variant"] or args[3]
		}
		data = getcachedtable(frame, countryDataCountry, apar)
		asuf = amap[avar].altlink
		apre = amap[avar].linkpre
		alink =
			data["link alias-" .. amap[avar].altvar] or
			(apre or '') .. " " .. (clink or data["shortname alias"] or data.alias or country) .. " " .. asuf
	else
		data =
			(args["nodata"] and {}) or
			getcachedtable(frame, countryDataCountry, { variant = args["variant"] or args[3] })
		avar = ""
		amap = { [""] = { altvar = "" } }
	end

	--Name and link parameters
	clink = clink or data.alias or country

	local pref = args["pref"]
	local suff = args["suff"] or asuf
	local pref2 = args["pref2"]
	local suff2 = args["suff2"]
	if not pref and not suff then --Default prefix
		pref = "علم"
	end
	local yn_map = { [""] = 0, ["0"] = 0, ["no"] = 0, ["n"] = 0, ["1"] = 1, ["yes"] = 1, ["y"] = 1 }
	local fthe = (args["pthe"] and yn_map[args["pthe"]] ~= 0) or (args["the"] and yn_map[args["the"]] ~= 0)
	local nthe = (args["nthe"] and yn_map[args["nthe"]] ~= 0) or (args["the"] and yn_map[args["the"]] ~= 0)
	-- fthe = fthe and (pref and "t" or "T") .. "he " or ""
	-- nthe = nthe and (pref and "t" or "T") .. "he " or ""
	fthe = fthe and (pref and "ا" or "ا") .. "ل " or ""
	nthe = nthe and (pref and "ا" or "ا") .. "ل " or ""
	local flink =
		args["plink"] or args["flink"] or alink or clink == "" and "" or
		space2emp((pref or "") .. " ") .. fthe .. clink .. space2emp(" " .. (suff or ""))
	local flink2
	if args["plink2"] or args["flink2"] or pref2 or suff2 then
		flink2 =
			args["plink2"] or args["flink2"] or clink == "" and "" or
			space2emp((pref2 or "") .. " ") .. fthe .. clink .. space2emp(" " .. (suff2 or ""))
	else
		flink2 = flink
	end
	local fsec = args["psection"] or args["section"]
	local fsec2 = args["psection2"] or args["section"]
	local csec = args["csection"] or args["section"]
	fsec = fsec and "#" .. fsec or ""
	fsec2 = fsec2 and "#" .. fsec2 or ""
	csec = csec and "#" .. csec or ""

	if string.find(me, "f") then
		if mw.title.new(flink).exists == false then
			if flink2 ~= flink and mw.title.new(flink2).exists == true then
				flink = flink2
				fsec = fsec2
			else
				flink = clink
			end
		end
	end

	local name = args["name"]
	if not name then
		local cname =
			string.find(me, "e") and (data["name alias-" .. amap[avar].altvar] or data["shortname alias"] or data.alias) or
			country
		if mn == "f" then
			name =
				cname == "" and "" or space2emp((pref or "") .. " ") .. nthe .. cname .. space2emp(" " .. (suff or ""))
		else
			name = cname
		end
	end

	--Image parameters
	local pimage = args["image"]
	local placeholder = "Flag placeholder.svg"
	local variant = args["variant"] or args[3] or ""
	local image_map = { [""] = placeholder, ["none"] = placeholder, ["blank"] = placeholder }
	if pimage then --Remove namespace
		pimage = string.gsub(pimage, "^[Ff][Ii][Ll][Ee]:", "")
		pimage = string.gsub(pimage, "^[Ii][Mm][Aa][Gg][Ee]:", "")
	end
	local iname = image_map[pimage] or pimage

	local size = args["size"] or args["sz"]
	local size_map = { xs = "12x8px", s = "17x11px", m = "23x15px", l = "32x21px", xl = "46x30px" }
	if size == nil or string.find(size, "^%d*x?%d+px$") then
		--valid EIS size ( .. px, x .. px or .. x .. px) or unset
	elseif string.find(size, "^%d*x?%d+$") then --EIS size without "px" suffix
		size = size .. "px"
	else                                     --size from map, or invalid value
		size = size_map[size] or nil
	end
	local border = args["border"]

	if iname then
		size = size or "23x15px"
		if yn_map[border] == 0 then
			border = ""
		else
			border = "|border"
		end
	else
		iname =
			data["flag alias-" .. amap[avar].altvar .. "-" .. variant] or data["flag alias-" .. variant] or
			data["flag alias-" .. amap[avar].altvar] or
			data["flag alias"] or
			placeholder
		size = size or emp2nil(data.size) or "23x15px"
		if border then
			if yn_map[border] == 0 then
				border = ""
			else
				border = "|border"
			end
		else
			local autoborder = data["border-" .. variant] or data["border-" .. amap[avar].altvar] or data.border
			if autoborder and autoborder ~= "border" then
				border = ""
			else
				border = "|border"
			end
		end
	end

	local am = ""
	if args["alt"] or string.find(me, "a") then
		am = args["alt"] or args["name"] or country
		am = am .. "|" .. am
	end

	--Build display name
	local text = args["text"]
	if not text then
		if mn == "x" then                         --no text
			text = ""
		elseif mn == "p" or mn == "f" or mn == "*" then --prefix/suffix link
			text = flink == "" and name or "[[" .. flink .. fsec .. "|" .. name .. "]]"
			-- By the principle of least surprise, there should be some
			-- indication that the link [[X of Country|Country]] does not
			-- go to [[Country]].
			if mn == "*" and clink ~= flink then
				text = text:sub(1, -3) .. "\226\128\175*]]"
			end
		elseif mn == "l" then --display link target
			text = flink == "" and name or "[[" .. flink .. fsec .. "|" .. (args["name"] or flink) .. "]]"
		elseif mn == "b" then --both prefix/suffix and normal country link
			local preflink =
				pref and (flink == "" and pref .. " " or "[[" .. flink .. fsec .. "|" .. pref .. "]] ") or ""
			local sufflink =
				suff and (flink == "" and " " .. suff or " [[" .. flink .. fsec .. "|" .. suff .. "]]") or ""
			local namelink =
				(name == "" and "" or nthe) .. (clink == "" and name or "[[" .. clink .. csec .. "|" .. name .. "]]")
			text = preflink .. namelink .. sufflink
		elseif mn == "d" then --data template
			local title = mw.title.new("Template:بيانات بلد " .. country)
			--check if redirect
			if title.isRedirect then
				text = '<span class="plainlinks">[' .. title:fullUrl("redirect=no") .. " " .. name .. "]</span>"
			else
				text = "[[" .. title.fullText .. "|" .. name .. "]]"
			end
		elseif mn == "u" then --unlinked
			text = name
		elseif mn == "a" then --abbr
			text =
				name == country and
				(clink == country and country or "<abbr title='" .. clink .. "'>" .. country .. "</abbr>") or
				("<abbr title='" .. name .. "'>" .. country .. "</abbr>")
		else --country link (default)
			text = clink == "" and name or "[[" .. clink .. csec .. "|" .. name .. "]]"
		end
		if string.find(me, "p") then
			text = "(" .. text .. ")"
		end
	end

	if type(text) == "function" then
		text = text(data)
	end

	--Define separator
	local separator = "&nbsp;" --non-breaking space (n)
	if ms == "x" then       --no separator
		separator = ""
	elseif ms == "l" then   --line break
		separator = "<br/>"
	end

	--Add preftext, if used
	local preftext = args["preftext"]
	if (preftext or "") ~= "" then
		text = preftext .. separator .. text
	end

	--Build image
	local ilink = args["ilink"]
	if not ilink then
		if mi == "x" or (iname == placeholder and pimage ~= placeholder) then --no image/invisible image
			iname = placeholder
			border = ""
			ilink = "|link="
			am = ""
		elseif mi == "i" then        --image page link
			ilink = ""
		elseif mi == "c" then        --country link
			ilink = "|link=" .. clink .. (clink == "" and "" or csec)
		elseif mi == "p" or mi == "f" then --prefix/suffix link
			ilink = "|link=" .. flink .. (flink == "" and "" or fsec)
		elseif mi == "d" then        --data template
			local title = mw.title.new("Template:بيانات بلد " .. country)
			--check if redirect
			if title.isRedirect then
				ilink = "|link=" .. title:fullUrl("redirect=no")
			else
				ilink = "|link=" .. title.fullText
			end
		else --unlinked (default)
			ilink = "|link="
		end
	end
	if am == "" and string.find(me, "l") then
		am = mw.ustring.sub(ilink, 7, -1)
	end
	local image = "[[ملف:" .. iname .. "|" .. size .. border .. ilink .. "|alt=" .. am .. "]]"

	if iname == placeholder then
		if require("Module:yesno")(args["noredlink"]) == false or args["noredlink"] == "notext" then
			if country ~= "" and data.alias == nil then
				iname = ""
				image = "[[:Template:بيانات بلد " .. country .. "]]"
				if args["noredlink"] == "notext" then
					text = ""
				end
			end
		end
		if (args["missingcategory"] or "") ~= "" then
			image = image .. args["missingcategory"]
		end
		if string.find(me, "b") then
			text = ""
		end
	end

	--Combine image and name with separator
	local align_map = {
		left = "left",
		l = "left",
		center = "center",
		centre = "center",
		c = "center",
		middle = "center",
		m = "center",
		right = "right",
		r = "right"
	}
	local align = align_map[args["align"] or args["al"]]
	local nalign = align_map[args["nalign"] or args["nal"]]
	local out
	if string.find(me, "r") then
		--image right of name
		if (ms == "x" and mi == "x") or (string.find(me, "o") and iname == placeholder and pimage ~= placeholder) then --name only
			out = text
		elseif ms == "x" or ms == "n" or ms == "l" then                                                          --no separator, non-breaking space, or line break
			out = text .. '<span class="flagicon">' .. separator .. image .. "</span>"
		elseif ms == "t" then                                                                                    --table cell
			out =
				'style="text-align:' ..
				(nalign or "left") ..
				'"|' ..
				text ..
				'||style="text-align:' ..
				(align or "center") .. '"|<span class="flagicon">' .. image .. "</span>"
		else --fixed-width span box (default)
			local width = args["width"] or args["w"] or require("Module:Flaglist").luawidth(size)
			out =
				text ..
				'&nbsp;<span class="flagicon" style="display:inline-block;width:' ..
				width .. "px;text-align:" .. (align or "right") .. ';">' .. image .. "</span>"
		end
	else                                                                                                         --image left of name
		if (ms == "x" and mi == "x") or (string.find(me, "o") and iname == placeholder and pimage ~= placeholder) then --name only
			out = text
		elseif ms == "x" or ms == "n" or ms == "l" then                                                          --no separator, non-breaking space, or line break
			out = '<span class="flagicon">' .. image .. separator .. "</span>" .. text
		elseif ms == "t" then                                                                                    --table cell
			out =
				'style="text-align:' ..
				(align or "center") ..
				';"|<span class="flagicon">' ..
				image .. '</span>||style="text-align:' .. (nalign or "left") .. '"|' .. text
		else --fixed-width span box (default)
			local width = nopx(args["width"] or args["w"]) or require("Module:Flaglist").luawidth(size)
			out =
				'<span class="flagicon" style="display:inline-block;width:' ..
				width .. "px;text-align:" .. (align or "left") .. ';">' .. image .. "</span>&nbsp;" .. text
		end
	end
	if string.find(me, "w") then --avoid wrapping
		out = '<span class="nowrap">' .. out .. "</span>"
	end

	-- align in table
	if me:find("t") then
		out = 'style="text-align:' .. (align or "left") .. '"|' .. out
	end

	--Tracking categories
	local cat = ""
	if pimage and not image_map[pimage] and country ~= "" and data["flag alias"] and not args.demo then
		cat = "[[تصنيف:صفحات تستخدم قالب Flagg بصورة محددة]]"
	end

	return out .. cat
end

return p