Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
Revision as of 04:31, 26 February 2026 by Esportsamaze (talk | contribs)

Documentation for this module may be created at Module:Participant/doc

local p = {}
local html = mw.html
local cargo = mw.ext.cargo

-- HELPER: Smart Tournament Name Detection (Ignores /Teams, /Group A, etc.)
local function getTournamentName(args)
    if args.tournament and args.tournament ~= "" then
        return args.tournament
    end
    
    local pageTitle = mw.title.getCurrentTitle().text
    local parts = mw.text.split(pageTitle, '/')
    
    -- If path is "BGMI/Tournaments/BGIS 2026/Teams", parts[3] is "BGIS 2026"
    if parts[2] == "Tournaments" and parts[3] then
        return parts[3]
    end
    
    -- Fallback for root pages
    return mw.title.getCurrentTitle().baseText
end

-- INTERNAL: Builds the HTML for a single card
local function buildCard(data, seedOverride)
    local root = html.create('div'):addClass('roster-card')

    -- HEADER
    local header = root:tag('div'):addClass('roster-header')
    local headerContent = header:tag('div'):addClass('header-content')

    -- LOGO LOGIC (No #ifexist. Pure Database/Fallback)
    local lightLogo = "Shield_team.png"
    local darkLogo = "Shield_team_dark.png"

    if data.masterImg and data.masterImg ~= "" then
        lightLogo = data.masterImg
        darkLogo = (data.masterImgDark and data.masterImgDark ~= "") and data.masterImgDark or lightLogo
    elseif data.entryImg and data.entryImg ~= "" then
        lightLogo = data.entryImg
        darkLogo = (data.entryImgDark and data.entryImgDark ~= "") and data.entryImgDark or lightLogo
    end

    local logoDiv = headerContent:tag('div'):addClass('roster-logo')
    logoDiv:tag('div'):addClass('logo-lightmode'):wikitext('[[File:' .. lightLogo .. '|link=]]')
    logoDiv:tag('div'):addClass('logo-darkmode'):wikitext('[[File:' .. darkLogo .. '|link=]]')

    -- NAME LOGIC (Display Name Override)
    local displayName = data.displayName
    if not displayName or displayName == "" then displayName = data.team end
    headerContent:tag('div'):addClass('roster-name'):wikitext('[[' .. data.team .. '|' .. displayName .. ']]')

    -- SEEDING (Uses the stage override if provided, else the original entry seed)
    local finalSeed = seedOverride
    if not finalSeed or finalSeed == "" then finalSeed = data.seeding end
    if finalSeed and finalSeed ~= "" then
        root:tag('div'):addClass('roster-subheader'):wikitext(finalSeed)
    end

    -- PLAYERS
    local contentRows = root:tag('div'):addClass('roster-content-rows')
    local players = {data.p1, data.p2, data.p3, data.p4, data.p5, data.p6}
    local playerCount = 0
    for _, pl in ipairs(players) do 
        if pl and pl ~= "" then playerCount = playerCount + 1 end 
    end

    local playerInner = contentRows:tag('div'):addClass('roster-players-inner'):addClass('count-' .. playerCount)
    for _, pl in ipairs(players) do
        if pl and pl ~= "" then
            playerInner:tag('div'):addClass('roster-row player'):wikitext('[[' .. pl .. ']]')
        end
    end

    -- STAFF
    if (data.coach and data.coach ~= "") or (data.analyst and data.analyst ~= "") then
        local staffInner = contentRows:tag('div'):addClass('roster-staff-inner')
        if data.coach and data.coach ~= "" then
            staffInner:tag('div'):addClass('roster-row staff'):wikitext('C: [[' .. data.coach .. ']]')
        end
        if data.analyst and data.analyst ~= "" then
            staffInner:tag('div'):addClass('roster-row staff'):wikitext('A: [[' .. data.analyst .. ']]')
        end
    end

    return tostring(root)
end

-- PUBLIC 1: ENTRY MODULE (Saves to Cargo, Displays Nothing)
function p.entry(frame)
    local args = frame:getParent().args
    local count = tonumber(args.count) or 20
    local tournamentName = getTournamentName(args) -- USES SMART DETECTION

    for i = 1, count do
        local prefix = 't' .. i
        local team = args[prefix]

        if team and team ~= "" then
            if cargo and cargo.store then
                cargo.store("Tournament_Teams", {
                    tournament = tournamentName,
                    team = team,
                    display_name = args[prefix .. 'name'],
                    image = args[prefix .. 'img'],
                    image_dark = args[prefix .. 'imgdark'],
                    seeding = args[prefix .. 'seed'],
                    p1 = args[prefix .. 'p1'],
                    p2 = args[prefix .. 'p2'],
                    p3 = args[prefix .. 'p3'],
                    p4 = args[prefix .. 'p4'],
                    p5 = args[prefix .. 'p5'],
                    p6 = args[prefix .. 'p6'],
                    coach = args[prefix .. 'c'],
                    analyst = args[prefix .. 'a']
                })
            end
        end
    end

    return "<div style='display:none;'>Roster Data Saved Successfully.</div>"
end

-- PUBLIC 2: DISPLAY MODULE (Fetches from Cargo instantly, Builds Cards)
function p.display(frame)
    local args = frame:getParent().args
    local tournamentName = getTournamentName(args) -- USES SMART DETECTION
    local count = tonumber(args.count) or 24

    -- 1. Gather Requested Teams
    local requestedTeams = {}
    local orderedRequests = {}

    for i = 1, count do
        local team = args['t' .. i]
        if team and team ~= "" then
            local cleanTeam = team:gsub("'", "\\'")
            table.insert(requestedTeams, "'" .. cleanTeam .. "'")
            table.insert(orderedRequests, { name = team, seed = args['t' .. i .. 'seed'] })
        end
    end

    if #requestedTeams == 0 then return "" end
    local teamListSql = table.concat(requestedTeams, ", ")

    -- 2. MEMORY MAP A: Fetch Rosters (ONE QUERY)
    local rosterDb = {}
    if cargo and cargo.query then
        local rResults = cargo.query(
            "Tournament_Teams",
            "team, display_name, image, image_dark, seeding, p1, p2, p3, p4, p5, p6, coach, analyst",
            { where = "tournament='" .. tournamentName:gsub("'", "\\'") .. "' AND team IN (" .. teamListSql .. ")", limit = count }
        )
        for _, row in ipairs(rResults) do
            rosterDb[row.team] = row
        end
    end

    -- 3. MEMORY MAP B: Fetch Master Logos (ONE QUERY)
    local masterDb = {}
    if cargo and cargo.query then
        local mResults = cargo.query(
            "Teams",
            "_pageName, image, image_dark",
            { where = "_pageName IN (" .. teamListSql .. ")", limit = count }
        )
        for _, row in ipairs(mResults) do
            masterDb[row._pageName] = row
        end
    end

    -- 4. BUILD HTML
    local container = html.create('div')
        :addClass('participant-group-container')
        :css('display', 'flex')
        :css('flex-wrap', 'wrap')
        :css('gap', '15px')
        :css('justify-content', 'center')

    for _, req in ipairs(orderedRequests) do
        local teamName = req.name
        local rosterData = rosterDb[teamName] or { team = teamName }

        if masterDb[teamName] then
            rosterData.masterImg = masterDb[teamName].image
            rosterData.masterImgDark = masterDb[teamName].image_dark
        end

        rosterData.entryImg = rosterData.image
        rosterData.entryImgDark = rosterData.image_dark
        rosterData.displayName = rosterData.display_name

        container:wikitext(buildCard(rosterData, req.seed))
    end

    return tostring(container)
end

return p