package electrosphere.server.content.unit;

import org.joml.Vector3d;

import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.state.equip.ServerEquipState;
import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.data.units.UnitDefinition;
import electrosphere.game.data.units.UnitEquippedItem;
import electrosphere.game.data.units.UnitLoader;
import electrosphere.logger.LoggerInterface;
import electrosphere.server.datacell.Realm;

/**
 * Utilities for dealing with units
 */
public class UnitUtils {
    
    /**
     * Spawns a unit
     * @param realm The realm to spawn in
     * @param position The position to spawn at
     * @param type The type of unit
     * @return The entity encompassing the unit
     */
    public static Entity spawnUnit(Realm realm, Vector3d position, String type){
        UnitLoader unitLoader = Globals.gameConfigCurrent.getUnitLoader();
        UnitDefinition unitDefinition = unitLoader.getUnit(type);
        if(unitDefinition == null){
            LoggerInterface.loggerEngine.ERROR(new IllegalArgumentException("Tried to spawn undefined unit type! " + type));
            return null;
        }
        String creatureId = unitDefinition.getCreatureId();
        if(creatureId == null || creatureId.equals("")){
            LoggerInterface.loggerEngine.ERROR(new IllegalArgumentException("Tried to spawn unit with invalid creatureId! \"" + creatureId + "\""));
            return null;
        }
        Entity rVal = CreatureUtils.serverSpawnBasicCreature(realm, position, creatureId, CreatureTemplate.createDefault(creatureId));
        
        //optionally apply ai
        if(unitDefinition.getAI() != null){
            Globals.aiManager.removeAI(rVal);
            Globals.aiManager.attachAI(rVal, unitDefinition.getAI());
        }

        //optionally add equipment
        if(unitDefinition.getEquipment() != null){
            for(UnitEquippedItem equippedItem : unitDefinition.getEquipment()){
                if(equippedItem.getItemId() == null || equippedItem.getItemId().equals("")){
                    LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Equipped item id is invalid! \"" + equippedItem.getItemId() + "\""));
                }
                if(equippedItem.getPointId() == null || equippedItem.getPointId().equals("")){
                    LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Equipped point id is invalid! \"" + equippedItem.getPointId() + "\""));
                }
                //spawn the item in the world
                Entity itemInWorld = ItemUtils.serverSpawnBasicItem(realm, position, equippedItem.getItemId());

                //add the item to the creature's inventory
                Entity itemInInventory = InventoryUtils.serverAttemptStoreItemTransform(rVal, itemInWorld);

                //equip the item to the slot defined in the template
                ServerEquipState serverEquipState = ServerEquipState.getEquipState(rVal);
                serverEquipState.commandAttemptEquip(itemInInventory,serverEquipState.getEquipPoint(equippedItem.getPointId()));
            }
        }

        return rVal;
    }

}
