using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace ET.Server
{
    [FriendOf(typeof (MapEventComponent))]
    [FriendOfAttribute(typeof (Map))]
    public static class MapEventComponentSystem
    {
        public class MapEventComponentAwakeSystem: AwakeSystem<MapEventComponent>
        {
            /// <summary>
            /// 场景事件组件创建
            /// </summary>
            /// <param name="self"></param>
            protected override void Awake(MapEventComponent self)
            {
                Log.Info($"创建事件组件...");
            }
        }

        public class MapEventComponentDestroySystem: DestroySystem<MapEventComponent>
        {
            /// <summary>
            /// 场景事件组件销毁
            /// </summary>
            /// <param name="self"></param>
            protected override void Destroy(MapEventComponent self)
            {
                Log.Info($"销毁事件组件...");
            }
        }

        /** 玩家进场景后推的消息 **/
        public static void OnReady(this MapEventComponent self, WNPlayer player)
        {
        }

        /** 玩家登录事件 **/
        public static void OnPlayerLogin(this MapEventComponent self, WNPlayer player)
        {
        }

        /** 角色成功进入场景 **/
        public static void OnPlayerEntered(this MapEventComponent self, WNPlayer player)
        {
        }

        /** 单位死亡事件 **/
        public static void OnUnitDead(this MapEventComponent self, Map map, JObject msg)
        {
            Log.Debug($"单位死亡...");
            int unitType = Convert.ToInt32(msg.SelectToken("unitType"));
            // 攻击者
            long hitFinalPlayerId = msg.SelectToken("hitFinal").ToString() == ""? 0 : Convert.ToInt64(msg.SelectToken("hitFinal"));
            long belongPlayerId = msg.SelectToken("belongPlayerId").ToString() == ""? 0 : Convert.ToInt64(msg.SelectToken("belongPlayerId"));
            long[] atkAssistantList = JsonConvert.DeserializeObject<long[]>(Convert.ToString(msg.SelectToken("atkAssistantList")) ?? string.Empty);
            WNPlayer hitFinalPlayer = null;

            // 默认使用第一个摸怪玩家
            if (belongPlayerId > 0)
            {
                hitFinalPlayer = map.GetPlayer(belongPlayerId);
            }

            if (hitFinalPlayer == null && hitFinalPlayerId > 0)
            {
                hitFinalPlayer = map.GetPlayer(hitFinalPlayerId);
            }

            switch (unitType)
            {
                case 0:
                    // 怪物死亡
                    int unitTemplateId = Convert.ToInt32(msg.SelectToken("unitTemplateId"));
                    Monster monsterProp = MonsterCategory.Instance.Get(unitTemplateId);
                    if (monsterProp == null)
                    {
                        Log.Error($"unitDead not fount montster : {unitTemplateId}, {map.MapId}, {msg}");
                        return;
                    }

                    // todo 怪物死亡处理逻辑
                    Log.Debug($"怪物死亡处理...");
                    break;
                case 1:
                    // 玩家死亡
                    long unitPlayerId = Convert.ToInt64(msg.SelectToken("unitPlayerId"));

                    if (hitFinalPlayerId <= 0)
                    {
                        // 被boss杀死
                        int attackerTemplateId = Convert.ToInt32(msg.SelectToken("attackerTemplateId"));
                        Log.Debug($"玩家死亡...被boss杀死...playerId={unitPlayerId}, bossId={attackerTemplateId}");
                    }
                    else
                    {
                        // 被玩家杀死
                        Log.Debug($"玩家死亡...被玩家杀死...playerId={unitPlayerId}, 攻击者={hitFinalPlayerId}");
                    }

                    // 复活
                    WNPlayer unitPlayer = map.GetPlayer(unitPlayerId);
                    if (unitPlayer == null)
                    {
                        return;
                    }

                    unitPlayer.AddComponent<PlayerReliveTimeComponent, WNPlayer>(unitPlayer);

                    break;
                case 2:
                    // 宠物死亡
                    break;
            }
        }

        /** 副本消息 **/
        public static void OnMessageEvent(this MapEventComponent self, JObject msg)
        {
        }

        /** 场景结算事件 **/
        public static void OnGameOver(this MapEventComponent self, Map map)
        {
            if (map?.Players is not { Count: > 0 })
            {
                return;
            }

            foreach (WNPlayer player in map.Players.Values.Where(player => player != null))
            {
                // 记录玩家历史
                map.SyncPlayerHistoryData(player);
                // 战斗服场景玩家离开
                map.PlayerLeaveRequest(player, false);
                // 本地场景移除玩家
                map.RemovePlayer(player, false);
                // 战斗服结束场景
                map.GetZoneManager().destroyZoneRequest(map.Id.ToString());

                player.Map = null;
            }
        }

        /** 拾取道具 **/
        public static void OnPickItem(this MapEventComponent self, JObject msg)
        {
        }

        /** 击杀boss **/
        public static void OnKillBoss(this MapEventComponent self, JObject msg)
        {
        }

        /** 战斗统计 **/
        public static void OnBattleReport(this MapEventComponent self, Map map, JObject msg)
        {
            string data = Convert.ToString(msg.SelectToken("data"));
            if (string.IsNullOrEmpty(data))
            {
                return;
            }

            List<Struct.BattleReports> list = new List<Struct.BattleReports>();

            var battleReports = JsonConvert.DeserializeObject<List<Struct.BattleReports>>(data);
            if (battleReports is { Count: > 0 })
            {
                foreach (Struct.BattleReports report in battleReports)
                {
                    // 过滤一下非我方单位
                    if (report.Force != 1)
                    {
                        continue;
                    }

                    uint ID = report.ID;
                    long PlayerUUID = string.IsNullOrEmpty(report.PlayerUUID)? 0 : Convert.ToInt64(report.PlayerUUID);
                    int TemplateID = report.TemplateId;
                    int Force = report.Force;
                    int TotalDamage = report.TotalDamage;

                    string name = "";
                    if (PlayerUUID > 0)
                    {
                        name = "玩家-" + TemplateID;
                    }
                    else
                    {
                        if (TemplateID > 0)
                        {
                            Monster prop = MonsterCategory.Instance.Get(TemplateID);
                            if (prop != null)
                            {
                                name = prop.Name;
                            }
                        }
                    }

                    list.Add(new Struct.BattleReports(ID, report.PlayerUUID, TemplateID, name, Force, TotalDamage));
                }
            }

            map.GetComponent<MapRankComponent>().UpdateRank(list, map);
        }
    }
}