using System;

namespace XGame.Framework.Time
{
    public class Clock : IClock
    {
        private AlarmRepository _clientAlarmRepo;
        private AlarmRepository _serverAlarmRepo;
        private TimerRepository _timerRepo;

        public Clock(long timeStamp)
        {
            var realTime = UnityEngine.Time.realtimeSinceStartup;
            _clientAlarmRepo = new AlarmRepository()
            {
                time = new TimeStamp()
                {
                    realtimeSinceStartup = realTime,
                    timeStamp = timeStamp
                }
            };
            _serverAlarmRepo = new AlarmRepository()
            {
                time = new TimeStamp()
                {
                    realtimeSinceStartup = realTime,
                    timeStamp = timeStamp
                }
            };
            _timerRepo = new TimerRepository();
        }
        private AlarmRepository GetAlarmRepository(ClockType clockTyp = ClockType.Server)
        {
            return clockTyp == ClockType.Server ? _serverAlarmRepo : _clientAlarmRepo;
        }
        public void SetTime(long timestamp, ClockType clockTyp = ClockType.Server)
        {
            GetAlarmRepository(clockTyp).SetTime(timestamp);
        }
        public long GetNowTime(ClockType clockTyp = ClockType.Server)
        {
            var alarmTime = GetAlarmRepository(clockTyp).time;
            return alarmTime.timeStamp + (long)((UnityEngine.Time.realtimeSinceStartup - alarmTime.realtimeSinceStartup) * 1000);
        }
        public IAlarm AddAlarm(long triggerTimestamp, Action action, ClockType clockTyp = ClockType.Server)
        {
            return GetAlarmRepository(clockTyp).AddAlarm(action, GetNowTime(clockTyp), triggerTimestamp);
        }

        public ITimer AddDelayTimer(int delay, Action action)
        {
            return _timerRepo.AddDelayTimer(delay, action);
        }

        public ITimer AddLooperTimer(int delay, int interval, Action<int> action, int loopTime = -1)
        {
            return _timerRepo.AddLooperTimer(delay, interval, action, loopTime);
        }

        public void Update(int millisecond)
        {
            _clientAlarmRepo.ClockUpdate(millisecond);
            _serverAlarmRepo.ClockUpdate(millisecond);
            _timerRepo.ClockUpdate(millisecond);
        }

        public void Dispose()
        {
            _clientAlarmRepo.Dispose();
            _serverAlarmRepo.Dispose();
            _timerRepo.Dispose();
        }
    }
}