-- This module handles demonstration and list of possible values for all storm
-- category templates! Please test this module on Module:Storm categories/demo/doc
-- before publishing to avoid errros. Thank you!
--
local colorRatio = require("Module:Color contrast")._ratio
local TableTools = require("Module:TableTools")
local stormcats = require("Module:Storm categories")
local cats = require("Module:Storm categories/categories").cats
local colors = require("Module:Storm categories/colors").colors
local icons = require("Module:Storm categories/icons").icons
local p = {}

local customKeys = {}
for k, v in pairs(colors) do
	table.insert
end
for k, v in pairs(icons) do
	table.insert
end
TableTools.removeDuplicates(customKeys)

function tableEmpty(_table)
	for k, v in pairs(_table) do
		return false
	end
	return true
end

--- Generates and renderds the demo table.
-- @param frame The Scribunto frame.
function p.demo(frame)
	local plain = (frame.args["plain"] or frame:getParent.args["plain"] or "") ~= ""
	local verbose = (frame.args["verbose"] or frame:getParent.args["verbose"] or "") ~= ""
	
	local legend = setmetatable
	local errors = setmetatable
	local warnings = setmetatable
	
	--- Builds the entire reflist
	-- @param _group The group to build for. Uses `legend` by default.
	function buildReflist(_group)
		group = _group or legend
		return frame:expandTemplate{ title = 'reflist', args = {
			group = getmetatable(group)["refgroupname"]
	end
	
	--- Returns a single  tag containing the legend provided and
	-- attaches the note definition to the list of notes.
	-- @param details The details of the legend.
	-- @param _group The group to write in. Uses `legend` by default.
	function createLegend
		hash = string.sub(mw.hash.hashValue, 0, 8)
		group = _group or legend
		if group[hash] == nil then
			group[hash] = plain and "" or frame:extensionTag{ 
				-- 
				name = 'ref',
				content = mw.ustring.gsub(details, "%[%[File:([^%|]+)[^%]]*%]%]", ":File:%1"),
				args = { 
					name = hash, 
					group = getmetatable(group)["refgroupname"]
		end
		
		-- 
		return plain and "" or frame:extensionTag{ name = 'ref', args = { 
			name = hash,
			group = getmetatable(group)["refgroupname"]
	end
	
	--- Checks for color contrast issues and tags accordingly.
	-- Returns the refernce tag, so this should be used in conjunction with an
	-- HTML node's :wikitext function.
	function contrastCheck(color)
		local catColorBlackRatio = colorRatio
		local catColorLinkRatio = colorRatio
		local catColorVisitedLinkRatio = colorRatio
		
		local finalWikitext = ""
		if catColorBlackRatio == "?" or catColorLinkRatio == "?" or catColorVisitedLinkRatio == "?" then
			finalWikitext = finalWikitext ..
				createLegend
		else
			if catColorBlackRatio < 4.5 then
				finalWikitext = finalWikitext ..
					createLegend("This color has contrast issues with black (not WCAG 2.0 AA-compatible). It will be unusable on all infoboxes and storm season summaries.", errors)
			end
			if catColorLinkRatio < 4.5 then
				finalWikitext = finalWikitext ..
					createLegend("This color has contrast issues with links (not WCAG 2.0 AA-compatible). It should not be used in conjunction with a link.", warnings)
			end
			if catColorVisitedLinkRatio < 4.5 then
				finalWikitext = finalWikitext ..
					createLegend("This color has contrast issues with visited links (not WCAG 2.0 AA-compatible with #0b0080). It should not be used in conjunction with a visited link.", warnings)
			end
			if actualCat == "c0c0c0" and cat[sortkey] ~= 0 then
				finalWikitext = finalWikitext ..
					createLegend
			end
		end
		return finalWikitext
	end
	
	function colorInfo
		local catColorBlackRatio = colorRatio
		local catColorLinkRatio = colorRatio
		local catColorVisitedLinkRatio = colorRatio
		
		local nc = tostring(mw.html.create("abbr")
		);
		local aa = tostring(mw.html.create("abbr")
		);
		local aaa = tostring(mw.html.create("abbr")
		);
		
		function contrastLevel(contrast)
			return contrast >= 7 and aaa or (contrast >= 4.5 and aa or nc)
		end
		
		return mw.html.create("td")
				"#" .. color .. (extra or "") .. contrastCheck(color) .. (verbose and (""
				.. tostring(
					mw.html.create("abbr")
				) .. ": " .. string.format .. " (" .. contrastLevel(catColorBlackRatio) .. ")"
				.. tostring(
					mw.html.create("abbr")
				) .. ": " .. string.format .. " (" .. contrastLevel(catColorLinkRatio) .. ")"
				.. tostring(
					mw.html.create("abbr")
				) .. ": " .. string.format .. " (" .. contrastLevel(catColorVisitedLinkRatio) .. ")") or "")
			)
	end
	
	local categoryTable = mw.html.create("table")
		
	categoryTable
			mw.html.create("tr")
		):node(
			mw.html.create("tr")
		)
	
	for name, cat in TableTools.sortedPairs(cats) do
		local rows = { mw.html.create("tr") }
		local row = rows[1]
		
		local actualIcon = stormcats._icon(name)
		local icon = mw.html.create("td")
		if cat["icon"] ~= nil and actualIcon ~= cat["icon"] then
			icon:wikitext(
				createLegend("Overriden from original icon (" .. cat["icon"] .. ")")
			)
		end
			
		local id = mw.html.create("td")
		local actualColor = stormcats._color(name)
		local colorPreview = mw.html.create("td")
		local color = colorInfo(
			actualColor,
			verbose,
			actualColor ~= cat["color"] and createLegend(
				"Overriden from original color ( #"
				.. cat["color"]
				.. ")"
			) or ""
		):css:css
		
		local sortkeyCategory = mw.html.create("td")
		local sortkey = mw.html.create("td")
			
		if cat["sortkey"] < 0 then
			sortkeyCategory:wikitext("Invalid")
		elseif cat["sortkey"] < 20000 then
			sortkeyCategory:wikitext("Global")
		elseif cat["sortkey"] < 30000 then
			sortkeyCategory:wikitext("Historical")
		elseif cat["sortkey"] < 40000 then
			sortkeyCategory:wikitext("SWIO")
		elseif cat["sortkey"] < 50000 then
			sortkeyCategory:wikitext("Aus/Fiji")
		elseif cat["sortkey"] < 60000 then
			sortkeyCategory:wikitext("NIO")
		elseif cat["sortkey"] < 80000 then
			sortkeyCategory:wikitext("WPAC")
		elseif cat["sortkey"] < 90000 then
			sortkeyCategory:wikitext("Atl/EPac/SAtl")
		elseif cat["sortkey"] < 100000 then
			sortkeyCategory:attr
			sortkeyCategory:wikitext("''Global''")
		else
			sortkeyCategory:wikitext("Invalid")
		end
		
		if type(cat["name"]) == "string" then
			local name = mw.html.create("td")
			row:node(icon)
			row:node(id)
			row:node(name)
		else
			local nameTableLength = TableTools.size(cat["name"])
			icon:attr
			id:attr
			colorPreview:attr
			color:attr
			sortkeyCategory:attr
			sortkey:attr
			
			row:node(icon)
			row:node(id)
			local firstDone = false
			for key, basinName in TableTools.sortedPairs(cat["name"]) do
				if firstDone then
					local nameRow = mw.html.create("tr")
					
					nameRow
						
					table.insert	
				else
					firstDone = true
					row
				end
			end
		end
		
		row:node(colorPreview)
		row:node(color)
		row:node(sortkeyCategory)
		row:node(sortkey)
		
		for _, _row in TableTools.sortedPairs(rows) do
			categoryTable:node(_row)
		end
	end
	
	for name, _ in TableTools.sortedPairs(TableTools.listToSet(customKeys)) do
		if cats[name] == nil then
			local row = mw.html.create("tr")
			
			local icon = stormcats._icon
			row
						icon ~= nil
						and icon
						or "''''"
					))
			
			local color = stormcats._color
			-- Add more conditions eventually
			if color ~= nil then
				row
			else
				row
			end
			categoryTable:node(row)
		end
	end
	
	out = ""
	if not plain and not tableEmpty(errors) then
		out = out
			.. tostring(mw.html.create("h4"):wikitext("Error"))
		 .. tostring(mw.html.create("p"):wikitext)
		 .. buildReflist(errors)
	end
	if not plain and not tableEmpty(legend) then
		out = out
			.. tostring(mw.html.create("h4"):wikitext("범례"))
		 .. buildReflist(legend)
	end
	out = out .. tostring(categoryTable)
	if not plain and not tableEmpty(warnings) then
		out = out
			.. tostring(mw.html.create("h4"):wikitext("Warnings"))
		 .. tostring(mw.html.create("p"):wikitext("This table contains warnings than should be addressed. Please note that some warnings cannot be fully addressed without changes that would require consensus."))
		 .. buildReflist(warnings)
	end
	
	return mw.text.trim(out)
end