require('strict')
local p = {}

local lects = mw.loadData('Module:IPA/data/export')

local function addNote(cell, note)
	cell:wikitext(string.format(' <small>(%s)</small>', note))
end

function p.main()
	local t = mw.html.create('table'):addClass('wikitable sortable mw-collapsible')
		:tag('caption'):addClass('nowrap'):wikitext('Data overview'):done()
		:tag('tr')
			:tag('th'):attr('colspan', 4):wikitext('Language'):done()
			:tag('th'):attr('colspan', 4):wikitext('Dialect'):done()
			:done()
		:tag('tr')
			:tag('th'):wikitext('Code'):done()
			:tag('th'):wikitext('Name'):done()
			:tag('th'):wikitext('Link'):done()
			:tag('th'):wikitext('Key'):done()
			:tag('th'):wikitext('Code'):done()
			:tag('th'):wikitext('Name'):done()
			:tag('th'):wikitext('Link'):done()
			:tag('th'):wikitext('Key'):done()
			:done()
	local langRow, langCells, dialectCount
	for i, lect in ipairs(lects) do
		local row
		local cells = {}
		if lect.parent then
			dialectCount = dialectCount + 1
			if dialectCount == 1 then
				row = langRow
			else
				row = t:tag('tr')
				for _, cell in ipairs(langCells) do
					cell:attr('rowspan', dialectCount)
				end
			end
		else
			row = t:tag('tr')
			langRow = row
			langCells = cells
			dialectCount = 0
		end
		for _ = 1, 4 do
			table.insert(cells, row:tag('td'))
		end
		if not lect.parent and not (lects[i + 1] and lects[i + 1].parent) then
			for _ = 1, 4 do
				row:tag('td'):css('background', '#ececec')
			end
		end
		cells[1]:wikitext('<code>' .. lect.code:gsub('^[^-]+%-', '') .. '</code>')
		if lect.aliases then
			local aliases = {}
			for _, alias in ipairs(lect.aliases) do
				table.insert(aliases, alias)
			end
			addNote(cells[1], string.format(
				'also <code>%s</code>',
				table.concat(aliases, '</code>, <code>')
			))
		end
		do
			local notes = {}
			if lect.name then
				if lect.name == lect.extName then
					table.insert(notes, 'redundant')
				elseif lect.extName then
					table.insert(notes, string.format('overrides "%s"', lect.extName))
				end
			end
			if lect.text then
				table.insert(notes, string.format('label: "%s"', lect.text))
			end
			cells[2]:wikitext(lect.name or lect.extName)
			if #notes > 0 then
				addNote(cells[2], table.concat(notes, '; '))
			end
		end
		do
			local note
			local intLink = lect.link or lect.generatedLink
			if intLink then
				if intLink == lect.extLink then
					note = 'redundant'
				elseif lect.extLink then
					note = string.format('overrides [[%s]]', lect.extLink)
					local intTitle = mw.title.new(intLink)
					intTitle = intTitle.redirectTarget or intTitle
					local extTitle = mw.title.new(lect.extLink)
					extTitle = extTitle.redirectTarget or extTitle
					if intTitle ~= extTitle then
						note = note .. ', a different article'
					end
				end
			end
			local s = intLink or lect.extLink
			s = lect.generatedLink and '([[' .. s .. ']])' or '[[' .. s .. ']]'
			cells[3]:wikitext(s)
			if note then
				addNote(cells[3], note)
			end
		end
		cells[4]:wikitext(
			lect.key and '[[' .. lect.key .. ']]' or
				'([[' .. (lect.parent and lect.parent.key or 'Help:IPA') .. ']])'
		)
	end
	return tostring(t)
end

function p.keys()
	local t = mw.html.create('table'):addClass('wikitable sortable mw-collapsible')
		:tag('caption'):addClass('nowrap'):wikitext('Languages with dedicated keys'):done()
		:tag('tr')
			:tag('th'):wikitext('Key'):done()
			:tag('th'):wikitext('Language'):done()
			:tag('th'):wikitext('Code'):done()
			:done()
	local byKey, keys = {}, {}
	for _, lect in ipairs(lects) do
		local key = lect.key or lect.parent and lect.parent.key
		if key then
			local asciiKey = mw.ustring.gsub(mw.ustring.toNFD(key), '[^ -~]', '')
			if not byKey[asciiKey] then
				byKey[asciiKey] = { name = key }
				table.insert(keys, asciiKey)
			end
			table.insert(byKey[asciiKey], {
				code = lect.code,
				name = lect.name or lect.extName,
				link = lect.link or lect.generatedLink or lect.extLink
			})
		end
	end
	table.sort(keys)
	for _, asciiKey in ipairs(keys) do
		local row = t:tag('tr')
		local keyLects = byKey[asciiKey]
		local keyCell = row:tag('td'):wikitext('[[' .. keyLects.name .. ']]')
		local lang
		if #keyLects > 1 then
			keyCell:attr('rowspan', #keyLects)
			table.sort(keyLects, function (a, b) return a.name < b.name end)
			local keyName = mw.ustring.gsub(keyLects.name, '^[^/]*/', '')
			for _, lect in ipairs(keyLects) do
				if lect.name == keyName then
					lang = lect
					break
				end
			end
			if not lang then
				for _, lect in ipairs(keyLects) do
					if lect.name:find(' languages$') then
						lang = lect
						break
					end
				end
			end
			if not lang then
				for _, lect in ipairs(keyLects) do
					if not lect.code:find('-') then
						lang = lect
						break
					end
				end
			end
		end
		lang = lang or keyLects[1]
		local prev = {
			name = lang.name,
			count = 1,
			cell = row:tag('td'):wikitext(
				string.format('[[%s|%s]]', lang.link, lang.name)
			)
		}
		row:tag('td'):wikitext('<code>' .. lang.code .. '</code>')
		for _, lect in ipairs(keyLects) do
			if lect ~= lang then
				local subRow = t:tag('tr')
				if prev.name == lect.name then
					prev.count = prev.count + 1
					prev.cell:attr('rowspan', prev.count)
				else
					prev = {
						name = lect.name,
						count = 1,
						cell = subRow:tag('td'):wikitext(
							string.format('[[%s|%s]]', lect.link, lect.name)
						)
					}
				end
				subRow:tag('td'):wikitext('<code>' .. lect.code .. '</code>')
			end
		end
	end
	return tostring(t)
end

return p