-- Module:AdaptationGuide
-- Formats precomputed Arc Almanac table models. Continue-from and coverage
-- stay in TypeScript; this file only writes wikitext. Lua 5.1 / Scribunto.
local p = {}

local VIEWS = {
	arcs = "arcs",
	["after-season"] = "afterSeason",
	coverage = "coverage",
	arc = "arc",
}

local function trim(s)
	if s == nil then
		return ""
	end
	return mw.text.trim(tostring(s))
end

local function errorHtml(msg)
	return '<strong class="error">' .. mw.text.nowiki(msg) .. "</strong>"
end

local function loadFranchise(id)
	local ok, data = pcall(mw.loadData, "Module:AdaptationGuide/data/" .. id)
	if not ok or type(data) ~= "table" then
		return nil
	end
	return data
end

local function plain(s)
	return mw.text.nowiki(s or "")
end

local function cellBits(cell)
	local bits = {}
	if cell.tone then
		table.insert(bits, 'class="aa-tone-' .. cell.tone .. '"')
	end
	if cell.spoiler then
		table.insert(bits, 'data-spoiler="1"')
	end
	local attr = ""
	if #bits > 0 then
		attr = " " .. table.concat(bits, " ")
	end
	local text
	if cell.href and cell.href ~= "" then
		text = "[" .. cell.href .. " " .. plain(cell.text) .. "]"
	else
		text = plain(cell.text)
	end
	local mark = cell.header and "!" or "|"
	if attr ~= "" then
		return mark .. attr .. " |" .. text
	end
	return mark .. text
end

local function renderTable(model)
	local out = {}
	table.insert(out, '{| class="wikitable aa-table" data-table="' .. (model.id or "") .. '"')
	table.insert(out, "|+ " .. plain(model.caption or ""))
	for _, heading in ipairs(model.head) do
		table.insert(out, "!" .. plain(heading))
	end
	for _, row in ipairs(model.rows) do
		table.insert(out, "|-")
		for _, cell in ipairs(row) do
			table.insert(out, cellBits(cell))
		end
	end
	table.insert(out, "|}")
	return table.concat(out, "\n")
end

local function ext(url, label)
	return "[" .. url .. " " .. plain(label) .. "]"
end

local function creditLine(data)
	local modified = ""
	if data.modified then
		modified = " (modified)"
	end
	return '<p class="aa-credit">Data: '
		.. ext(data.siteUrl, (data.titles.en or "") .. " adaptation guide")
		.. " (version "
		.. plain(data.version or "")
		.. ")"
		.. modified
		.. " by "
		.. ext(data.creditsUrl, "Arc Almanac contributors")
		.. ", licensed "
		.. ext(data.licenseUrl, "CC BY 4.0")
		.. ". "
		.. ext(data.issueFormUrl, "Report a correction")
		.. ".</p>"
end

local function selectModel(data, view, arcId)
	local tables = data.tables
	if type(tables) ~= "table" then
		return nil, "This data module has no tables."
	end
	if view == "arc" then
		if arcId == "" then
			return nil, "Missing arc. Use arc=<arcId> with view=arc."
		end
		local model = tables.arc and tables.arc[arcId]
		if not model then
			return nil, "Unknown arc: " .. arcId
		end
		return model
	end
	local key = VIEWS[view]
	local model = key and tables[key]
	if not model then
		return nil, "Unknown view: " .. view .. ". Use arcs, after-season, coverage, or arc."
	end
	return model
end

function p.main(frame)
	local args = frame.args
	if trim(args.franchise) == "" and frame.getParent then
		local parent = frame:getParent()
		if parent then
			args = parent.args
		end
	end

	local franchise = trim(args.franchise)
	if franchise == "" then
		return errorHtml("Missing franchise. Use franchise=<id>.")
	end
	local view = trim(args.view)
	if view == "" then
		return errorHtml("Missing view. Use view=arcs, after-season, coverage, or arc.")
	end
	if not VIEWS[view] then
		return errorHtml("Unknown view: " .. view .. ". Use arcs, after-season, coverage, or arc.")
	end

	local data = loadFranchise(franchise)
	if not data then
		return errorHtml("Unknown franchise: " .. franchise)
	end

	local model, err = selectModel(data, view, trim(args.arc))
	if not model then
		return errorHtml(err)
	end

	return '<div class="aa-guide">\n' .. renderTable(model) .. "\n" .. creditLine(data) .. "\n</div>"
end

return p
