using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;

public abstract class UIWarehouseManager : UISlotPanelManager<IndexValuePair<int, EquippableItem>>
{
    public override int SLOTS_NUMBER => 48;

    public static new UIWarehouseManager Instance { get; protected set; }
    /*
     * not sure why but childrens of this class dont interfere on parents Awake
     */

    /// <summary>
    /// Function to find item in warehouser by its id, returns list of all slots where item occured
    /// </summary>
    /// <param name="itemId"></param>
    /// <returns></returns>
    public override List<IndexValuePair<int, EquippableItem>> FindItemInWarehouse(int itemId)
    {
        return Elements.Where(item => item.Value.Id == itemId).ToList();
    }

    /// <summary>
    /// Function to find item in warehouser by its name, returns list of all slots where item occured
    /// </summary>
    /// <param name="itemId"></param>
    /// <returns></returns>
    public override List<IndexValuePair<int, EquippableItem>> FindItemInWarehouseByName(string itemName)
    {
        return Elements.Where(item => item.Value.name == itemName).ToList();
    }



    /// <summary>
    /// Function (SetItemOnPosition) to add slot with its number and item to list (which will be mapped with panel content)
    /// </summary>
    /// <param name="itemOnSlot"></param>
    public virtual void Add(IndexValuePair<int, EquippableItem> itemOnSlot)
    {
        if (!CheckIfSlotIsInRange(itemOnSlot.Key))
            throw new System.Exception($"Slot number: {itemOnSlot.Key} is out of range, avaiable: {SLOTS_NUMBER} slots");

        if (CheckIfSlotExists(itemOnSlot.Key) && !CheckIfPositionIsEmpty(itemOnSlot.Key))
            RemoveByPosition(itemOnSlot.Key);

        if(itemOnSlot.Value != null)
        {
            base.Add(itemOnSlot);
        }
    }

    /// <summary>
    /// Function to add item on first empty slot to list (which will be mapped with panel content)
    /// </summary>
    /// <param name="item"></param>
    public virtual void Add(EquippableItem item)
    {
        if(IsFull())
            throw new System.Exception($"Warehouse is full!!!");

        // find first empty position / slot
        var max = 0;
        if(Elements.Count() > 0) 
        { 
            for (int i = 0; i < SLOTS_NUMBER; i++) 
            {
                if (Elements.Where(el => el.Key == i && el.Value != null).Count() != 0)
                    continue;
                
                max = i;
                break; 
            } 
        }

        base.Add(new IndexValuePair<int, EquippableItem>(max, item));
    }


    public override void RemoveByPosition(int keyPosition)
    {
        if (!CheckIfSlotExists(keyPosition))
            return; // throw new System.Exception($"Slot with number: {keyPosition} don't exist");

        Debug.Log($"Remove from position: {keyPosition}");

        Elements.RemoveAll(itemSlot => itemSlot.Key == keyPosition);
    }

    public override int RemoveByItemId(int itemId)
    {
        return Elements.RemoveAll(itemSlot => itemSlot.Value.Id == itemId);
    }

    public override int RemoveByItemName(string itemName)
    {
        return Elements.RemoveAll(itemSlot => itemSlot.Value.Name == itemName);
    }

    protected override bool CheckIfSlotExists(int slotNumber)
    {
        return Elements.Any(itemSlot => itemSlot.Key == slotNumber);
    }

    /// <summary>
    /// Check if slot is empty in local list
    /// </summary>
    /// <returns></returns>
    protected override bool CheckIfPositionIsEmpty(int slotNumber)
    {
        if(CheckIfSlotExists(slotNumber)) {
            return Elements.Where(itemSlot => itemSlot.Key == slotNumber).First().Value == null;
        }

        return true;
    }
}