local p = {}
local data = require('Module:Video game reviews/data')
local yesno = require('Module:Yesno')
local vgwd = require('Module:Video game wikidata')
local getArgs

local function getActiveSystems(args)
	local activeSystems = {}
	for k,v in pairs(args) do
		if data.systems[k] and yesno(v) then
			table.insert
		end
	end
	table.sort(activeSystems, function
		return data.systems[a].sortkey < data.systems[b].sortkey
	end)
	return activeSystems
end

local function getArgKeyTables(args)
	local reviewers, aggregators, awards = {}, {}, {}
	for k in pairs(args) do
		if string.match then
			table.insert
		elseif string.match then
			table.insert
		elseif string.match then
			table.insert
		elseif string.match then
			table.insert
		elseif string.match then
			table.insert
		elseif string.match then
			table.insert
		end
	end
	local function comparator
		return tonumber(a:match('%d+')) < tonumber(b:match('%d+'))
	end
	table.sort
	table.sort
	table.sort
	return reviewers, aggregators, awards
end

local function getProvidedReviewersAndAggregators
	local providedReviewers, providedAggregators = {}, {}
	if usePlatforms then
		local seen = {}
		for k in pairs(args) do
			local splitPos = string.find
			if splitPos then
				local halfarg = string.sub
				if not seen[halfarg] then
					seen[halfarg] = true
					if data.reviewers[halfarg] then
						table.insert
					elseif data.aggregators[halfarg] then
						table.insert
					end
				end
			end
		end
	else
		for k in pairs(args) do
			if not string.find then
				if data.reviewers[k] then
					table.insert
				elseif data.aggregators[k] then
					table.insert
				end
			end
		end
	end
	table.sort(providedReviewers, function
		return data.reviewers[a].sortkey < data.reviewers[b].sortkey
	end)
	table.sort(providedAggregators, function
		return data.aggregators[a].sortkey < data.aggregators[b].sortkey
	end)
	return providedReviewers, providedAggregators
end

local function renderTitleRow
	local titleCell = tbl:tag('tr'):tag('th')

	if title then
		titleCell
	else
		titleCell
	end
end

local function renderMainHeading
	builder:tag('tr'):tag('th')
end

local function renderHeadingRowWithSystems
	renderMainHeading
	builder:tag('tr')
	builder = builder:tag('tr')
	for _,v in ipairs(activeSystems) do
		builder:tag('th'):wikitext(data.systems[v].name)
	end
end

local function renderHeadingRow
	renderMainHeading
	builder
end

local function renderRatingsBySystem
	builder = builder:tag('tr')
	builder:tag('td')

	for _,v in ipairs(activeSystems) do
		local combinedCode = code .. '_' .. v
		local cell = builder:tag('td')
		if args[combinedCode] then
			cell
		elseif na then
			cell
		end
	end
end

local function renderRating
	builder:tag('tr')
end

local function renderReviews
	builder = builder:tag('table')

	local reviewerCount = #providedReviewers + #customReviewerKeys
	local aggregatorCount = #providedAggregators + #customAggregatorKeys
	local reviewScore = data.i18n[reviewerCount == 1 and 'reviewScore' or 'reviewScores']
	local aggregateScore = data.i18n[aggregatorCount == 1 and 'aggregateScore' or 'aggregateScores']
	if #activeSystems ~= 0 then
		builder:wikitext(data.i18n.multiplatformCategory)
		local na = yesno(args.na)
		local showplatforms = #activeSystems ~= 1 or yesno(args.showplatforms)
		if reviewerCount ~= 0 then
			if showplatforms then
				renderHeadingRowWithSystems
			else
				renderHeadingRow
			end

			for _,v in ipairs(providedReviewers) do
				renderRatingsBySystem
			end
			for _,v in ipairs(customReviewerKeys) do
				renderRatingsBySystem
			end
		end
		if aggregatorCount ~= 0 then
			if reviewerCount ~= 0 then
				renderMainHeading
			elseif showplatforms then
				renderHeadingRowWithSystems
			else
				renderHeadingRow
			end

			for _,v in ipairs(providedAggregators) do
				renderRatingsBySystem
			end
			for _,v in ipairs(customAggregatorKeys) do
				renderRatingsBySystem
			end
		end
	else
		builder:wikitext(data.i18n.singleplatformCategory)
		if aggregatorCount ~= 0 then
			renderHeadingRow
			for _,v in ipairs(providedAggregators) do
				renderRating
			end
			for _,v in ipairs(customAggregatorKeys) do
				if (args[v .. '점수'] == nil) then
					renderRating
				else
					renderRating
				end
			end
		end
		if reviewerCount ~= 0 then
			renderHeadingRow
			for _,v in ipairs(providedReviewers) do
				renderRating
			end
			for _,v in ipairs(customReviewerKeys) do
				if (args[v .. '점수'] == nil) then
					renderRating
				else
					renderRating
				end
			end
		end
	end
end

local function renderAwards
	builder = builder:tag('table')
	
	renderMainHeading

	builder:tag('tr')

	for _,v in ipairs(awardKeys) do
		local Pubname = {}
		if (args[v .. '수여'] == nil) then
			Pubname = args[v .. 'Pub']
		else
			Pubname = args[v .. '수여']
		end
		 builder:tag('tr')
	end
end

local function renderMainTable
	local tbl = mw.html.create('table')
			((args.align == 'left' or args.align == 'none') and '0em 1em 1em 0em') or
			'0em 1em 1em 1em')

	if #activeSystems == 0 then
		-- Width: 20% Seems better since it scales with the article size.
		tbl
	end

	if args.title and args.state and (args.state == 'autocollapse'
			or args.state == 'collapsed' or args.state == 'expanded') then
		tbl
	end
	renderTitleRow

	if args.subtitle then
		tbl:tag('tr'):tag('th')
	end

	renderReviews(tbl:tag('tr'):tag('td'), providedReviewers, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, args)
	if #awardKeys ~= 0 then
		renderAwards(tbl:tag('tr'):tag('td'), args, awardKeys, (#customAggregatorKeys ~= 0 or #customReviewerKeys ~= 0 or #providedAggregators ~= 0 or #providedReviewers ~= 0) and 'none' or nil)
	end

	if wikidata == true then
		tbl:tag('tr'):tag('td')
	end

	return tbl
end

local function checkForWikidata
	local wikidata = false
	
	vgwd.setDateFormat(args["df"])
	vgwd.setGame(args["qid"])
	vgwd.setSystem(nil)
	vgwd.setGenerateReferences(true)
	vgwd.setShowUpdateLink(false)
	vgwd.setUpdateLinkStyle("pen")
	vgwd.setSystemFormat(args["systemFormat"])
	
	-- Loop through aggregators if we have any.
	if #providedAggregators ~= 0 then
		for _i,aggr in ipairs(providedAggregators) do
			-- Check if vgwd knows this aggregator.
			if vgwd.setReviewer(aggr) == nil then
				-- Loop through active systems
				if #activeSystems ~= 0 then
					for _j,sys in ipairs(activeSystems) do
						local combinedCode = aggr .. '_' .. sys
						if args[combinedCode] == 'wikidata' then
							vgwd.setSystem(sys)
							vgwd.setShowSystem(false)
							local vgwdScore = vgwd.printReviewScores(frame)
							if vgwdScore then
								args[combinedCode] = vgwdScore
							end
							wikidata = true							
						end
					end			
				else
					vgwd.setShowSystem(true)
		 		if args[aggr] == 'wikidata' then
						local vgwdScore = vgwd.printReviewScores(frame)
						if vgwdScore then
							args[aggr] = vgwdScore
						end
						wikidata = true
					end
				end	
			end
		end
	end

	return wikidata
end

function p._reviewbox
	for k, v in pairs(args) do
		if string.match then
			args.title = v
		elseif string.match then
			args.subtitle = v
		elseif string.match then
			args.status = v
		elseif string.match then
			args.width = v
		elseif string.match then
			args.align = v
		end
	end

	local activeSystems = getActiveSystems(args)
	local customReviewerKeys, customAggregatorKeys, awardKeys = getArgKeyTables(args)
	local providedReviewers, providedAggregators = getProvidedReviewersAndAggregators
	local wikidata = checkForWikidata
	if #customAggregatorKeys ~= 0 or #customReviewerKeys ~= 0 or #providedAggregators ~= 0 or #providedReviewers ~= 0 or #awardKeys ~= 0 then
		return renderMainTable
	elseif mw.title.getCurrentTitle.namespace == 0 then
		return data.i18n.emptyCategory
	end
end

function p.reviewbox(frame)
	if not getArgs then
		getArgs = require('Module:Arguments').getArgs
	end
	return p._reviewbox(frame, getArgs)
end