using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System; 

abstract public class BasePanelController : MonoBehaviour 
{
    [Header("Panel Information")]
    [SerializeField] protected GameObject _panel;
    [SerializeField] protected GameObject _blankSlot;
    [SerializeField] protected Button _panelCloseButton;

    [Header("Object Informations")]
    [SerializeField] protected GameObject _instance;
    
    // SYF
    [Header("Dragged Informations")]
    [SerializeField] protected Image _itemTemplate;
    [SerializeField] protected Image _tmp;


    [Header("Slots List")]
    [SerializeField] public int MAX_SLOT_CUNT = 6 * 8;
    [SerializeField] public List<ISlot> _itemSlots = new List<ISlot>();

    public void Awake()
    {
        _instance = gameObject;

        this.InitPanelSlots();
    }

    void Start()
    {
        if(_panelCloseButton)
        {
            _panelCloseButton.onClick.AddListener(CloseOnClick);
        }
    }

    public abstract void CloseOnClick();


    #region Main logic
    protected abstract ISlot SetupSlot(int key, GameObject _parent);

    public void SetupDragAndDropToSlot(ISlot slot)
    {
        slot.OnBeginDragEvent += BeginDrag;
        slot.OnEndDragEvent += EndDrag;
        slot.OnDragEvent += Drag;
        slot.OnDropEvent += Drop;
    }

    protected void InitPanelSlots()
    {
        if(_panel)
        {
            for(int i = 0; i < MAX_SLOT_CUNT; i++)
            {
                ISlot newSlot = SetupSlot(i, _panel);

                // Set new Slot instance
                _itemSlots.Add(newSlot);

                // Assign events
                this.SetupDragAndDropToSlot(_itemSlots[i]);
            } 
        }
    }

    protected void MakeDraggableItem(ItemSlot itemSlot)
    {
        if(_tmp)
        {
            _tmp.enabled = true;

            return;
        }
        
        GameObject globalGUI =  GameObject.FindGameObjectsWithTag("GUI")[0];

        if(globalGUI)
        {
            _tmp = Instantiate(_itemTemplate, _itemTemplate.transform.position, Quaternion.identity, globalGUI.transform);
            _tmp.transform.localPosition = _panel.transform.position;
            _tmp.sprite = itemSlot.Item.Image;
            _tmp.transform.position = Input.mousePosition;
            _tmp.enabled = true;
        } else {
            Debug.Log("Can't find global GUI object!!!");
        }
    }
    #endregion

    #region setup panel with content
    public void Setup(Dictionary<int, Item> _items)
    {
        SetPanelItems(_items);
    }

    private void SetPanelItems(Dictionary<int, Item> _items)
    {    
        foreach(int key in _items.Keys)
        {
            _itemSlots[key].SetItem(_items[key]);
        }    
    }
    #endregion

    #region base panel operations
    public bool AddItem(Item _item)
    {
        for(int i = 0; i < _itemSlots.Count; i++)
        {
            if(_itemSlots[i].Item == null)
            {
                _itemSlots[i].Item = _item;
                return true;
            }
        }
        return false;
    }

    public bool RemoveItem(Item _item)
    {
        for(int i = 0; i < _itemSlots.Count; i++)
        {
            if(_itemSlots[i].Item == _item)
            {
                _itemSlots[i].Item = null;
                return true;
            }
        }
        return false;
    }

    public bool IsFull()
    {
        for(int i = 0; i < _itemSlots.Count; i++)
        {
            if(_itemSlots[i].Item == null)
            {
                return false;
            }
        }
        return true;
    }
    #endregion

    #region Drag & Drop
    public void BeginDrag(ItemSlot itemSlot)
    {
        if (itemSlot.Item != null)
        {
            InventoryManager.Instance.DraggedSlot = itemSlot;

            MakeDraggableItem(itemSlot);
        }
    }

    public void EndDrag(ItemSlot itemSlot)
    {
        InventoryManager.Instance.DraggedSlot = null;

        DestroyImmediate(_tmp.gameObject, true);

        // apply list of items
        for (int i = 0; i < _itemSlots.Count; i++)
        {
            if (_itemSlots[i].Item != null)
            {
                _instance.GetComponent<BaseWarehouseController>().SetItemOnPosition(i, _itemSlots[i].Item);
            }
            else
            {
                _instance.GetComponent<BaseWarehouseController>().RemoveItemFromPosition(i);
            }
        }
    }

    public void Drag(ItemSlot itemSlot)
    {
        _tmp.transform.position = Input.mousePosition;
    }

    public void Drop(ItemSlot dropItemSlot)
    {
        if (dropItemSlot.CanReceiveItem(InventoryManager.Instance.DraggedSlot.Item) && InventoryManager.Instance.DraggedSlot.CanReceiveItem(dropItemSlot.Item))
        {
            EquippableItem dragItem = InventoryManager.Instance.DraggedSlot.Item as EquippableItem;
            EquippableItem dropItem = dropItemSlot.Item as EquippableItem;

            // for changing chest to evuuipment or onventory panel !!!!

            // if(draggedSlot is EquipmentSlot)
            // {
            //     if(dragItem != null) dragItem.Unequip(this);
            //     if(dropItem != null) dropItem.Equip(this);
            // }

            // if(dropItemSlot is EquipmentSlot)
            // {
            //     if(dragItem != null) dragItem.Equip(this);
            //     if(dropItem != null) dropItem.Unequip(this);
            // }

            Item draggedItem = InventoryManager.Instance.DraggedSlot.Item;  // remember temporary currently dragged item


            InventoryManager.Instance.DraggedSlot.Item = dropItemSlot.Item;
            dropItemSlot.Item = draggedItem;

            _instance.GetComponent<BaseWarehouseController>().SetItemOnPosition(InventoryManager.Instance.DraggedSlot.Number, InventoryManager.Instance.DraggedSlot.Item);
            _instance.GetComponent<BaseWarehouseController>().SetItemOnPosition(dropItemSlot.Number, dropItemSlot.Item);
        }
    }
    #endregion
}