if isClient() then return end

local TowingCommands = {}
local Commands = {}
local TowBarItemType = "TowBar.TowBar"

TowingCommands.wantNoise = getDebug() or false

local noise = function(msg)
    if TowingCommands.wantNoise then
        print("TowBarCommands: " .. msg)
    end
end

function Commands.attachTowBar(player, args)
    local vehicleA = getVehicleById(args.vehicleA)
    local vehicleB = getVehicleById(args.vehicleB)
    if not vehicleA then
        noise("no such vehicle (A) id=" .. tostring(args.vehicleA))
        return
    end
    if not vehicleB then
        noise("no such vehicle (B) id=" .. tostring(args.vehicleB))
        return
    end

    vehicleA:addPointConstraint(player, vehicleB, args.attachmentA, args.attachmentB)
end

function Commands.detachTowBar(player, args)
    local towingVehicle = args.towingVehicle and getVehicleById(args.towingVehicle) or nil
    local towedVehicle = args.vehicle and getVehicleById(args.vehicle) or nil

    if not towingVehicle and towedVehicle then
        towingVehicle = towedVehicle:getVehicleTowedBy()
    end
    if not towedVehicle and towingVehicle then
        towedVehicle = towingVehicle:getVehicleTowing()
    end

    if towedVehicle then
        towedVehicle:breakConstraint(true, false)
    end
    if towingVehicle and towingVehicle ~= towedVehicle then
        towingVehicle:breakConstraint(true, false)
    end
end

function Commands.consumeTowBar(player, args)
    if not player then return end
    local inventory = player:getInventory()
    if not inventory then return end

    local towBarItem = nil
    local itemId = args and args.itemId
    if itemId then
        towBarItem = inventory:getItemWithID(itemId)
    end
    if not towBarItem then
        towBarItem = inventory:getFirstTypeRecurse(TowBarItemType)
    end
    if not towBarItem then return end

    local wasPrimary = player:isPrimaryHandItem(towBarItem)
    local wasSecondary = player:isSecondaryHandItem(towBarItem)
    player:removeFromHands(towBarItem)
    inventory:Remove(towBarItem)
    sendRemoveItemFromContainer(inventory, towBarItem)

    if wasPrimary or wasSecondary then
        sendEquip(player)
    end
end

function Commands.giveTowBar(player, args)
    if not player then return end
    local inventory = player:getInventory()
    if not inventory then return end

    local towBarItem = inventory:AddItem(TowBarItemType)
    if not towBarItem then return end
    sendAddItemToContainer(inventory, towBarItem)

    if args and args.equipPrimary then
        player:setPrimaryHandItem(towBarItem)
        sendEquip(player)
    end
end

-- Compatibility aliases for older command names.
Commands.attachConstraint = Commands.attachTowBar
Commands.detachConstraint = Commands.detachTowBar

TowingCommands.OnClientCommand = function(module, command, player, args)
    if module == "towbar" and Commands[command] then
        local argStr = ""
        args = args or {}
        for k, v in pairs(args) do
            argStr = argStr .. " " .. tostring(k) .. "=" .. tostring(v)
        end
        noise("received " .. module .. " " .. command .. " " .. tostring(player) .. argStr)
        Commands[command](player, args)
    end
end

Events.OnClientCommand.Add(TowingCommands.OnClientCommand)
