using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Ingvar.LiveWatch
{
    /// <summary>
    /// Type for generic Watch methods when you don't know what type it is, or don't want use type based functionality
    /// </summary>
    public class Any
    {
        
    }
    
    public partial struct WatchReference<T>
    {
        internal WatchVariable WatchVariable { get; }

        public int ChildCount
        {
            get
            {
#if UNITY_EDITOR || LIVE_WATCH_BUILD
                return WatchVariable.Childs.Count;
#else  
                return 0;
#endif
            }
        }
        
        internal WatchReference(WatchVariable watchVariable)
        {
            WatchVariable = watchVariable;
        }

        public WatchReference<T> SetAlwaysCollapsable()
        {
#if UNITY_EDITOR || LIVE_WATCH_BUILD 
            WatchVariable.RuntimeMeta.AlwaysShrinkable = true;
#endif
            return this;
        }

        public WatchReference<T> SetDecimalPlaces(int value)
        {
#if UNITY_EDITOR || LIVE_WATCH_BUILD
            WatchVariable.RuntimeMeta.DecimalPlaces = value;
#endif
            return this;
        }

        public WatchReference<T> SetSortOrder(int value)
        {
#if UNITY_EDITOR || LIVE_WATCH_BUILD
            if (!WatchVariable.RuntimeMeta.IsOrderSet)
            {
                WatchVariable.RuntimeMeta.SortOrder = value;
                WatchVariable.RuntimeMeta.IsOrderSet = true;
                WatchVariable.RuntimeMeta.IsSortingRequired = true;
            }
#endif
            return this;
        }
        

        public WatchReference<T> UpdateOnce()
        {
#if UNITY_EDITOR || LIVE_WATCH_BUILD
            WatchVariable.RuntimeMeta.UpdateOnce = true;
#endif
            return this;
        }
        
        public WatchReference<T> PushEmptyValue(bool withRoot = true, int maxRecursionDepth = 10)
        {
#if UNITY_EDITOR || LIVE_WATCH_BUILD
            if (Watch.IsLive)
                WatchServices.ReferenceCreator.PushEmpty(this, withRoot, maxRecursionDepth);
#endif        
            return this;
        }

        public IEnumerable<string> GetChildNames()
        {
#if UNITY_EDITOR || LIVE_WATCH_BUILD
            return WatchVariable.Childs.SortedNames;
#else
            return Array.Empty<string>();
#endif
        }
        
        public WatchReference<V> GetOrAdd<V>(string path)
        {
#if UNITY_EDITOR || LIVE_WATCH_BUILD
            return WatchServices.ReferenceCreator.GetOrAdd<V, T>(this, path);
#else
            return WatchServices.ReferenceCreator.Empty<V>();
#endif
        }
    }
}