// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
//      Magicbane Emulator Project © 2013 - 2022
//                www.magicbane.com


package engine.objects;

import engine.Enum;
import engine.Enum.ItemType;
import engine.gameManager.DbManager;
import org.pmw.tinylog.Logger;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

public class ItemBase {

    public static ItemBase GOLD_ITEM_BASE = null;
    public static int GOLD_BASE_ID = 7;
    public static HashMap<Integer, ItemBase> _itemBaseByUUID = new HashMap<>();
    private static final HashMap<Integer, Integer> itemHashIDMap = new HashMap<>();
    private static final HashMap<String, Integer> _IDsByNames = new HashMap<>();
    private static final ArrayList<ItemBase> _resourceList = new ArrayList<>();
    public final int uuid;

    private final int modTable;
    private final int useID;
    private int hashID;
    private final byte useAmount;

    private final short percentRequired;
    private final short defense;
    private final float dexPenalty;
    private final float speed;
    private final float range;
    private final short minDamage;
    private final short maxDamage;
    private final String mastery;
    private final engine.Enum.SourceType damageType;
    private boolean isConsumable;
    private final boolean isStrBased;
    private ArrayList<Integer> animations = new ArrayList<>();
    private ArrayList<Integer> offHandAnimations = new ArrayList<>();

    public ItemBase(ResultSet rs) throws SQLException {

        this.uuid = rs.getInt("ID");
        this.useID = rs.getInt("useID");
        this.useAmount = rs.getByte("useAmount");
        this.modTable = rs.getInt("modTable");
        this.hashID = rs.getInt("itemHashID");

        this.isConsumable = false;
        this.percentRequired = rs.getShort("percentRequired");
        this.defense = rs.getShort("defense");
        this.dexPenalty = rs.getFloat("dexPenalty");
        this.isStrBased = (rs.getInt("isStrBased") == 1);
        this.speed = rs.getFloat("speed");
        this.range = rs.getFloat("range");
        this.minDamage = rs.getShort("minDamage");
        this.maxDamage = rs.getShort("maxDamage");

        this.mastery = rs.getString("mastery");
        damageType = Enum.SourceType.valueOf(rs.getString("damageType").toUpperCase());

        ItemTemplate template = ItemTemplate.itemTemplates.get(this.getUUID());

        if (template == null)
            Logger.error(this.getUUID() + " null template");
        else
            switch (ItemTemplate.itemTemplates.get(this.getUUID()).item_type) {
                case RUNE:
                case SCROLL:
                case WAND:
                case POTION:
                case CHARTER:
                case DEED:
                case EMPLOYMENTCONTRACT:
                case BUCKET:
                case REALMCHARTER:
                case TREASURE:
                case OFFERING:
                    this.isConsumable = true;
                    break;
            }

        try {
            DbManager.ItemBaseQueries.LOAD_ANIMATIONS(this);
        } catch (Exception e) {
            Logger.error(e.getMessage());
        }
        initializeHashes();

    }

    public static void addToCache(ItemBase itemBase) {

        _itemBaseByUUID.put(itemBase.uuid, itemBase);

        if (ItemTemplate.itemTemplates.get(itemBase.uuid).item_type.equals(ItemType.RESOURCE))
            _resourceList.add(itemBase);

        ItemTemplate template = ItemTemplate.itemTemplates.get(itemBase.uuid);

        if (template == null)
            Logger.error("Null template for: " + itemBase.uuid);
        else
            _IDsByNames.put(template.item_base_name.toLowerCase().replace(" ", "_"), itemBase.uuid);
    }

    public static HashMap<Integer, Integer> getItemHashIDMap() {
        return itemHashIDMap;
    }

    public static ItemBase getItemBase(int uuid) {

        return _itemBaseByUUID.get(uuid);
    }

    public static ItemBase getGoldItemBase() {
        if (ItemBase.GOLD_ITEM_BASE == null)
            ItemBase.GOLD_ITEM_BASE = getItemBase(7);
        return ItemBase.GOLD_ITEM_BASE;
    }

    public static int getIDByName(String name) {
        if (ItemBase._IDsByNames.containsKey(name))
            return ItemBase._IDsByNames.get(name);
        return 0;
    }

    public static HashMap<Integer, ItemBase> getUUIDCache() {
        return _itemBaseByUUID;
    }

    public static ArrayList<ItemBase> getResourceList() {
        return _resourceList;
    }

    public static void loadAllItemBases() {
        DbManager.ItemBaseQueries.LOAD_ALL_ITEMBASES();
    }

    public boolean isConsumable() {
        return this.isConsumable;
    }

    public boolean isDiscRune() {
        int ID = uuid;
        //class, discipline runes
        return ID > 2499 && ID < 3050;
    }

    public boolean isGlass() {
        int ID = uuid;
        return ID > 7000099 && ID < 7000281;
    }

    public final void initializeHashes() {
        itemHashIDMap.put(this.hashID, uuid);

    }

    public int getUseID() {
        return this.useID;
    }

    public byte getUseAmount() {
        return this.useAmount;
    }

    public int getModTable() {
        return modTable;
    }

    public int getHashID() {
        return hashID;
    }

    public final int getUUID() {
        return uuid;
    }
    public String getMastery() {
        return mastery;
    }

    public short getDefense() {
        return defense;
    }

    public float getDexPenalty() {
        return dexPenalty;
    }

    public float getSpeed() {
        return speed;
    }

    public float getRange() {
        return range;
    }

    public boolean isStrBased() {
        return isStrBased;
    }

    public short getMaxDamage() {
        return maxDamage;
    }

    public short getMinDamage() {
        return minDamage;
    }

    public Enum.SourceType getDamageType() {
        return damageType;
    }

    public short getPercentRequired() {
        return percentRequired;
    }

    public ArrayList<Integer> getAnimations() {
        return animations;
    }

    public void setAnimations(ArrayList<Integer> animations) {
        this.animations = animations;
    }

    public ArrayList<Integer> getOffHandAnimations() {
        return offHandAnimations;
    }

    public void setOffHandAnimations(ArrayList<Integer> offHandAnimations) {
        this.offHandAnimations = offHandAnimations;
    }

}