using System.Collections.Generic;
using System.Linq;
using NBC;
using UnityEngine;

namespace NBF
{
    /// <summary>
    /// loading进度任务
    /// </summary>
    public class LoadingTask<T> where T : UIPanel
    {
        public static readonly string LoadingTips = "Loading...";
        private NTask _currentTask;
        private readonly List<NTask> _tasks = new();

        private StepType _step = StepType.Idle;

        private float _time = 0;

        public float Progress => _currentTask?.Progress ?? 0;

        public string Info => _currentTask != null ? _currentTask.Info : LoadingTips;

        public int Count => _tasks.Count;


        public LoadingTask()
        {
            Game.OnUpdate += OnUpdate;
        }

        enum StepType
        {
            Idle,
            Run,
            FinishWait,
            Done
        }

        public void Reset()
        {
            _time = 0;
            _tasks.Clear();
            _currentTask = null;
        }

        public void TryEnd()
        {
            foreach (var task in _tasks)
            {
                if (task is LoadingWaitTask<T> waitTask)
                {
                    waitTask.End();
                }
            }
        }

        public void ForceEnd()
        {
            _step = StepType.Done;
            // StatusChange?.Invoke();
        }

        public void Add(NTask task)
        {
            if (_currentTask == null)
            {
                if (_tasks.Count < 1)
                {
                    Reset();
                    _step = StepType.Idle;
                }

                _currentTask = task;
            }

            _tasks.Add(task);
            if (_currentTask is LoadingWaitTask<T> && _tasks.Count > 1)
            {
                //如果当前是wait
                foreach (var t in _tasks.Where(t => t is not LoadingWaitTask<T>))
                {
                    _currentTask = t;
                    break;
                }
            }
        }


        protected void OnUpdate()
        {
            if (_step == StepType.Done)
            {
                return;
            }

            // var st = TaskStatus.Running;
            var dongCount = 0;
            foreach (var task in _tasks)
            {
                if (task.Status >= NTaskStatus.Success)
                {
                    dongCount++;
                }
            }

            _step = dongCount >= _tasks.Count ? StepType.FinishWait : StepType.Run;

            if (_step == StepType.FinishWait)
            {
                _time += Time.deltaTime;
                if (_tasks.Count > 0)
                {
                    _step = StepType.Run;
                }

                if (_time >= 0.3f)
                {
                    End();
                }
            }
        }

        private void End()
        {
            _step = StepType.Done;
            UI.Inst.HideUI<T>();
            // Game.Main.TimerComponent.Unity.OnceTimer()
            Timer.FrameOnce(1, this, _ => { Reset(); });
        }
    }

    public class LoadingWaitTask<T> : NTask where T : UIPanel
    {
        protected override void OnStart()
        {
            Info = LoadingTask<T>.LoadingTips;
        }

        public void End()
        {
            Finish();
        }
    }
}