MonsterDrop = {}

function MonsterDrop.Init()
    if MonsterDrop_Config.Enabled then
        GameServerFunctions.MonsterDie(MonsterDrop.GiveItem)
    end
end

function MonsterDrop.GiveItem(Player, Monster)
    local m = User.new(Monster)
    local p = User.new(Player)
    local lang = p:getLanguage()
    local mClass = m:getClass()
    local mMap = m:getMapNumber()
    local mX = m:getX()
    local mY = m:getY()
    local config = -1

    for i, monster in ipairs(MonsterDrop_Config.Monster) do
        if monster.Class == mClass or monster.Class == -1 then 
            if monster.Local == -1 then
                config = MonsterDrop_Config.Monster[i]
                goto continue
            else
                if MonsterDrop_Config.Local[monster.Local] == nil then
                    LogAdd(string.format("Monster Drop local config error on index %d", i))
                    return 0
                end
                if mMap == MonsterDrop_Config.Local[monster.Local].Mapa then
                    if mX >= MonsterDrop_Config.Local[monster.Local].Start.X and mX <= MonsterDrop_Config.Local[monster.Local].End.X then
                        if mY >= MonsterDrop_Config.Local[monster.Local].Start.Y and mY <= MonsterDrop_Config.Local[monster.Local].End.Y then
                            config = MonsterDrop_Config.Monster[i]
                            goto continue
                        end
                    end
                end
            end
        end
    end

    ::continue::

    if config == -1 then return 0 end

    local drop = 0

    if config.Drop.Enabled then
        drop = 1
    end

    local returnType = 0

    if drop == 1 then
        if MonsterDrop_Config.Drop[config.Drop.Index] == nil then
            returnType = 0
            goto continua
        end

        if config.Drop.Random then
            local item = MonsterDrop.GetItem(MonsterDrop_Config.Drop[config.Drop.Index], 0)
            if item.Section == -1 then
                returnType = item.Index
                goto continua
            end
            MonsterDrop.DropItem(Player, mMap, mX, mY, item)
        else
            for i, item in ipairs(MonsterDrop_Config.Drop[config.Drop.Index]) do
                if type(item) == "table" and item.Section ~= -1 and item.Index ~= -1 then
                    MonsterDrop.DropItem(Player, mMap, mX, mY, item)
                end
            end
        end
        returnType = 1
    end

    ::continua::

    return returnType
end

function MonsterDrop.DropItem(aIndex, map, x, y, item)
    local level = Utils.GetRandom(item.Level.Min, item.Level.Max, math.random(1,10))
    local luck = 0
    if type(item.Luck) == "number" and item.Luck > 0 then
        if Utils.GetSuccessByRate(item.Luck) then
            luck = 1
        end
    end
    local skill = 0
    if type(item.Skill) == "number" and item.Skill > 0 then
        if Utils.GetSuccessByRate(item.Skill) then
            skill = 1
        end
    end
    local opt = Utils.GetRandom(item.Opt.Min, item.Opt.Max, math.random(1,10))
    local exc = 0
    local expcount = 1
    if type(item.Exc) == "table" then
        for z = 1, 6 do
            if item.Exc[z] > 0 then
                if Utils.GetSuccessByRate(item.Exc[z]) then
                    exc = exc + expcount
                end
                expcount = expcount * 2
            end
        end
    end

    local ancient = 0
    if type(item.Ancient) == "number" and item.Ancient > 0 then
        if Utils.GetSuccessByRate(item.Ancient) then
            ancient = 1
        end
    end

    local socket = 0
    if type(item.Socket) == "table" then
        for z = 1, 3 do
            if item.Socket[z] > 0 then
                if Utils.GetSuccessByRate(item.Socket[z]) then
                    socket = socket + 1
                end
            end
        end
    end
    
    if socket == 0 then 
        socket = 255 
    end

    local success = CreateItemMap(aIndex, map, x, y, GET_ITEM(item.Section, item.Index), level, skill, luck, opt, exc, ancient, 0, socket, item.ItemTime)

    if success == 0 then
        LogAdd(string.format("Item drop failed at position X: %d, Y: %d in map: %d", x, y, map))
    end
end

function MonsterDrop.GetItem(Drop, tipo)
    local t = {}
    for i, dropItem in ipairs(Drop) do
        if type(dropItem.Rate) == "number" then
            for x = 1, (dropItem.Rate/100)*10000 do
                table.insert(t, dropItem)
            end
        end
    end

    if #t == 0 then
        if tipo == 0 then
            t = {Section = -1 , Index = 0}
            return t
        else
            return -1
        end
    end

    return t[Utils.GetRandom(1, #t, math.random(1, 100))]
end

MonsterDrop.Init()

return MonsterDrop