using System;
using System.Collections.Generic;
using System.Linq;
using Entitas;
using JNGame.Sync.Entity;
using JNGame.Sync.Frame.Entity;
using JNGame.Sync.Frame.Service;
using JNGame.Sync.System;
using JNGame.Sync.System.View;
using UnityEngine;

namespace JNGame.Sync.Frame
{
    public abstract class JNSyncDefaultService : JNSyncService
    {
        
        private SBaseSystem[] _allSystems;
        protected override JNBaseSystem[] AllSystems => _allSystems;

        public JNContexts Contexts;
        
        public abstract bool IsStartGame { get; }
        

        public JNSyncDefaultService() : base()
        {
            
        }

        public override void Initialize()
        {
            base.Initialize();
            
            Contexts = CreateContexts();
            Contexts.Sync = this;
            Contexts.InitReference(this);
            var systems = new List<SBaseSystem>();
            systems.Add(CreateRandom());
            systems.AddRange(NewLogicSystems());
            systems.AddRange(NewDataSystems());
            systems.AddRange(NewViewSystems());
            _allSystems = systems.ToArray();
            
            foreach (var system in _allSystems)
            {
                system.Sync = this;
                system.Contexts = Contexts;
                Add(system);
            }
            
            Debug.Log("Initialize");
            
        }

        public override Systems Add(ISystem system)
        {
            (system as SLogicSystem)?.OnSyncStart();
            return base.Add(system);
        }

        public virtual JNContexts CreateContexts()
        {
            return new JNContexts();
        }
        
        //随机数系统
        public virtual JNRandomSystem CreateRandom()
        {
            return new JNRandomSystem(1000);
        }
        
        public virtual SLogicSystem[] NewLogicSystems()
        {
            return Array.Empty<SLogicSystem>();
        }
        
        public virtual SDataSystemBase[] NewDataSystems()
        {
            return Array.Empty<SDataSystemBase>();
        }
        
        public virtual SViewSystem[] NewViewSystems()
        {
            return Array.Empty<SViewSystem>();
        }

        /// <summary>
        /// 自动更新视图帧
        /// </summary>
        public override void Execute()
        {
            
#if (!ENTITAS_DISABLE_VISUAL_DEBUGGING && UNITY_EDITOR)
            if (paused) return;
#endif
            base.Execute();
            
        }

        /// <summary>
        /// 推逻辑帧
        /// </summary>
        public void Simulate()
        {
            
#if (!ENTITAS_DISABLE_VISUAL_DEBUGGING && UNITY_EDITOR)
            SyncDuration = 0;
            var timeSimulate = DateTime.Now.Ticks;
#endif
            
            for (int i = 0; i < _syncSystems.Count; i++)
            {

                
#if (!ENTITAS_DISABLE_VISUAL_DEBUGGING && UNITY_EDITOR)
                if (syncSystemInfos[i].isActive){

                    var time = DateTime.Now.Ticks;
                    _syncSystems[i].OnSyncUpdate();
                    double time1 = (DateTime.Now.Ticks - time) / 10000f;
                    syncSystemInfos[i].AddSyncUpdateDuration(time1);
                    
                }
#else
                _syncSystems[i].OnSyncUpdate();
#endif
            }
            
            //给实体推帧
            Contexts.Simulate();
            
#if (!ENTITAS_DISABLE_VISUAL_DEBUGGING && UNITY_EDITOR)
            SyncDuration = (DateTime.Now.Ticks - timeSimulate) / 10000f;
#endif

        }

    }
        
}