BTtow = {}
BTtow.Create = {}
BTtow.Init = {}

local TowbarVariantSize = 24
local TowbarNormalStart = 0
local TowbarLargeStart = 24
local TowbarMaxIndex = TowbarVariantSize - 1
local VanillaScaleMin = 1.5
local VanillaScaleMax = 2.0

local function getVehicleModelScale(script)
    if not script then return nil end

    local ok, result = pcall(function()
        return script:getModelScale()
    end)
    if ok and type(result) == "number" then
        return result
    end

    ok, result = pcall(function()
        local model = script:getModel()
        if model then
            return model:getScale()
        end
        return nil
    end)
    if ok and type(result) == "number" then
        return result
    end

    return nil
end

local function isVanillaScale(script)
    local modelScale = getVehicleModelScale(script)
    if modelScale == nil then
        return true
    end

    local configuredMin = TowBarMod and TowBarMod.Config and tonumber(TowBarMod.Config.vanillaTowbarModelScaleMin)
    local configuredMax = TowBarMod and TowBarMod.Config and tonumber(TowBarMod.Config.vanillaTowbarModelScaleMax)
    local minScale = configuredMin or VanillaScaleMin
    local maxScale = configuredMax or VanillaScaleMax
    return modelScale >= minScale and modelScale <= maxScale
end

local function getTowbarIndexVanilla(script)
    local z = script:getPhysicsChassisShape():z() / 2 - 0.1
    local index = math.floor((z * 2 / 3 - 1) * 10)
    return math.max(0, math.min(TowbarMaxIndex, index))
end

local function getTowbarIndexSmallScale(script)
    if not script then return nil end

    local maxAbsTowZ = nil
    local trailer = script:getAttachmentById("trailer")
    if trailer then
        maxAbsTowZ = math.abs(trailer:getOffset():z())
    end
    local trailerFront = script:getAttachmentById("trailerfront")
    if trailerFront then
        local frontAbsZ = math.abs(trailerFront:getOffset():z())
        if not maxAbsTowZ or frontAbsZ > maxAbsTowZ then
            maxAbsTowZ = frontAbsZ
        end
    end

    if maxAbsTowZ ~= nil then
        local index = math.floor((maxAbsTowZ + 0.1 - 1.0) * 10)
        return math.max(0, math.min(TowbarMaxIndex, index))
    end

    return nil
end

local function getTowbarModelSlot(script)
    local isVanilla = isVanillaScale(script)
    local index = getTowbarIndexVanilla(script)
    if not isVanilla then
        local attachmentIndex = getTowbarIndexSmallScale(script)
        if attachmentIndex ~= nil then
            index = attachmentIndex
        else
            local offset = TowBarMod and TowBarMod.Config and tonumber(TowBarMod.Config.smallScaleTowbarIndexOffset) or 2
            index = math.max(0, math.min(TowbarMaxIndex, index + offset))
        end
    end
    return index, isVanilla
end

function BTtow.Create.towbar(vehicle, part)  
    if part == nil then return end
    for j=0, TowbarVariantSize - 1 do
        part:setModelVisible("towbar" .. j, false)        
    end
end

function BTtow.Init.towbar(vehicle, part)
    if part == nil then return end
    for j=0, TowbarVariantSize - 1 do
        part:setModelVisible("towbar" .. j, false)
    end
    if vehicle:getModData()["isTowingByTowBar"] and vehicle:getModData()["towed"] then
        local script = vehicle:getScript()
        if script then
            local index, isVanilla = getTowbarModelSlot(script)
            local partId = part:getId()
            local shouldShowOnThisPart = (isVanilla and partId == "towbar") or ((not isVanilla) and partId == "towbarLarge")
            if shouldShowOnThisPart then
                part:setModelVisible("towbar" .. index, true)
            end
        end
    end
end
