local MessageBox = require("Module:Message box")
local yesno = require("Module:Yesno")

local p = {}

local function demoCheck(args)
	return yesno(args["demo"]) or yesno(args["nocat"])
end

local function showWarning(text, nocat)
	mw.addWarning(text)
	return nocat and "" or "[[Category:Pages with split article warnings]]"
end

local function delink(text)
	if text == nil then
		return nil
	end
	return string.gsub(string.gsub(require("Module:Delink")._delink{text}, "%[%[", ""), "%]%]", "")
end

local function showError(text, nocat)
	return string.format(
		"%s%s %s",
		nocat and "" or "[[Category:Pages with split article errors]] ",
		tostring(
			mw.html.create("span")
				:css("color", "red")
				:css("font-weight", "bold")
				:wikitext("Error:")
		),
		text
	)
end

local function singleText(args)
	local text = ""
	-- from1 also included in case someone filed the template improperly
	local from = delink(args["from"] or args["from1"]) or mw.title.getCurrentTitle().subjectPageTitle.prefixedText
	local fromTalk = mw.title.new(from).talkPageTitle.prefixedText
	
	if args["from1"] then
		text = text .. showWarning(
			"<code>from</code> is not a row-based parameter. Use <code>from</code> instead of <code>from1</code>.",
			demoCheck(args)
		)
	end
	
	-- Row-based parameters
	local to = delink(args["to"] or args["to1"])
	local diff = args["diff"] or args["diff1"]
	local date = args["date"] or args["date1"]
	local from_oldid = args["from_oldid"] or args["from_oldid1"]
    if to == nil then
    	return showError("Target page was not specified with <code>to</code>.", demoCheck(args))
	end
	if date == nil then
		text = text .. showWarning("Split date was not specified with <code>date</code>. This may cause an error in the future.", demoCheck(args))
	end
	
	text = string.format("Material from [[%s]] was split to [[%s]]", from, to, date)
	if diff ~= nil and date ~= nil then
		if diff:match("^[0123456789/]+$") then
			text = string.format("%s on [[Special:Diff/%s|%s]]", text, diff, date)
		else
			text = string.format("%s on [%s %s]", text, diff, date)
		end
	elseif date ~= nil then
		text = string.format("%s on %s", text, date)
	end
	
	if from_oldid ~= nil then
		if from_oldid:match("^[0123456789/]+$") then
			text = string.format("%s from [[Special:Diff/%s|this version]]", text, from_oldid)
		else
			text = string.format("%s from [%s this version]", text, from_oldid)
		end
	end
	text = string.format(
		"%s. The former page's [[Special:PageHistory/%s|history]] now serves to "..
		"[[Wikipedia:Copying within Wikipedia|provide attribution]] for that content "..
		"in the latter page, and it must not be deleted so long as the latter page "..
		"exists. Please leave this template in place to link the article histories "..
		"and preserve this attribution.", 
		text, from
	)
	
	if fromTalk ~= mw.title.getCurrentTitle().prefixedText then
		 text = string.format(
		 	"%s The former page's talk page can be accessed at [[%s]].",
		 	text, fromTalk
	 	)
	end
	
	return text
end

local function row(args, i)
	local to = delink(args["to" .. i] or (i == 1 and args["to"] or nil))
	local toTalk = mw.title.new(delink(to)).subjectPageTitle.prefixedText
	local diff = args["diff" .. i] or (i == 1 and args["diff"] or nil)
	local date = args["date" .. i] or (i == 1 and args["date"] or nil)
	local from_oldid = args["from_oldid" .. i] or (i == 1 and args["from_oldid"] or nil)
	if date == nil then
		text = text .. showWarning(string.format(
			"Split date for \"%s\" (<code>to%s</code>) was not specified with <code>date</code>. This may cause an error in the future.",
			to, i
		), demoCheck(args))
	end
	
	local rowText = string.format(
		"[[%s]] ([[%s|talk]] | [[Special:PageHistory/%s|history]])",
		to, toTalk, to, date, diff
	)
	if diff ~= nil and date ~= nil then
		if diff:match("^[0123456789/]+$") then
			rowText = string.format("%s on [[Special:Diff/%s|%s]]", rowText, diff, date)
		else
			rowText = string.format("%s on [%s %s]", rowText, diff, date)
		end
	elseif date ~= nil then
		rowText = string.format("%s on %s", rowText, date)
	end
	if from_oldid ~= nil then
		if from_oldid:match("^%d+$") then
			rowText = string.format("%s from [[Special:Diff/%s|this version]]", rowText, from_oldid)
		else
			rowText = string.format("%s from [%s this version]", rowText, from_oldid)
		end
	end
	
	return mw.html.create("li"):wikitext(rowText)
end

local function multiText(args)
	local text = ""
	-- from1 also included in case someone filed the template improperly
	local from = delink(args["from"] or args["from1"]) or mw.title.getCurrentTitle().subjectPageTitle.prefixedText
	local fromTalk = mw.title.new(delink(from)).talkPageTitle.prefixedText
	local collapse = tonumber(args["collapse"]) or yesno(args["collapse"])
	if args["from1"] then
		text = text .. showWarning(
			"<code>from</code> is not a row-based parameter. Use <code>from</code> instead of <code>from1</code>.",
			demoCheck(args)
		)
	end
	if args["from_oldid1"] then
		text = text .. showWarning(
			"<code>from_oldid</code> is not a row-based parameter. Use <code>from_oldid</code> instead of <code>from_oldid1</code>.",
			demoCheck(args)
		)
	end
	
	text = string.format(
		"Material from [[%s]] was split to other pages. The former page's "..
		"[[Special:PageHistory/%s|history]] now serves to "..
		"[[Wikipedia:Copying within Wikipedia|provide attribution]] for that content "..
		"in the latter pages, and it must not be deleted so long as the latter pages "..
		"exist. Please leave this template in place to link the article histories "..
		"and preserve this attribution.", from, from
	)
	
	local ul = mw.html.create("ul")
	local ul2
	local target = ul
	
	-- Row-based parameters
	local i = 1
	while args["to" .. i] or (i == 1 and args["to"]) do
		-- Swap out ul with collapsible table if collapsible
		if collapse == true and i == 1 then
			-- Only on first run
			target = mw.html.create("table")
				:attr("class", "mw-collapsible mw-collapsed")
				:attr("style", "width:100%; background-color: var( --background-color-warning-subtle, #fdf2d5 ); color: inherit;")
				:node(mw.html.create("tr")
					:node(mw.html.create("th")
						:wikitext("Page splits")
					)
				)
				:node(mw.html.create("td"):node(ul))
		elseif collapse == (i - 1) then
			ul2 = ul
			ul = mw.html.create("ul")
			-- Only once threshold has been reached
			target = mw.html.create("table")
				:attr("class", "mw-collapsible mw-collapsed")
				:attr("style", "width:100%; background-color: var( --background-color-warning-subtle, #fdf2d5 ); color: inherit;")
				:node(mw.html.create("tr")
					:node(mw.html.create("th")
						:wikitext("Other page splits")
					)
				)
				:node(mw.html.create("tr")
					:node(mw.html.create("td"):node(ul))
				)
		end
		
		ul:node(row(args, i))
		i = i + 1
	end
	
	if fromTalk ~= mw.title.getCurrentTitle().prefixedText then
		 text = string.format(
		 	"%s The former page's talk page can be accessed at [[%s]].",
		 	text, fromTalk
	 	)
	end
	
	text = text .. " " .. tostring(ul2 or "") .. tostring(target)
	
	return text
end

local function bannerText(args)
	-- Checks if there are multiple rows
	local text
	if args["to2"] ~= nil and ((args["to1"] or args["to"]) ~= nil) then
		text = multiText(args) --.. categories(args,true)
	else
		text = singleText(args) --.. categories(args,false)
	end
	return text
end

function p.renderBanner(args)
	return MessageBox.main('tmbox', {
		name = "split-article",
		small = args["small"],
		image = '[[File:Split-arrows.svg|50px]]',
		text = bannerText(args)
	})
end

function p.main(frame)
	local getArgs = require('Module:Arguments').getArgs
	local args = getArgs(frame, {
		trim = true,
		removeBlanks = true
	})
	return p.renderBanner(args)
end

return p