Module:LogInBonusList

local cargo = mw.ext.cargo local List = require 'Module:ListUtil' local Hash = require 'Module:HashUtil' local Datetime = require 'Module:DatetimeUtil' local gsub = mw.ustring.gsub local Rt = require 'Module:RewardText'._main

local QUERY_ARGS = { tables = 'LogInBonus=EV, LogInBonusRewards=R, Units=U, Skills=S', fields = "R._pageName=Page, R.Name=Name, R._ID=_ID," .. "IFNULL(EV.StartTime, R.StartTime)=StartTime," .. "IFNULL(EV.EndTime, DATE_ADD(R.StartTime, INTERVAL 86399 SECOND))=EndTime," .. "R.Kind=Kind, R.Item=Item, S.Name=Seal, R.Accessory=Accessory," .. "R.Amount=Amount, IFNULL(CONCAT(U.Name, ': ', U.Title), U.Name)=Unit, R.Rarity=Rarity", join = 'R._pageName=EV._pageName, R.Unit=U.WikiName, R.SacredSeal=S.WikiName', groupBy = 'R._ID', limit = 10000, }

local getLogInName = function(name, page) if name == 'New Heroes Log-In Bonus' or name == 'Special Heroes Log-In Bonus' then name = name .. ' (' .. gsub(gsub(gsub(gsub(page, '%s*%(Notification%)$', ''), '%s*[Ss]ummoning [Ee]vent%s*', ),														 '%s*:?%s*New Heroes%s*:?%s*', , 1), '%s*:?%s*Special Heroes%s*:?%s*', '', 1)						.. ')' elseif name == 'Tempest Trials Log-In Bonus' or name == 'Voting Gauntlet Log-In Bonus' then name = name .. ' (' .. gsub(gsub(gsub(gsub(gsub(gsub(page, '%s*%(Notification%)$', ''), '%s*Tempest Trials%+?:?%s*', ),																	'%s*Voting Gauntlet:?%s*', ), '...%s*Coming Soon!?%s*', ),																	'^%(', ),																	'%)$', '')						.. ')' end return name end

local reorderQuery = function(query) query = Hash.values(List.group_by(query, function (v) return v.Name == 'Daily Log-In Bonus' and v.Name or v.Name .. v.Page end)) local rewards = List.map(query, function (v) return List.group_by(v, function (v2) return v2.Item .. v2.Unit .. v2.Seal .. v2.Accessory end) end) for iGr, login in ipairs(query) do		local _, startTime = List.min(login, function (v1, v2) return v1.StartTime < v2.StartTime end) local _, endTime = List.max(login, function (v1, v2) return v1.EndTime < v2.EndTime end) query[iGr] = { Page = login[1].Page, Name = getLogInName(login[1].Name, login[1].Page), StartTime = startTime.StartTime, EndTime = endTime.EndTime, Rewards = Hash.values(Hash.map(rewards[iGr], function (v, reward) s = '' if v[1].Kind == 'unit' then s = List.reduce(List.map(v, function (v2) return '{hero=' .. v2.Unit ..';rarity='.. v2.Rarity .. '}' end), function (s1, s2) return s1 .. ';' .. s2 end) elseif v[1].Kind == 'accessory' then s = '{accessory=' .. reward .. '}'				elseif v[1].Kind == 'sacredseal' then s = '{seal=' .. reward .. '}'				else s = '{kind=' .. reward .. ';count=' .. List.reduce(v, function (n, v3) return n + v3.Amount end, 0) .. '}'				end return { id = v[1]._ID, s = s,				} end)), }		if #query[iGr].Rewards > 1 then table.sort(query[iGr].Rewards, function (v1, v2) return v1.id < v2.id end) query[iGr].Rewards = List.reduce(query[iGr].Rewards, function (v1, v2) return (v1.s or v1) .. ';' .. v2.s end) else query[iGr].Rewards = query[iGr].Rewards[1].s		end end table.sort(query, function (v1, v2) return v1.StartTime < v2.StartTime or v1.StartTime == v2.StartTime and v1.Name < v2.Name end) return query end

local createTable = function(loginsList, frame) if #loginsList == 0 then return Currently no such Log-In Bonuses end local tbl = mw.html.create('table'):addClass('wikitable'):addClass('default'):addClass('sortable'):css('text-align', 'center')

local row = tbl:tag('tr') row:tag('th'):wikitext('Name') row:tag('th'):wikitext('Availability') row:tag('th'):wikitext('Rewards')

for _, v in ipairs(loginsList) do		row = tbl:tag('tr') row:tag('td'):wikitext( .. v.Name .. ) row:tag('td'):wikitext(Datetime.ht_range(v.StartTime, v.EndTime)) row:tag('td'):wikitext(Rt({ '[' .. v.Rewards .. ']', iconfirst=1 }, frame)) end

return tostring(tbl) end

local currentLogIn = function(args, frame) local currentDaily = reorderQuery(cargo.query(QUERY_ARGS.tables,QUERY_ARGS.fields, { join = QUERY_ARGS.join, where = "(EV.Name=R.Name AND EV.Kind = 'daily' AND EV.Name != 'Daily Log-In Bonus' AND NOW BETWEEN EV.StartTime AND EV.EndTime)" .. " OR (R.Name = 'Daily Log-In Bonus' AND NOW > R.StartTime AND NOW < DATE_ADD(R.StartTime, INTERVAL 86399 SECOND))", groupBy = QUERY_ARGS.groupBy, limit = QUERY_ARGS.limit, }))	local currentOneTime = reorderQuery(cargo.query(QUERY_ARGS.tables, QUERY_ARGS.fields, { join = QUERY_ARGS.join, where = ("EV.Name=R.Name AND EV.Kind != 'daily' AND (NOW BETWEEN EV.StartTime AND EV.EndTime) AND EV.EndTime != '%s'"):format(Datetime.MAX_TIME), groupBy = QUERY_ARGS.groupBy, limit = QUERY_ARGS.limit, }))	local unendingOneTime = List.map_self(reorderQuery(cargo.query(QUERY_ARGS.tables, QUERY_ARGS.fields, {			join = QUERY_ARGS.join,			where = ("EV.Name=R.Name AND EV.Kind != 'daily' AND NOW > EV.StartTime AND EV.EndTime = '%s'"):format(Datetime.MAX_TIME),			groupBy = QUERY_ARGS.groupBy,			limit = QUERY_ARGS.limit,		})), function(v) v.EndTime = nil; return v end) return ' Daily Log-In Bonuses ' .. createTable(currentDaily, frame) .. ' Temporary One-Time Log-In Bonuses ' .. createTable(currentOneTime, frame) .. ' Permanent One-Time Log-In Bonuses '.. createTable(unendingOneTime, frame) end

local dailyLogIn = function(args, frame) local logins = reorderQuery(cargo.query(QUERY_ARGS.tables, QUERY_ARGS.fields, { join = QUERY_ARGS.join, where = ("(EV.Name=R.Name AND EV.Kind='daily' AND EV.StartTime BETWEEN '%d-01-01T07:00:00Z' AND '%d-01-01-T06:59:59Z')"):format(args.year, args.year+1) .. (" OR (R.Name='Daily Log-In Bonus' AND R.StartTime BETWEEN '%d-01-01T07:00:00Z' AND '%d-01-01-T06:59:59Z')"):format(args.year, args.year+1), groupBy = QUERY_ARGS.groupBy, limit = QUERY_ARGS.limit, }))	return createTable(logins, frame) end

local oneTimeLogIn = function(args, frame) local logins = reorderQuery(cargo.query(QUERY_ARGS.tables, QUERY_ARGS.fields, { join = QUERY_ARGS.join, where = ("EV.Name=R.Name AND EV.Kind!='daily' AND EV.StartTime BETWEEN '%d-01-01T07:00:00Z' AND '%d-01-01-T06:59:59Z'"):format(args.year, args.year+1), groupBy = QUERY_ARGS.groupBy, limit = QUERY_ARGS.limit, }))	return createTable(logins, frame) end

return require 'Module:MakeMWModule'.makeMWModule { current = currentLogIn, daily = dailyLogIn, oneTime = oneTimeLogIn, }