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

/// <summary>
/// Racer Items controls item usage
/// All behaviors should be handled LOCALLY ONLY
/// </summary>

public class RacerItems : RacerCoreFeature
{
    [Header("Item Data")]
    #region
    [Tooltip("The current player item")]
    [SerializeField] [ReadOnly] ItemSO m_currentItem = null;
    [SerializeField] [ReadOnly] int m_currentItemIndex = -1;

    [SerializeField] ItemSO[] m_availableItems = new ItemSO[0];
    public ItemSO[] AvailableItems { get { return m_availableItems; } }

    //[Tooltip("Modifies how quickly a player builds up an item charge while holding the Fire input.")]
    //[Range(0.5f, 1.5f)]
    //[SerializeField] float m_chargeRate = 1f;
    //public float ChargeRate { get { return m_chargeRate; } }

    //[Tooltip("Tracks the total amount of firing charge the player has accumulated.")]
    //[ReadOnly]
    //[SerializeField] float m_chargeLevel = 0;
    //public float ChargeLevel { get { return m_chargeLevel; } }

    [Tooltip("The amount of time it takes to roll an item once an item box has been hit.")]
    [SerializeField] [Range(1, 5)] float m_timeToRoll = 3;
    #endregion

    [Header("Debug")]
    #region
    [SerializeField] DebugChannelSO m_debugChannel;
    #endregion

    // DELEGATES //
    #region
    public delegate void OnItemChargeUpdateAction(float _perc);
    public OnItemChargeUpdateAction OnItemChargeUpdate;

    public delegate void OnItemDisplayUpdateAction(Sprite _displayImage);
    public OnItemDisplayUpdateAction OnItemDisplayUpdate;
    #endregion

    // COROUTINES //
    #region
    IEnumerator co_itemRoll;
    #endregion

    // DEFAULT METHODS //
    #region
    new void OnEnable()
    {
        base.OnEnable();

        Core.Controller.OnFireStart += ActivateItem;
    }
    new void OnDisable()
    {
        base.OnEnable();

        Core.Controller.OnFireEnd -= ActivateItem;
    }
    private void Update()
    {
        #if UNITY_EDITOR
        if (Input.GetKeyDown(KeyCode.O))
            DebugSetItem();
        #endif
    }
    #endregion

    // ROLL ITEM METHODS //
    #region
    /// <summary>
    /// Rolls an item if the player has none
    /// </summary>
    public void RollItem()
    {
        // If our item array is not initilialized, return
        if (m_availableItems == null)
            return;

        // If we have no items in our array, return
        if (m_availableItems.Length == 0)
            return;

        // If we already have an item, return
        if (m_currentItem)
            return;

        // If we are already rolling an item, return
        if (co_itemRoll != null)
            return;
        
        // Start the roll!
        co_itemRoll = ItemRoll();
        StartCoroutine(co_itemRoll);
    }
    /// <summary>
    /// Item roll coroutine
    /// </summary>
    /// <returns></returns>
    IEnumerator ItemRoll()
    {
        float _timer = m_timeToRoll;
        int _currentDisplay = 0;

        while (_timer > 0)
        {
            _currentDisplay++;

            if (_currentDisplay == m_availableItems.Length)
                _currentDisplay = 0;
            
            // This is here to skip null entries in the item list.
            while (m_availableItems[_currentDisplay] == null)
            {
                _currentDisplay++;

                if (_currentDisplay == m_availableItems.Length)
                    _currentDisplay = 0;
            }
            
            if (OnItemDisplayUpdate != null)
                OnItemDisplayUpdate.Invoke(m_availableItems[_currentDisplay].ItemDisplaySprite);

            _timer -= 0.1f;
            yield return new WaitForSeconds(0.1f);
        }

        while (m_currentItem == null)
        {
            m_currentItemIndex = Random.Range(0, m_availableItems.Length);

            m_currentItem = m_availableItems[m_currentItemIndex];

            if (m_debugChannel)
                m_debugChannel.Raise(this, "Chose " + m_currentItem.name);
        }

        if (OnItemDisplayUpdate != null)
            OnItemDisplayUpdate.Invoke(m_availableItems[m_currentItemIndex].ItemDisplaySprite);
        
        co_itemRoll = null;

        yield return null;
    }
    #if UNITY_EDITOR
    void DebugSetItem()
    {
        if (m_currentItem != null)
            return;

        m_currentItemIndex = Random.Range(0, m_availableItems.Length);
        m_currentItem = m_availableItems[m_currentItemIndex];

        if (OnItemDisplayUpdate != null)
            OnItemDisplayUpdate.Invoke(m_availableItems[m_currentItemIndex].ItemDisplaySprite);
    }
    #endif
    #endregion

    // FIRE ITEM METHODS //
    #region
    void ActivateItem()
    {
        if (!m_currentItem)
            return;

        m_currentItem.Activate(Core);
        
        m_currentItem = null;

        if (OnItemDisplayUpdate != null)
            OnItemDisplayUpdate.Invoke(null);
    }
    #endregion
    // PHOTON / RPC //
    #region
    new public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        
    }
    #endregion
}
