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

public class LogicTrayUI : LogicElementHolder
{

    //[SerializeField]
    //protected List<LogicBlock> list;
    [SerializeField]
    protected LogicElementUI Prefab;
    [SerializeField]
    protected int insertIndex = -1;
    [SerializeField]
    private Transform content;

    [SerializeField]
    protected BlockReader reader;

    #region Unity Functions
    public void Start()
    {
        UpdateDisplay();
    }

    protected override void OnEnable()
    {
        base.OnEnable();
        if (reader != null)
            reader.OnUpdate += UpdateDisplay;
    }

    protected override void OnDisable()
    {
        base.OnDisable();
        if (reader != null)
            reader.OnUpdate -= UpdateDisplay;
    }
    #endregion Unity Functions

    public void SetBlockReader(BlockReader newBlockReader)
    {
        if (reader != null)
            reader.OnUpdate -= UpdateDisplay;

        reader = newBlockReader;
        reader.OnUpdate += UpdateDisplay;
        UpdateDisplay();
    }

    [ContextMenu("Update Display")]
    public void UpdateDisplay()
    {
        //Destroy all children
        int destroyedCount = content.childCount; //we need to know how many were destroyed since unity doesn't actually destroy anything until the end of the frame
        foreach (Transform child in content)
            Destroy(child.gameObject);

        //Instatiate logicElement prefab
        foreach (LogicBlock element in reader.LogicChain)
        {
            LogicElementUI elementUI = Instantiate(Prefab.gameObject, content).GetComponent<LogicElementUI>();
            elementUI.Initialise(element, this);
        }

        //Add insertIndex object if needed
        if (insertIndex != -1)
        {
            GameObject elementObject = Instantiate(Prefab.gameObject, content);
            elementObject.GetComponentInChildren<TextMeshProUGUI>().text = "insert";
            elementObject.GetComponentInChildren<Image>().color = new Color(0.5f, 0.5f, 0.5f, 0.25f);

            //Set sibling index to where we want it in list + add destroyedCount since technically they are still here
            elementObject.transform.SetSiblingIndex(destroyedCount + insertIndex);
        }



    }

    #region LogicElementHolder Implementation

    /// <summary>
    /// When a LogicElement has started being dragged from this Tray
    /// </summary>
    /// <param name="element">Element which is being dragged</param>
    public override void OnRemove(LogicElementUI element)
    {
        reader.Remove(element.logicElement);
    }

    /// <summary>
    /// When a logicElement needs to be added back to this Tray
    /// </summary>
    /// <param name="element">Element to add</param>
    public override void OnAdd(LogicElementUI element)
    {
        int index = GetInsertIndex(element.rectTransform);
        reader.Insert(index, element.logicElement);

        Destroy(element.gameObject);
    }

    /// <summary>
    /// When a logic Element is hovering over this holder
    /// </summary>
    /// <param name="element">Element which is hovering</param>
    public override void OnHover(LogicElementUI element)
    {
        insertIndex = GetInsertIndex(element.rectTransform);
        UpdateDisplay();
    }

    /// <summary>
    /// First frame a logic Element is hovering over this holder
    /// </summary>
    /// <param name="element">Element which is hovering</param>
    public override void OnHoverStart(LogicElementUI element)
    {
        Debug.Log("OnHoverStart");
        //Create insert prefab at End
        insertIndex = content.childCount;
        UpdateDisplay();
    }

    /// <summary>
    /// first frame a logic Element is  no longer hovering over this holder
    /// </summary>
    /// <param name="element">Element which is hovering</param>
    public override void OnHoverEnd(LogicElementUI element)
    {
        //Remove insert prefab
        insertIndex = -1;
        UpdateDisplay();
    }
    #endregion LogicElementHolder Implementation

    #region Helper Functions

    public int GetInsertIndex(RectTransform rt)
    {
        Rect rect = rt.GlobalRect();

        foreach (Transform child in content)
        {
            RectTransform childRect = child as RectTransform;

            if (rect.Overlaps(childRect.GlobalRect()))
                return child.GetSiblingIndex();
        }
        return reader.LogicChain.Count;
    }

    #endregion Helper Functions

}
