using System;
using System.Collections.Generic;

using System.Text;
using UnityEngine;

namespace Thousandto.Core.Base
{
    /// <summary>
    /// 每日时间分区的管理
    /// 并且管理游戏时间与真实时间的比例
    /// </summary>
    public class DayTimeSpanManager
    {
        #region //常量以及静态定义
        /// <summary>
        /// 把一天分成8个区段
        /// </summary>
        const int CHANGE_TIME_NUM = 8;
        /// <summary>
        /// 每个区段为3个小时
        /// </summary>
        const int DAY_TIMESPAN_SECONDS = (24 / CHANGE_TIME_NUM) * 3600;
        /// <summary>
        /// 开始位置,左下角 Vector3(-1, -1, 0);
        /// </summary>
        public static Vector3 StartPos = new Vector3(-1, -1, 0);
        /// <summary>
        /// 第一个1/4时间的位置,Vector3(-0.5f, -0.15f, 0);
        /// </summary>
        public static Vector3 OneQuarter = new Vector3(-0.5f, -0.15f, 0);
        /// <summary>
        /// 中间顶点位置,Vector3.zero;
        /// </summary>
        public static Vector3 MidPos = Vector3.zero;
        /// <summary>
        /// 第三个1/4时间的位置Vector3(0.5f, -0.15f, 0);
        /// </summary>
        public static Vector3 ThreeQuarter = new Vector3(0.5f, -0.15f, 0);
        /// <summary>
        /// 结束位置,右下角Vector3(1f, -1, 0);
        /// </summary>
        public static Vector3 EndPos = new Vector3(1f, -1, 0);
        #endregion

        #region//私有变量
        //区段记录
        private List<DayTimeSpan> _lstTimeSpan = new List<DayTimeSpan>();
        //当前区间
        private DayTimeSpan _curTimeSpan = null;        
        //时间心跳计数器
        private TimeIntervalConter _tic = null;
        //时间间隔
        private ulong _timeInterval = 60;
        //真实时间与游戏时间的比率
        private float _timeRatio = DAY_TIMESPAN_SECONDS; //真实时间6小时相当于游戏时间24小时,3小时切换一次
        
        #endregion
        #region//属性信息
        public DayTimeSpan CurrentTimeSpan
        {
            get
            {
                return _curTimeSpan;
            }
        }
        #endregion

        #region //公共接口
        //初始化处理
        public void Initialize()
        {   
            InitializeTimeSpan();
            InitializeTimeIntervalConter();
            UpdateDayTimeSpan();
        }
        //卸载
        public void Uninitialize()
        {
            if (_tic != null)
            {
                GameTimeManager.ShareInstance.RemoveTimeIntervalConter(_tic);
            }
        }

        //设置真实时间与游戏时间的比率
        public void SetDayTimeRatio(float rotio)
        {
            _timeRatio = rotio;
        }

        //设置心跳的时间间隔
        public void SetDayTimeInterval(ulong interval)
        {
            _timeInterval = interval;
            if (interval < GameTimeManager.ShareInstance.WaitTickTime)
            {
                GameTimeManager.ShareInstance.WaitTickTime = interval;
            }
            _tic.m_intervalSeconds = _timeInterval;
        }
        //增加心跳回调
        public void AddDayTimeTickCallBack(MyAction onTick)
        {
            if (_tic != null)
            {
                _tic.AddCallBack(onTick);
            } 
        }

        //移除心跳回调
        public void RemoveDayTimeTickCallBack(MyAction onTick)
        {
            if (_tic != null)
            {
                _tic.RemoveCallBack(onTick);
            } 
        }
        /// <summary>
        /// 北京时间6小时=游戏一天24小时 
        /// 把真实时间转换为游戏时间
        /// </summary>
        /// <param name="realTime"></param>
        public ulong ConvertRealToGameDayTime(ulong realTime)
        {
            return realTime * (12 * 3600 / (ulong)_timeRatio) % TimeConstDefine.OneDaySecond;  // 4 * 60 是6分钟
        }

        //更新每日时间区间
        public void UpdateDayTimeSpan()
        {
            UpdateDayTimeSpan(GameTimeManager.ShareInstance.CurrentTime);
        }
        #endregion

        #region//私有函数
        //初始化时间区段
        private void InitializeTimeSpan()
        {
            _curTimeSpan = null;
            //先清除
            if (_lstTimeSpan.Count > 0)
            {
                _lstTimeSpan.Clear();
            }

            //再进行初始化
            for (int i = 0; i < CHANGE_TIME_NUM; i++)
            {
                int startTime = i * DAY_TIMESPAN_SECONDS;
                int endTime = (i + 1) * DAY_TIMESPAN_SECONDS;
                _lstTimeSpan.Add(new DayTimeSpan(startTime, endTime));
            }
            _lstTimeSpan[0].TimeType = DayTimeSpanType.Night;
            _lstTimeSpan[0].SetMoonPos(MidPos, ThreeQuarter);
            _lstTimeSpan[0].IsDayLightMap = false;

            _lstTimeSpan[1].TimeType = DayTimeSpanType.Morning;
            _lstTimeSpan[1].SetMoonPos(ThreeQuarter, EndPos);
            _lstTimeSpan[1].IsDayLightMap = false;

            _lstTimeSpan[2].TimeType = DayTimeSpanType.Morning;
            _lstTimeSpan[2].SetSunPos(StartPos, OneQuarter);
            _lstTimeSpan[2].NeedChangeDayNight = true;
            _lstTimeSpan[2].IsDayLightMap = true;


            _lstTimeSpan[3].TimeType = DayTimeSpanType.Day;
            _lstTimeSpan[3].SetSunPos(OneQuarter, MidPos);
            _lstTimeSpan[3].IsDayLightMap = true;


            _lstTimeSpan[4].TimeType = DayTimeSpanType.Day;
            _lstTimeSpan[4].SetSunPos(MidPos, ThreeQuarter);
            _lstTimeSpan[4].IsDayLightMap = true;

            _lstTimeSpan[5].TimeType = DayTimeSpanType.Dusk;
            _lstTimeSpan[5].SetSunPos(ThreeQuarter, EndPos);
            _lstTimeSpan[5].IsDayLightMap = true;

            _lstTimeSpan[6].TimeType = DayTimeSpanType.Dusk;
            _lstTimeSpan[6].SetMoonPos(StartPos, OneQuarter);
            _lstTimeSpan[6].NeedChangeDayNight = true;
            _lstTimeSpan[6].IsDayLightMap = false;

            _lstTimeSpan[7].TimeType = DayTimeSpanType.Night;
            _lstTimeSpan[7].SetMoonPos(OneQuarter, MidPos);
            _lstTimeSpan[7].IsDayLightMap = false;
        }

        //初始化time计数
        private void InitializeTimeIntervalConter()
        {
            if (_tic == null)
            {
                ulong currTime = GameTimeManager.ShareInstance.CurrentTime;
                //下次同步时间
                var nextTime = _timeInterval - (currTime % _timeInterval) + currTime;
                _tic = GameTimeManager.ShareInstance.AddTimeIntervalConter(nextTime, _timeInterval);
                _tic.AddCallBack(OnGameTimeHandler);
            }       
        }

        //当GameTime改变是的处理
        private void OnGameTimeHandler()
        {
            UpdateDayTimeSpan(_tic.m_beginTime); 
        }
        
        //更新每日时间区间
        private void UpdateDayTimeSpan(ulong curTimeSec)
        {            
            int dayTime = (int)ConvertRealToGameDayTime(curTimeSec);                
            DayTimeSpan timeSpan = FindTimeSpanTypeByTime(dayTime);
            if (_curTimeSpan != timeSpan && timeSpan != null)
            {   
                _curTimeSpan = timeSpan;
                UnityEngine.Gonbest.MagicCube.EventManager.SharedInstance.PushFixEvent(UnityEngine.Gonbest.MagicCube.CoreEventDefine.EID_CORE_DAY_TIMESPAN_CHANGED, _curTimeSpan);
            }
            
        }

        //通过时间查找区间
        private DayTimeSpan FindTimeSpanTypeByTime(int time)
        {
            DayTimeSpan timeSpan = null;
            for (int i = 0; i < _lstTimeSpan.Count; i++)
            {
                timeSpan = _lstTimeSpan[i].FindSpanByTime(time);
                if (timeSpan != null)
                {
                    return timeSpan;
                }
            }
            return null;
        }
        #endregion
    }
}