using System;

namespace XGame.Framework.Time
{
    public class Alarm : IAlarm, IDisposable
    {
        public enum AlarmRunState : sbyte
        {
            None,
            Running,
            Stoped,
            Finished,
        }

        private long _triggerTimeStamp;
        private long _curTimeStamp;
        private Action _action;
        private AlarmRunState _runState;

        public Alarm(Action action, long curTimeStamp, long triggerTimeStamp)
        {
#if UNITY_EDITOR
            UnityEngine.Assertions.Assert.IsTrue(triggerTimeStamp > curTimeStamp, "设置闹钟触发时间不能小于或者等于当前时间");
#endif
            _triggerTimeStamp = triggerTimeStamp;
            _curTimeStamp = curTimeStamp;
            _action = action;
            _runState = AlarmRunState.Running;
        }

        public void SetTime(long timestamp)
        {
            if (_runState == AlarmRunState.Running)
            {
                _curTimeStamp = timestamp;
            }
        }

        public void Cancel()
        {
            _runState = AlarmRunState.Stoped;
            _action = null;
        }

        public bool Update(int elapse)
        {
            if (_runState != AlarmRunState.Running)
            {
                return true;
            }

            _curTimeStamp += elapse;
            if (_curTimeStamp >= _triggerTimeStamp)
            {
                _runState = AlarmRunState.Finished;
                try
                {
                    _action?.Invoke();
                }
                catch (Exception e)
                {
                    Log.Exception("闹钟回调执行发生异常", e);
                    //throw new Exception($"闹钟回调执行发生异常:{e}");
                }
                return true;
            }

            return false;
        }

        public void Dispose()
        {
            _action = null;
        }
    }
}