local yesno = require('Module:Yesno')
local p = {}

local function makeData(args)
	local data = {
		classes = {}
	}

	-- Main table classes
	if yesno(args.metadata) ~= false or yesno(args["البيانات الوصفية"]) ~= false then
		table.insert(data.classes, 'metadata')
	end
	if (args.position and (args.position:lower() == 'right' or args.position == 'يمين')) or (args["المحاذاة"] and (args["المحاذاة"]:lower() == 'right' or args["المحاذاة"] == 'يمين')) then
		table.insert(data.classes, 'side-box-right')
	else
		table.insert(data.classes, 'side-box-left')
	end
	
	if args.collapsible or args["قابلية الطي"] then
		table.insert(data.classes, 'mw-collapsible')
		if args.collapsible == "collapsed" or args["قابلية الطي"] == "collapsed" then
			table.insert(data.classes, 'mw-collapsed')
		end
		data.collapsible = true
	end

	table.insert(data.classes, args.class or args["الصنف"] or '')

	-- Image
	if (args.image and args.image ~= 'none') or (args["الصورة"] and args["الصورة"] ~= 'بدون') then
		data.image = args.image or args["الصورة"]
	end
	
	-- Text class
	if args.textclass == 'plainlist' or not args.textclass or args["صنف النص"] == 'plainlist' or not args["صنف النص"] then
		data.textclass = 'plainlist'
		data.plainlist_templatestyles = 'Plainlist/styles.css'
	else
		data.textclass = args.textclass or args["صنف النص"]
	end

	-- Copy over data that does not need adjusting
	local argsToCopy = {
		'role', 'labelledby', 'style', 'textstyle', 'templatestyles', 
		'above', 'abovestyle', 'text', 'imageleft', 'below'
	}
	local argsArabic = {
		role = "دور",
		labelledby = "معرف",
		style = "طراز",
		textstyle = "طراز النص",
		templatestyles = "أنماط القالب",
		above = "الأعلى",
		abovestyle = "طراز الأعلى",
		text = "النص",
		imageleft = "صورة يسار",
		below = "الأدنى"
	}

	for _, key in ipairs(argsToCopy) do
		data[key] = args[key] or args[argsArabic[key]] or nil
	end

	return data
end

local function renderSidebox(data)
	-- Renders the sidebox HTML.
	local root = mw.html.create('div')
	root:attr('role', data.role)
		:attr('aria-labelledby', data.labelledby)
		:addClass('side-box')
	for i, class in ipairs(data.classes or {}) do
		root:addClass(class)
	end
	if data.style then
		root:cssText(data.style)
	end
	
	local frame = mw.getCurrentFrame()
	if data.plainlist_templatestyles then
		root:wikitext(frame:extensionTag{
			name = 'templatestyles', args = { src = data.plainlist_templatestyles }
		})
	end

	-- The "above" row
	if data.above then
		local above = root:newline():tag('div')
		above:addClass('side-box-abovebelow')
			:newline()
			:wikitext(data.above)
		if data.textstyle then
			above:cssText(data.textstyle)
		end
		if data.abovestyle then
			above:cssText(data.abovestyle)
		end
	end

	-- The body row
	local body = root:newline():tag('div')
		body:addClass('side-box-flex')
			:addClass(data.collapsible and 'mw-collapsible-content')
			:newline()
	if data.image then
		body:tag('div')
			:addClass('side-box-image')
			:wikitext(data.image)
	end
	local text = body:newline():tag('div')
	text:addClass('side-box-text')
		:addClass(data.textclass)
	if data.textstyle then
		text:cssText(data.textstyle)
	end
	text:wikitext(data.text or '')
	if data.imageleft then
		body:newline():tag('div')
			:addClass('side-box-imageleft')
			:wikitext(data.imageleft)
	end

	-- The below row
	if data.below then
		local below = root:newline():tag('div')
		below
			:addClass('side-box-abovebelow')
			:wikitext(data.below)
		if data.textstyle then
			below:cssText(data.textstyle)
		end
	end

	root:newline()
	local templatestyles = ''
	if data.templatestyles then
		templatestyles = frame:extensionTag{
			name = 'templatestyles', args = { src = data.templatestyles }
		}
	end
	return frame:extensionTag{
		name = 'templatestyles', args = { src = 'Module:Side box/styles.css' }
	} .. templatestyles .. tostring(root)
end

function p._main(args)
	local data = makeData(args)
	return renderSidebox(data)
end

function p.main(frame)
	local origArgs = frame:getParent().args
	local args = {}
	for k, v in pairs(origArgs) do
		v = v:match('%s*(.-)%s*$')
		if v ~= '' then
			args[k] = v
		end
	end
	return p._main(args)
end

return p