require 'Scripts/Data/rewards.lua'

math.randomseed(os.time())

function isValidDrop(reward, rewardKey)
    local playerProfile = BAMFGame:sharedGame():getPlayerProfile()

    return (reward.minimumAwardThreshold or DEFAULT_MINIMUM_AWARD_THRESHOLD) <= playerProfile:getRewardCount(rewardKey) and
     (reward.levelRequirement or DEFAULT_LEVEL_REQUIREMENT) <= playerProfile:getLastCompletedStoryLevelOrder() and
     (reward.inventoryRequirement == nil or playerProfile:getInventory():hasAmount(reward.inventoryRequirement, 1))
end

function canDrop(rewards, rewardKey)
    if rewards~= nil then
        for i=1, #rewards do
            if isValidDrop(rewards[i], rewardKey) then
                return true
            end
        end
    end

    return false
end

function getNextRewardList(rewardKey)
    for key,rewardList in pairs(rewardMap[rewardKey]) do
        if (BAMFGame:sharedGame():getPlayerProfile():getNextRewardCounter(rewardList.rewardCategory or DEFAULT_REWARD_CATEGORY) <= 0) and
         canDrop(rewardList.items or DEFAULT_ITEMS, rewardKey) then
            return rewardList
        end
    end

    return {}
end

function getRandomRewardFromList(rewards, rewardKey)
    local validRewards = {}
    local totalWeight = 0

    for i=1, #rewards do
        if isValidDrop(rewards[i], rewardKey) then
            totalWeight = totalWeight + (rewards[i].probabilityWeight or DEFAULT_PROBABILITY_WEIGHT)
            table.insert(validRewards, rewards[i])
        end
    end

    if totalWeight > 0 then
        local random = math.random(totalWeight)

        for i=1, #validRewards do
            local probabilityWeight = validRewards[i].probabilityWeight or DEFAULT_PROBABILITY_WEIGHT

            if random <= probabilityWeight then
                return validRewards[i]
            else
                random = random - probabilityWeight
            end
        end
    end

    return {}
end

function getRandomReward(input)
    local rewardKey = input:getRewardKey():getCString()

    BAMFGame:sharedGame():getPlayerProfile():decrementNextRewardCounters(input:getRewardDecrement())

    local rewardList = getNextRewardList(rewardKey)

    local randomNextRewardCounter = math.random(rewardList.minNextRewardCounter or DEFAULT_MIN_NEXT_REWARD_COUNTER, rewardList.maxNextRewardCounter or DEFAULT_MAX_NEXT_REWARD_COUNTER)
    BAMFGame:sharedGame():getPlayerProfile():setNextRewardCounter(rewardList.rewardCategory or DEFAULT_REWARD_CATEGORY, randomNextRewardCounter)

    local reward = getRandomRewardFromList(rewardList.items or DEFAULT_ITEMS, rewardKey)
    BAMFGame:sharedGame():getPlayerProfile():incrementRewardCount(rewardKey)

    local output = RewardData:create(rewardKey)
    output:setShopItemKey(reward.shopItemKey or DEFAULT_SHOP_ITEM_KEY)

    -- Hack
    if string.match(rewardKey, "Drop") and reward.shopItemKey == "Coin" then
        output:setAmount(math.random(input:getMinCoinsOverride(), input:getMaxCoinsOverride()))
    else
        output:setAmount(reward.amount or DEFAULT_AMOUNT)
    end

    if reward.soundKey ~= nil then
        output:addComponent("SoundComponent", SoundComponent:create(reward.soundKey))
    end

    return output
end

function initializeRewardCounters()
    for _,rewardLists in pairs(rewardMap) do
        for i=1, #rewardLists do
            local rewardList = rewardLists[i]
            if BAMFGame:sharedGame():getPlayerProfile():getNextRewardCounter(rewardList.rewardCategory or DEFAULT_REWARD_CATEGORY) < 0 then
                local randomNextRewardCounter = math.random(rewardList.minNextRewardCounter or DEFAULT_MIN_NEXT_REWARD_COUNTER, rewardList.maxNextRewardCounter or DEFAULT_MAX_NEXT_REWARD_COUNTER)
                BAMFGame:sharedGame():getPlayerProfile():setNextRewardCounter(rewardList.rewardCategory or DEFAULT_REWARD_CATEGORY, randomNextRewardCounter)
            end
        end
    end
end