#include "adapters/eft/items/actions/ItemActions.h"

#include <string>

#include "adapters/eft/items/actions/ItemFactoryService.h"
#include "adapters/eft/items/actions/ItemPlacementService.h"
#include "foundation/diagnostics/ExecutionPath.h"

namespace ta::adapters::eft::items
{
    using ta::features::items::contracts::PendingAction;
    using ta::features::items::contracts::quest_item_inventory_slot_index;

    bool ItemActions::execute_stack(const ta::features::items::contracts::ItemCreateRequest& request,
                              ta::adapters::il2cpp::Il2CppObjectInstance game_world_instance,
                              ta::adapters::il2cpp::Il2CppObjectInstance main_player)
    {
        ta::foundation::execution_path::step(request.trace_id, "ItemActions", "begin item creation", request.template_id);
        Il2CppObject* item = ta::adapters::eft::items::ItemFactoryService::create_preset_item(request.template_id);
        if (!item)
        {
            ta::foundation::execution_path::fail(request.trace_id, "ItemFactoryService", "item creation returned null");
            return false;
        }

        const bool configured = ta::adapters::eft::items::ItemFactoryService::configure_created_item(item, {
            request.amount,
            request.override_max_amount,
            request.found_in_raid,
            request.max_stack_size
        });
        ta::foundation::execution_path::step(request.trace_id, "ItemFactoryService", "configure item",
                                      configured ? "configured" : "partial or unchanged");

        if (!place_created_item(request, game_world_instance, main_player, item))
        {
            ta::foundation::execution_path::fail(request.trace_id, "ItemPlacementService", "placement failed");
            return false;
        }
        return true;
    }

    bool ItemActions::place_created_item(const ta::features::items::contracts::ItemCreateRequest& request,
                                         ta::adapters::il2cpp::Il2CppObjectInstance game_world_instance,
                                         ta::adapters::il2cpp::Il2CppObjectInstance main_player,
                                         Il2CppObject* item)
    {
        switch (request.action)
        {
        case PendingAction::CreateItem:
            if (request.slot_index == quest_item_inventory_slot_index)
                return ta::adapters::eft::items::ItemPlacementService::place_in_quest_inventory(main_player, item);
            return ta::adapters::eft::items::ItemPlacementService::place_in_equipment(
                main_player, item, request.slot_index, request.overwrite_slot);
        case PendingAction::TransitItem:
            return ta::adapters::eft::items::ItemPlacementService::place_into_transit_stash(
                game_world_instance, main_player, item);
        case PendingAction::None:
        default:
            return false;
        }
    }
}
