local VE = {}
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local Camera = workspace.CurrentCamera

-- Stores all ESP objects
VE.ESPObjects = {}
VE.UpdateRate = 1 / 60  -- Default to 60 FPS
VE.Running = false

-- Initialize Visual Engine
function VE.Init()
    VE.Running = true
    task.spawn(VE.UpdateLoop)
end

-- Destroy all ESP objects and stop updating
function VE.Destroy()
    VE.Running = false
    for _, esp in pairs(VE.ESPObjects) do
        for _, line in pairs(esp.Lines) do
            line:Remove()
        end
    end
    VE.ESPObjects = {}
end

-- Set ESP update rate
function VE.SetUpdateRate(rate)
    VE.UpdateRate = 1 / math.max(rate, 1) -- Prevent division by zero
end

-- Add ESP for all players (3D Box with 4 sides)
function VE.AddESP()
    for _, player in pairs(Players:GetPlayers()) do
        if player ~= Players.LocalPlayer and player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
            local rootPart = player.Character.HumanoidRootPart
            local esp = {Lines = {}, Player = player}
            
            -- Create 4 lines for the 3D box
            for i = 1, 4 do
                local line = Drawing.new("Line")
                line.Thickness = 2
                line.Color = Color3.new(1, 0, 0)
                line.Transparency = 1
                esp.Lines[i] = line
            end
            VE.ESPObjects[player] = esp
        end
    end
end

-- ESP Update Loop
function VE.UpdateLoop()
    while VE.Running do
        local deltaTime = task.wait(VE.UpdateRate)
        for _, esp in pairs(VE.ESPObjects) do
            local player = esp.Player
            if player and player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
                local rootPart = player.Character.HumanoidRootPart
                local screenPos, onScreen = Camera:WorldToViewportPoint(rootPart.Position)
                
                if onScreen then
                    -- Define 3D box corners
                    local size = Vector3.new(3, 6, 0)
                    local corners = {
                        rootPart.Position + Vector3.new(size.X, size.Y, size.Z),
                        rootPart.Position + Vector3.new(-size.X, size.Y, size.Z),
                        rootPart.Position + Vector3.new(-size.X, -size.Y, size.Z),
                        rootPart.Position + Vector3.new(size.X, -size.Y, size.Z),
                    }
                    
                    -- Convert to screen positions
                    local screenCorners = {}
                    for i, corner in pairs(corners) do
                        local pos, vis = Camera:WorldToViewportPoint(corner)
                        if vis then
                            screenCorners[i] = Vector2.new(pos.X, pos.Y)
                        else
                            screenCorners[i] = nil
                        end
                    end
                    
                    -- Update ESP Lines
                    if #screenCorners == 4 then
                        esp.Lines[1].From = screenCorners[1]
                        esp.Lines[1].To = screenCorners[2]
                        
                        esp.Lines[2].From = screenCorners[2]
                        esp.Lines[2].To = screenCorners[3]
                        
                        esp.Lines[3].From = screenCorners[3]
                        esp.Lines[3].To = screenCorners[4]
                        
                        esp.Lines[4].From = screenCorners[4]
                        esp.Lines[4].To = screenCorners[1]
                        
                        for _, line in pairs(esp.Lines) do
                            line.Visible = true
                        end
                    else
                        for _, line in pairs(esp.Lines) do
                            line.Visible = false
                        end
                    end
                else
                    for _, line in pairs(esp.Lines) do
                        line.Visible = false
                    end
                end
            end
        end
    end
end

return VE