Module:Build bracket

local p = {}

-- Submodules
local Helpers = require("Module:Build bracket/Helpers")
local Config = require("Module:Build bracket/Config")
local Params = require("Module:Build bracket/Params")
local StateChecks = require("Module:Build bracket/StateChecks")
local Logic = require("Module:Build bracket/Logic")
local Paths = require("Module:Build bracket/Paths")
local Render = require("Module:Build bracket/Render")
-- local Deprecations = require('Module:Build bracket/Deprecations')

function p.main(frame)
    -- Shared mutable state passed among submodules
    local state = {
        headerindex = {},
        rlegs = {},
        maxlegs = {},
        hascross = {},
        crossCell = {},
        pathCell = {},
        skipPath = {},
        hide = {},
        byes = {},
        teamsPerMatch = {},
        matchgroup = {},
        maxtpm = 0
    }
    local config = {}

    -- 1) Parse args & set config (also installs arg accessors on Helpers)
    Config.init(frame, state, config, Helpers)

    -- 2) Bind StateChecks (used by Params/Logic/Paths/Render)
    StateChecks.bind(state, config, Helpers)

    -- 3) Build entries skeleton from args (headers/teams/text/lines/groups)
    Params.buildSkeleton(state, config, Helpers, StateChecks)

    -- 4) Discover indices/byes/hide across the skeleton
    Params.scanStructure(state, config, Helpers, StateChecks)

    -- 5) assign per-entry params
    Params.assign(state, config, Helpers, StateChecks)

    -- 5.5) apply minround slicing (reindex to start at 1)
    Params.sliceForMinround(state, config)

    -- 6) Logic passes (max legs, grouping, aggregates, bolding)
    Logic.updateMaxLegs(state, config, Helpers)
    Logic.matchGroups(state, config)
    Logic.computeAggregate(state, config, Helpers, StateChecks)
    Logic.boldWinner(state, config, Helpers, StateChecks)

    -- 7) paths + derive groups from paths
    Paths.build(state, config, Helpers, StateChecks)
    Paths.attachGroups(state, config, Helpers, StateChecks)

    -- (Harmless guard if user passed odd ranges)
    if (tonumber(config.c) or 1) < (tonumber(config.minc) or 1) then
        config.c = config.minc
    end

    -- 8) Render HTML table
    local html = Render.buildTable(frame, state, config, Helpers, StateChecks)
    return tostring(html)
end

-- Exposed for tests/scripts that invoke without a frame
p._main = p.main

return p