using CommonAI.Zone;
using CommonAI.Zone.Helper;
using CommonAI.Zone.Instance;
using CommonLang;
using CommonLang.Vector;
using System.Collections.Generic;
using XmdsCommon.EditorData;
using XmdsCommon.Message;
using XmdsCommon.Plugin;
using XmdsCommonServer.Plugin;
using XmdsCommonServer.Plugin.Quest;
using XmdsCommonServer.Plugin.Units;

namespace XmdsCommonQuest.Quest
{
    /// <summary>
    /// 炼魂任务
    /// </summary>
    [QuestTypeListen(XmdsQuestData.TaskType.RefineSoul)]
    class Quest_RefineSoul : QuestScript
    {
        private InstanceItem mRefineItem;
        
        public int mRefineItemTemplateID;
        public const string Attribute_Quality = "refine_quality";
        public const string Attribute_Name = "refine_name";
        public const string Attribute_ID = "refine_id";
        public const string Attribute_Killed = "refine_killed";

        public static int CheckIntervalMS = 3000;
        public static int OutDistanceOffset = 10;

        public enum RefineState
        {
            None,
            PutReady,
            Progress,
            GetReady,
            Complete,
        }

        private List<int> mTargetMasters;
        private TimeTaskMS mRefineTimeTask;
        private RefineState mRefineState;

        //private void SendPutEvent(bool canPut)
        //{
        //    PlayerPutRefineSoulItemB2c evt = new PlayerPutRefineSoulItemB2c();
        //    evt.CanPut = canPut;
        //    evt.QuestID = QuestID;
        //    Player.queueEvent(evt);
        //}
        
        private void SendRefineSeekEvent()
        {
            ChangeQuestSeekB2C evt = new ChangeQuestSeekB2C();
            evt.SeekInfo = string.Format("{0},{1}", mRefineItem.X, mRefineItem.Y);
            evt.QuestID = QuestID;
            Player.queueEvent(evt);
            Virtual.SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_REFINE_BLINK);

        }

        public RefineState State
        {
            get
            {
                return mRefineState;
            }
            set
            {
                mRefineState = value;
                switch (mRefineState)
                {
                    case RefineState.PutReady:
                        RemoveRefineItem();
                        break;
                    case RefineState.Progress:
                        Virtual.SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_REFINE_PUT_OK);
                        break;
                    case RefineState.GetReady:
                        var prop = (mRefineItem.Info.Properties as XmdsItemProperties);
                        if (prop.RefineSuccessEffect != null)
                        {
                            UnitEffectEvent ue = new UnitEffectEvent(mRefineItem.ID, prop.RefineSuccessEffect);
                            mRefineItem.Parent.queueObjectEvent(mRefineItem, ue);
                        }
                        mTargetMasters.Clear();
                        //推送临时寻路.
                        SendRefineSeekEvent();
                        break;
                    case RefineState.Complete:
                        Zone.QuestAdapter.DoUpdateQuestStatus(Player.PlayerUUID, QuestID, XmdsQuestData.Attribute_SubState, "1");
                        (Player as XmdsInstancePlayer).RemoveQuestScript(QuestID);
                        break;
                }
            }
        }


        private void RemoveRefineItem()
        {
            if (mRefineItem != null)
            {
                Zone.RemoveObjectByID(mRefineItem.ID);
            }
        }

        //private void AddRefineItem(Vector2 pos)
        //{
        //    if (mRefineItem != null)
        //    {
        //        mRefineItem.setPos(pos.X, pos.Y);
        //        mRefineItem.SendForceSync();
        //    }
        //    else
        //    {
        //        var itemInfo = Zone.Templates.getItem(mRefineItemTemplateID);
        //        if (itemInfo != null)
        //        {
        //            //uuid 作为name同步到客户端,以便客户端隐藏/显示
        //            mRefineItem = Zone.AddItem(itemInfo, Player.PlayerUUID, pos.X, pos.Y, Player.Direction, Player.Force, Player.PlayerUUID, null);
        //            mRefineItem.OnTryPickItem += MRefineItem_OnTryPickItem;
        //            //mRefineItem.OnObjectRemoved += MRefineItem_OnObjectRemoved;
        //        }
        //    }
        //    var q = Player.GetQuest(QuestID);

        //    if (string.IsNullOrEmpty(q.Attributes.Get(Attribute_Killed)))
        //    {
        //        State = RefineState.Progress;
        //    }
        //    else
        //    {
        //        State = RefineState.GetReady;
        //    }

        //}

        private void RefineItem_Tick(TimeTaskMS task)
        {
            if(mRefineItem == null || State == RefineState.GetReady)
            {
                return;
            }
            var prop = (mRefineItem.Info.Properties as XmdsItemProperties);
            var distance = CMath.getDistance(Player.X, Player.Y, mRefineItem.X, mRefineItem.Y);
            if(prop.RefineSoulRadius + OutDistanceOffset < distance)
            {
                State = RefineState.PutReady;
            }
        }

        private void MRefineItem_OnObjectRemoved(InstanceZoneObject obj)
        {            
            mRefineItem = null;
            if(State == RefineState.Progress)
            {
                Virtual.SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_REFINE_GET_OK);
                State = RefineState.PutReady;
            }
        }

        private bool MRefineItem_OnTryPickItem(InstanceItem item, InstanceUnit unit)
        {
            return unit == Player;
        }

        protected override void OnDispose()
        {
            if(State != RefineState.None)
            {
                Player.OnAttack -= Player_OnAttack;
                Player.OnGotInstanceItem -= Player_OnGotInstanceItem;
            }
            RemoveRefineItem();
            if(mRefineTimeTask != null)
            {
                mRefineTimeTask.Stop();
            }
        }

        protected override void OnStart()
        {
            //检测该任务目标场景
            var q = Player.GetQuest(QuestID);
            int scenid = XmdsQuestData.GetTargetSceneID(q);
            var id = q.Attributes.Get(Attribute_ID);

            if (scenid != Zone.Data.GetID() || XmdsQuestData.IsTargetComplete(q) || !int.TryParse(id, out mRefineItemTemplateID))
            {
                (Player as XmdsInstancePlayer).RemoveQuestScript(QuestID);
            }
            else
            {
                //初始化怪物列表, 进度
                string target = XmdsQuestData.GetTarget(q);
                var tmps = target.Split(':');
                mTargetMasters = new List<int>();
                for(int i = 0; i < tmps.Length; i++)
                {
                    int tmpId = 0;
                    if(int.TryParse(tmps[i], out tmpId))
                    {
                        mTargetMasters.Add(tmpId);
                    }
                }
                
                State = RefineState.PutReady;
                Player.OnAttack += Player_OnAttack;
                Player.OnGotInstanceItem += Player_OnGotInstanceItem;
                mRefineTimeTask = Zone.AddTimePeriodicMS(CheckIntervalMS, RefineItem_Tick);
            }         
        }

        public override void OnStatusChanged(string key, string v)
        {
            base.OnStatusChanged(key, v);
            if(mRefineItem != null && key == Attribute_Killed && !string.IsNullOrEmpty(v))
            {
                //任务目标已达成
                State = RefineState.GetReady;
            }
        }

        private void Player_OnGotInstanceItem(InstanceUnit obj, InstanceItem item)
        {
            if(mRefineItem != null && item == mRefineItem && State == RefineState.GetReady)
            {
                State = RefineState.Complete;
            }
        }

        private void Player_OnAttack(InstanceUnit obj, InstanceUnit target, int hp, CommonAI.Zone.Formula.AttackSource source)
        {
            //所杀怪是否正确
            //处于杀怪半径内
            //通知游戏服进度加一
            if (mRefineItem != null &&
                State == RefineState.Progress && 
                hp > 0 && 
                target.IsDead() && 
                mTargetMasters.Count > 0 &&
                mTargetMasters.IndexOf(target.Info.TemplateID) >= 0)
            {
                var prop = (mRefineItem.Info.Properties as XmdsItemProperties);
                bool inRound = CMath.intersectRound(mRefineItem.X, mRefineItem.Y, prop.RefineSoulRadius, target.X, target.Y, target.Info.BodySize);
                if(inRound)
                {
                    Zone.QuestAdapter.DoUpdateQuestStatus(Player.PlayerUUID, QuestID, XmdsQuestData.Attribute_AddProgress, "1");
                    //添加spell, 从怪飞出到法器
                    //UnitLaunchShowSpellB2C evt = new UnitLaunchShowSpellB2C();
                    //evt.Spell = prop.RefineSoulSpell;
                    //evt.LauncherID = target.ID;
                    //evt.TargetX = mRefineItem.X;
                    //evt.TargetY = mRefineItem.Y;
                    //Player.queueEvent(evt);
                    Zone.unitLaunchSpell(XmdsSkillType.none, target, prop.RefineSoulSpell,
                        target.X, target.Y, 0, new Vector2(mRefineItem.X,mRefineItem.Y));
                }
            }
        }

        private Vector2 CalcNextRefineItemPos()
        {
            Vector2 pos = new Vector2(Player.X, Player.Y);
            MathVector.movePolar(pos, Player.Direction, 3);
            return pos;
        }

        public override bool TryDoAction(ObjectAction act)
        {
            //if (act is PlayerPutRefineSoulItemAction && !Virtual.IsInSafeArea())
            //{
            //    Vector2 pos = CalcNextRefineItemPos();
            //    int gx = 0, gy = 0;
            //    Zone.PathFinder.PosToBlock(pos.X, pos.Y, out gx, out gy);
            //    if(!Zone.PathFinder.TouchMapBlock(gx, gy))
            //    {
            //        AddRefineItem(pos);
            //    }              
            //    return true;
            //}
            return false;
        }

    }
}