local TXUI, F, E, I, V, P, G = unpack(select(2, ...))
local O = TXUI:GetModule("Options")
local CL = TXUI:GetModule("Changelog")

local ipairs = ipairs
local sub = string.sub
local format = string.format
local type = type

function O:FormatChangelog(options, version, changelogIndex, changelog)
    -- Get the changes from the last changelog
    local changelogGeneralData = changelog.CHANGES
    local changelogRetailData = changelog.CHANGES_RETAIL
    local changelogWrathData = changelog.CHANGES_WRATH

    if (changelog.HOTFIX == true) and not changelogGeneralData then changelogGeneralData = { "* General", I.Strings.ChangelogText[I.Enum.ChangelogType.HOTFIX] } end

    local function generateSectionLog(section, title)
        if (type(section) ~= "table") or (#section == 0) then return "" end

        local text = ""
        local index = 1

        if title then text = text .. F.String.ToxiUI("•" .. title) .. "\n\n" end

        for _, line in ipairs(section) do
            if sub(line, 1, 2) == "* " then
                if title then
                    text = text .. format("%02d", index) .. ". " .. F.String.Trim(line:sub(3)) .. "\n"
                    index = index + 1
                else
                    line = "•" .. line:sub(3)
                    index = 1
                    text = text .. "\n" .. F.String.Trim(F.String.ToxiUI(line)) .. "\n\n"
                end
            else
                text = text .. format("%02d", index) .. ". " .. F.String.Trim(line) .. "\n"
                index = index + 1
            end
        end

        return text .. "\n"
    end

    local generatedText = generateSectionLog(changelogGeneralData)

    if changelog.DYNAMIC then
        local dynamicSection = changelog.DYNAMIC()
        if dynamicSection ~= nil and #dynamicSection > 0 then generatedText = generatedText .. generateSectionLog(dynamicSection, "Additional") end
    end

    if TXUI.IsRetail then
        generatedText = generatedText .. generateSectionLog(changelogRetailData, "Retail")
    elseif TXUI.IsWrath then
        generatedText = generatedText .. generateSectionLog(changelogWrathData, "Wrath")
    end

    -- Get a pretty version number
    local versionString = CL:FormattedVersion(version)

    -- Version header
    local header = {
        order = self:GetOrder(),
        type = "header",
        name = F.String.ToxiUI(versionString),
    }

    -- Big header on first changelog
    if (changelogIndex == 0) or (changelogIndex == 9999) then
        header["type"] = "description"
        header["name"] = (changelogIndex == 0) and "Latest Version " .. header["name"] or header["name"]
        header["fontSize"] = "large"
    end

    -- Add header
    options["clHeader" .. changelogIndex] = header

    -- Generate the actual changes line per line
    options["clChanges" .. changelogIndex] = {
        order = self:GetOrder(),
        type = "description",
        name = generatedText,
        fontSize = "medium",
    }
end

function O:Changelog()
    local options = self.options.information.args.changelog.args

    -- Reset order for new page
    self:ResetOrder()

    options["_recent"] = {
        order = self:GetOrder(),
        name = "Latest Changes",
        type = "group",
        args = {},
    }

    -- Vars
    local recentChangelogs = {}
    local changelogIndex = 0
    local changelogCount = 0

    -- Recent Changelog Generation
    for version, changelog in CL:GetSorted() do
        -- Get pretty changelog
        self:FormatChangelog(options["_recent"]["args"], version, changelogIndex, changelog)

        -- Add as recent changelog
        recentChangelogs[version] = true

        -- Increase by 1, this is only for iteration
        changelogIndex = changelogIndex + 1

        -- Increase by 1 if its not a hotfix
        if changelog.HOTFIX ~= true then changelogCount = changelogCount + 1 end

        -- If we had 3 major changelogs, exit loop
        if changelogCount == 3 then break end
    end

    -- Other Changelog Generation
    for version, changelog in CL:GetSorted() do
        if (changelog.HOTFIX ~= true) and not recentChangelogs[version] then
            -- Create new group
            options[version] = {
                order = self:GetOrder(),
                name = version,
                type = "group",
                args = {},
            }

            -- Get pretty changelog
            self:FormatChangelog(options[version]["args"], version, 9999, changelog)
        end
    end
end

O:AddCallback("Changelog")
