using Photon.Pun;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace Kryz.CharacterStats.Examples
{
    public class Inventory : MonoBehaviour
    {
        [SerializeField] List<Item> items;
        [SerializeField] Transform itemsParent;
        [SerializeField] ItemSlot[] itemSlots;
        [SerializeField] GameObject characterPanelUI;

        [SerializeField] GameEventListener onJoinedRoom;

        public UnityEvent_Item OnItemRightClickedEvent = new UnityEvent_Item();
        public UnityEvent_Item OnItemRightClickedEventWhileVendoring = new UnityEvent_Item();

        InventoryData inventoryData = new InventoryData();

        public bool isVendoring;

        #region Singleton
        private static Inventory _instance;

        // Public reference to the singleton instance
        public static Inventory Instance
        {
            get
            {
                // If the instance doesn't exist, try to find it in the scene
                if (_instance == null)
                {
                    _instance = FindObjectOfType<Inventory>();
                }
                return _instance;
            }
        }
        #endregion

        private void Awake()
        {
            for (int i = 0; i < itemSlots.Length; i++)
            {
                itemSlots[i].OnRightClickEvent.AddListener(HandleItemSlotOnRightClick);
            }

            onJoinedRoom.Response.AddListener(LoadInventory);
        }

        private void HandleItemSlotOnRightClick(Item item)
        {
            if(isVendoring)
            {
                OnItemRightClickedEventWhileVendoring.Invoke(item);
            }
            else
            {
                OnItemRightClickedEvent.Invoke(item);
            }
        }

        private void Start()
        {
            RefreshUI(false);
        }

        private void OnValidate()
        {
            if (itemsParent != null)
            {
                itemSlots = itemsParent.GetComponentsInChildren<ItemSlot>();
                RefreshUI(false);
            }
        }

        private void RefreshUI(bool shouldSave)
        {
            int i = 0;
            for (; i < items.Count && i < itemSlots.Length; i++)
            {
                itemSlots[i].Item = items[i];

                if (ItemIndexer.Instance != null)
                    inventoryData.inventoryItems[i] = ItemIndexer.Instance.Items.IndexOf(items[i]);

            }

            for (; i < itemSlots.Length; i++)
            {
                itemSlots[i].Item = null;

                inventoryData.inventoryItems[i] = -1;
            }
            if (!Application.isPlaying) return;
            if (!PhotonNetwork.IsConnected) return;
            if (!PhotonNetwork.InRoom) return;
            if (!shouldSave) return;

            PlayerDataHandler.Instance.SaveCharacterInventoryData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value, inventoryData);
        }

        public bool AddItem(Item item)
        {
            if (IsFull())
                return false;

            items.Add(item);

            RefreshUI(true);
            return true;
        }

        public bool RemoveItem(Item item)
        {
            if (items.Remove(item))
            {
                RefreshUI(true);
                return true;
            }
            return false;
        }

        public bool IsFull()
        {
            return items.Count >= itemSlots.Length;
        }

        public void LoadInventory()
        {
            inventoryData = PlayerDataHandler.Instance.LoadCharacterInventoryData(PlayerDataHandler.Instance.currentPlayerName.Value, PlayerDataHandler.Instance.currentCharacterName.Value);

            if (inventoryData != null)
            {
                Debug.Log("Success Loading Inventory");
                for (int i = 0; i < inventoryData.inventoryItems.Length; i++)
                {
                    if (inventoryData.inventoryItems[i] < 0) continue;

                    items.Add(ItemIndexer.Instance.Items[inventoryData.inventoryItems[i]]);
                }

                RefreshUI(false);
            }
            else
                inventoryData = new InventoryData();
        }

        public void OpenInventory()
        {
            characterPanelUI.SetActive(true);
        }
        public void CloseInventory()
        {
            characterPanelUI.SetActive(false);
        }
    }
}
