--[[
    SocietixM Plugin - Network Management
    Handles communication with SocietixM servers and ID management
]]

local SocietixMPlugin = script.Parent.Parent
local Core = require(SocietixMPlugin.Core)

local Network = {}
Network.__index = Network

-- Network configuration
local API_BASE_URL = "https://api.societixm.com"
local DISCOVERY_ENDPOINT = API_BASE_URL .. "/servers"
local ID_ENDPOINT = API_BASE_URL .. "/ids"
local CONNECTION_TIMEOUT = 10

-- Network state
local registeredServers = {}
local activeConnections = {}

function Network:Initialize()
    print("[SocietixM] Initializing network...")
    
    -- Set up HTTP service
    local HttpService = game:GetService("HttpService")
    
    -- Test connection to API
    self:TestConnection()
    
    print("[SocietixM] Network initialized")
end

function Network:TestConnection()
    local HttpService = game:GetService("HttpService")
    
    spawn(function()
        local success, result = pcall(function()
            local response = HttpService:GetAsync(DISCOVERY_ENDPOINT .. "/ping", false, {
                ["Content-Type"] = "application/json"
            })
            return response
        end)
        
        if success then
            print("[SocietixM] API connection test successful")
        else
            warn("[SocietixM] API connection test failed:", result)
        end
    end)
end

function Network:RegisterServer(serverData)
    print("[SocietixM] Registering server...")
    
    local HttpService = game:GetService("HttpService")
    
    spawn(function()
        local success, result = pcall(function()
            local jsonData = HttpService:JSONEncode(serverData)
            local response = HttpService:PostAsync(DISCOVERY_ENDPOINT .. "/register", jsonData, Enum.HttpContentType.ApplicationJson, false, {
                ["Content-Type"] = "application/json"
            })
            return response
        end)
        
        if success then
            print("[SocietixM] Server registered successfully")
            registeredServers[serverData.Id] = serverData
        else
            warn("[SocietixM] Failed to register server:", result)
        end
    end)
end

function Network:UnregisterServer(serverId)
    print("[SocietixM] Unregistering server...")
    
    local HttpService = game:GetService("HttpService")
    
    spawn(function()
        local success, result = pcall(function()
            local response = HttpService:PostAsync(DISCOVERY_ENDPOINT .. "/unregister", 
                HttpService:JSONEncode({Id = serverId}), 
                Enum.HttpContentType.ApplicationJson, 
                false, 
                {
                    ["Content-Type"] = "application/json"
                }
            )
            return response
        end)
        
        if success then
            print("[SocietixM] Server unregistered successfully")
            registeredServers[serverId] = nil
        else
            warn("[SocietixM] Failed to unregister server:", result)
        end
    end)
end

function Network:DiscoverServers(callback)
    print("[SocietixM] Discovering servers...")
    
    local HttpService = game:GetService("HttpService")
    
    spawn(function()
        local success, result = pcall(function()
            local response = HttpService:GetAsync(DISCOVERY_ENDPOINT .. "/list", false, {
                ["Content-Type"] = "application/json"
            })
            return HttpService:JSONDecode(response)
        end)
        
        if success and result then
            print("[SocietixM] Discovered", #result, "servers")
            if callback then
                callback(result)
            end
        else
            warn("[SocietixM] Failed to discover servers:", result)
            if callback then
                callback({})
            end
        end
    end)
end

function Network:GenerateSocietixId(robloxGameId, callback)
    print("[SocietixM] Generating Societix ID for game:", robloxGameId)
    
    local HttpService = game:GetService("HttpService")
    
    spawn(function()
        local requestData = {
            RobloxGameId = robloxGameId,
            Timestamp = tick(),
            ClientId = self:GetClientId()
        }
        
        local success, result = pcall(function()
            local jsonData = HttpService:JSONEncode(requestData)
            local response = HttpService:PostAsync(ID_ENDPOINT .. "/generate", jsonData, Enum.HttpContentType.ApplicationJson, false, {
                ["Content-Type"] = "application/json"
            })
            return HttpService:JSONDecode(response)
        end)
        
        if success and result and result.SocietixId then
            print("[SocietixM] Generated Societix ID:", result.SocietixId)
            if callback then
                callback(result.SocietixId)
            end
        else
            warn("[SocietixM] Failed to generate Societix ID:", result)
            -- Fallback to local generation
            local localId = self:GenerateLocalSocietixId(robloxGameId)
            if callback then
                callback(localId)
            end
        end
    end)
end

function Network:ResolveSocietixId(societixId, callback)
    print("[SocietixM] Resolving Societix ID:", societixId)
    
    local HttpService = game:GetService("HttpService")
    
    spawn(function()
        local success, result = pcall(function()
            local response = HttpService:GetAsync(ID_ENDPOINT .. "/resolve/" .. societixId, false, {
                ["Content-Type"] = "application/json"
            })
            return HttpService:JSONDecode(response)
        end)
        
        if success and result and result.RobloxGameId then
            print("[SocietixM] Resolved Societix ID to game:", result.RobloxGameId)
            if callback then
                callback(result.RobloxGameId)
            end
        else
            warn("[SocietixM] Failed to resolve Societix ID:", result)
            if callback then
                callback(nil)
            end
        end
    end)
end

function Network:ValidateSocietixId(societixId, callback)
    print("[SocietixM] Validating Societix ID:", societixId)
    
    local HttpService = game:GetService("HttpService")
    
    spawn(function()
        local success, result = pcall(function()
            local response = HttpService:GetAsync(ID_ENDPOINT .. "/validate/" .. societixId, false, {
                ["Content-Type"] = "application/json"
            })
            return response
        end)
        
        local isValid = success and result == "true"
        print("[SocietixM] Societix ID validation result:", isValid)
        
        if callback then
            callback(isValid)
        end
    end)
end

function Network:ConnectToServer(serverId, societixId, callback)
    print("[SocietixM] Connecting to server:", serverId)
    
    -- Check if already connected
    if activeConnections[serverId] then
        warn("[SocietixM] Already connected to server:", serverId)
        if callback then
            callback(false, "Already connected")
        end
        return
    end
    
    -- For now, simulate connection (in production, this would use actual networking)
    spawn(function()
        wait(1) -- Simulate connection delay
        
        local connection = {
            ServerId = serverId,
            SocietixId = societixId,
            ConnectedAt = tick(),
            IsActive = true
        }
        
        activeConnections[serverId] = connection
        
        print("[SocietixM] Connected to server:", serverId)
        
        if callback then
            callback(true, "Connected successfully")
        end
    end)
end

function Network:DisconnectFromServer(serverId)
    print("[SocietixM] Disconnecting from server:", serverId)
    
    if activeConnections[serverId] then
        activeConnections[serverId].IsActive = false
        activeConnections[serverId] = nil
        print("[SocietixM] Disconnected from server:", serverId)
    else
        warn("[SocietixM] Not connected to server:", serverId)
    end
end

function Network:SendMessage(serverId, message, callback)
    if not activeConnections[serverId] or not activeConnections[serverId].IsActive then
        warn("[SocietixM] Not connected to server:", serverId)
        if callback then
            callback(false, "Not connected")
        end
        return
    end
    
    print("[SocietixM] Sending message to server:", serverId)
    
    spawn(function()
        wait(0.1)
        
        print("[SocietixM] Message sent successfully")
        
        if callback then
            callback(true, "Message sent")
        end
    end)
end

function Network:GetActiveConnections()
    local connections = {}
    for serverId, connection in pairs(activeConnections) do
        if connection.IsActive then
            table.insert(connections, connection)
        end
    end
    return connections
end

function Network:IsConnected(serverId)
    return activeConnections[serverId] and activeConnections[serverId].IsActive
end

function Network:GenerateLocalSocietixId(robloxGameId)
    local timestamp = tostring(tick())
    local input = robloxGameId .. "_" .. timestamp .. "_societix_local"
    
    -- Simple hash function
    local hash = 0
    for i = 1, #input do
        hash = hash + string.byte(input, i)
    end
    
    return "SX" .. tostring(hash % 1000000)
end

function Network:GetClientId()
    -- Generate a unique client identifier
    local userId = tostring(game.Players.LocalPlayer and game.Players.LocalPlayer.UserId or 0)
    local placeId = tostring(game.PlaceId)
    local timestamp = tostring(tick())
    
    local input = userId .. "_" .. placeId .. "_" .. timestamp
    
    -- Simple hash
    local hash = 0
    for i = 1, #input do
        hash = hash + string.byte(input, i)
    end
    
    return "CLIENT_" .. tostring(hash % 100000)
end

function Network:Cleanup()
    print("[SocietixM] Cleaning up network...")
    
    -- Disconnect from all servers
    for serverId, _ in pairs(activeConnections) do
        self:DisconnectFromServer(serverId)
    end
    
    -- Clear registered servers
    registeredServers = {}
    
    print("[SocietixM] Network cleanup complete")
end

return Network
