using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;

[Serializable]
[RequireComponent(typeof(XRSocketInteractor))]
public class InventorySlot : MonoBehaviour
{
    private XRSocketInteractor xrSocketInteractor;

    private GameObject _itemInSlot;

    private Inventory _parentInventory;

    private void Awake()
    {
        xrSocketInteractor = GetComponent<XRSocketInteractor>();
        var oldestInteractableSelected = xrSocketInteractor.GetOldestInteractableSelected();

        
        xrSocketInteractor.selectEntered.AddListener(SelectEnter);
        xrSocketInteractor.selectExited.AddListener(SelectExit);
        
        xrSocketInteractor.hoverEntered.AddListener(HoverEnter);
        xrSocketInteractor.hoverExited.AddListener(HoverExit);
        
        
    }

    private void HoverEnter(HoverEnterEventArgs args)
    {
        if (_itemInSlot == null) return;
        if (_itemInSlot.GetComponent<InventoryItem>() == null) return;
        if (_itemInSlot == args.interactableObject.transform.gameObject) return;
        
        //Debug.Log("hoverenter "+args.interactableObject + " " + xrSocketInteractor.hasHover + " " + xrSocketInteractor.hasSelection);
        
        var newItem = args.interactableObject.transform.gameObject;

        var itemData = newItem.GetComponentInChildren<ItemData>();
        Debug.Log("HOVER ENTER: "+itemData);
        if (itemData.canStack && itemData.itemId == _itemInSlot.GetComponentInChildren<ItemData>().itemId)
        {
            var inventoryItem = newItem.GetComponent<InventoryItem>();
            
            if (inventoryItem != null)
            {
                _itemInSlot.GetComponent<InventoryItem>().ChangeCount(inventoryItem.Count);
            }
            else
            {
                _itemInSlot.GetComponent<InventoryItem>().ChangeCount(1);
            }
            
            args.manager.interactableUnregistered += ManagerOninteractableUnregistered;
            args.manager.UnregisterInteractable(args.interactableObject);
            args.manager.interactableUnregistered -= ManagerOninteractableUnregistered;
        }

    }
    
    
    private void HoverExit(HoverExitEventArgs args)
    {
        Debug.Log("hoverexit "+args.interactableObject + " " + xrSocketInteractor.hasHover + " " + xrSocketInteractor.hasSelection);
    }

    private void SelectEnter(SelectEnterEventArgs args)
    {
        Debug.Log("Added to slot item " + _itemInSlot);
        var newItem = args.interactableObject.transform.gameObject;
        

        //Converts the item into a inventory item 
        if (newItem.GetComponent<InventoryItem>() == null && newItem.GetComponent<ItemData>().canStack)
        {

            var load = Resources.Load("Helar/Item", typeof(GameObject)) as GameObject;
            
            var instance = Instantiate(load, args.interactorObject.transform);
            
            instance.GetComponent<InventoryItem>().itemPrefab = newItem.gameObject;

            instance.transform.localScale = Vector3.one;
            instance.transform.localPosition = Vector3.zero;
            
            instance.GetComponent<InventoryItem>().enabled = true;
            
            
            args.manager.interactableUnregistered += ManagerOninteractableUnregistered;
            args.manager.UnregisterInteractable(args.interactableObject);
            args.manager.interactableUnregistered -= ManagerOninteractableUnregistered;

            args.interactableObject = instance.GetComponent<XRGrabInteractable>();

            args.interactorObject.interactablesSelected.Add(instance.GetComponent<XRGrabInteractable>());
            
            Debug.Log("Upgraded item to InventoryItem "+instance);
            

            _itemInSlot = instance;
            return;
        }
        
        _itemInSlot = newItem;
        //xrSocketInteractor.attachTransform = _itemInSlot.transform;
        Debug.Log("Holstered item" + _itemInSlot.GetComponentInChildren<ItemData>());
    }

    private void ManagerOninteractableUnregistered(InteractableUnregisteredEventArgs obj)
    {
        Debug.Log("Removing object "+ obj);
        Destroy(obj.interactableObject.transform.gameObject);
    }

    private void SelectExit(SelectExitEventArgs args)
    {
        if (_itemInSlot == null) return;
        if (_itemInSlot.GetComponent<InventoryItem>() == null) return;

        var component = _itemInSlot.GetComponent<Rigidbody>();
        component.useGravity = true;
        component.angularDrag = 2f;
        component.drag = 0.5f;
        
        if (!_itemInSlot.GetComponentInChildren<ItemData>().canStack ||
            _itemInSlot.GetComponent<InventoryItem>().Count == 1)
        {
            //var transformGameObject = _itemInSlot.GetComponentInChildren<ItemData>().transform.gameObject;
            //Debug.Log(transformGameObject);
            //args.interactableObject = transformGameObject.GetComponent<XRGrabInteractable>();
            //todo change back to regular item
        }
        Debug.Log("Removed from slot item " + _itemInSlot);
        _itemInSlot = null;
    }

    public void SetParentInventory(Inventory inventory)
    {
        _parentInventory = inventory;
    }

    public bool ContainsItem()
    {
        return _itemInSlot != null;
    }
    
    public bool ContainsItem(int id)
    {
        if (!ContainsItem()) return false;


        var inventoryItem = _itemInSlot.GetComponent<InventoryItem>();
        if (inventoryItem != null) return inventoryItem.GetItemid() == id;
        
        return false;
    }

    public void AssignItem(GameObject newObject)
    {
        _itemInSlot = newObject;
    }

    public InventoryItem GetItem()
    {
        var inventoryItem = _itemInSlot.GetComponent<InventoryItem>();
        if (inventoryItem == null) Debug.LogError("Item in slot doesn't have InventoryItem component");
        return inventoryItem;
    }
}