local function loadBlacklistFile()
    local json = file.Read("npc_blacklist.json", "DATA")
    if not json or json == "" then return {} end
    local data = util.JSONToTable(json)
    return istable(data) and data or {}
end

local function resetHostile()
    local npcs = list.Get("NPC")
    for class, npc in pairs(npcs) do
        if npc["m_OldData"] then
            local oldData = util.JSONToTable(npc["m_OldData"])
            if oldData then
                list.Set("NPC", class, oldData)
            end
        end
    end
end

local function replaceHostile()
    local blacklist = loadBlacklistFile()
    local npcs = list.Get("NPC")
    local citizenEnemy = npcs["npc_citizen_rebel_enemy"]

    for class, npc in pairs(npcs) do
        if table.HasValue(blacklist, class) then continue end
        if npc["Class"] == "npc_combine_s" and npc["Category"] ~= "#spawnmenu.category.combine" then
            npc["m_OldData"] = npc["m_OldData"] or util.TableToJSON(npc, false)
            npc["Class"] = citizenEnemy["Class"]
            npc["KeyValues"] = {
                Hostile = 1,
                SquadName =	"overwatch",
                citizentype = 4
            }
            list.Set("NPC", class, npc)
        end
    end
end

CreateClientConVar("replacehostile_blacklist", "", false, false, "Blacklist NPC Classes")

concommand.Add("replacehostile_reload", function()
    resetHostile()
    replaceHostile()
    print("NPC Hostile Reloaded")
end)

hook.Add("PopulateToolMenu", "ReplaceHostileMenu", function()
    local blacklist = loadBlacklistFile()
    local defaultBlacklistStr = table.concat(blacklist, ",")

    RunConsoleCommand("replacehostile_blacklist", defaultBlacklistStr)

    spawnmenu.AddToolMenuOption("Options", "Replace Hostile", "ReplaceHostileConfig", "Settings", "", "", function(panel)
        panel:ClearControls()
        
        local blacklistEntry = panel:TextEntry("Blacklist Classes", "replacehostile_blacklist")

        panel:ControlHelp("Separate classes with commas.\nExample: npc_my_custom_hostile,npc_my_hostile,npc_hostile_test")
        panel:Button("Reload NPCs", "replacehostile_reload")

        blacklistEntry.OnChange = function(self)
            local val = self:GetValue() or ""
            local newBlacklist = {}

            for e in string.gmatch(val, '([^,]+)') do
                local trimmed = string.Trim(e)
                if trimmed ~= "" then
                    table.insert(newBlacklist, trimmed)
                end
            end

            local valid = true
            for _, v in ipairs(newBlacklist) do
                if type(v) ~= "string" or v == "" then
                    valid = false
                    break
                end
            end
            
            if valid then
                file.Write("npc_blacklist.json", util.TableToJSON(newBlacklist, false))
            end
        end
    end)
end)

timer.Simple(0, function()
    replaceHostile()
end)