using IceInternal;
using System;
using System.Collections.Generic;
using System.Text.Json;
using Unity.Mathematics;

namespace ET.Server
{
    [MessageHandler(SceneType.Gate)]
    [FriendOfAttribute(typeof(ET.Server.BattleIceAgentComponent))]
    public class C2G_EnterMapHandler : AMRpcHandler<C2G_EnterMap, G2C_EnterMap>
    {
        protected override async ETTask Run(Session session, C2G_EnterMap request, G2C_EnterMap response, Action reply)
        {
            if(BattleIceAgentComponent.Instance == null)
            {
                Log.Error("Battle ice is null");
                response.Error = (int)ErrorCode.EnterMap.BattleSvrErr;
                reply();
                return;
            }

            StartSceneConfig startSceneConfig = StartSceneConfigCategory.Instance.GetBySceneName(session.DomainZone(), request.MapName);
            if (startSceneConfig == null)
            {
                response.Error = (int)ErrorCode.EnterMap.MapNotExist;
                reply();
                return;
            }

            Player player = session.GetComponent<SessionPlayerComponent>().GetMyPlayer();
            var gatemap = player.GetComponent<GateMapComponent>();
            if (gatemap != null)
            {
                player.RemoveComponent<GateMapComponent>();
            }
            GateMapComponent gateMapComponent = player.AddComponent<GateMapComponent>();

            //TODO: 先从所有map scene中查找是不是已经存在
            //TODO: 判断找到的scene人数是否已满等限制,如果人数超过限制,则需要传送到不同的战斗服
            // 在Gate上动态创建一个Map Scene,把Unit从DB中加载放进来,然后传送到真正的Map中,这样登陆跟传送的逻辑就完全一样了
            var scene = await SceneFactory.CreateServerScene(gateMapComponent, player.Id, IdGenerater.Instance.GenerateInstanceId(), gateMapComponent.DomainZone(), "GateMap", SceneType.Map);
            var scnInstance = scene.InstanceId.ToString();
            gateMapComponent.Scene = scene;

            //TODO: DELETE
            UnitComponent unitComponent = scene.GetComponent<UnitComponent>();
            Unit unit = unitComponent.AddChildWithId<Unit, int>(player.Id, 1001);
            unit.AddComponent<MoveComponent>();
            unit.Position = new float3(-10, 0, -10);
            NumericComponent numericComponent = unit.AddComponent<NumericComponent>();
            numericComponent.Set(NumericType.Speed, 6f); // 速度是6米每秒
            numericComponent.Set(NumericType.AOI, 15000); // 视野15米
            //unit.AddComponent<AOIEntity, int, float3>(9 * 1000, unit.Position);
            unit.AddComponent<UnitGateComponent, long>(session.InstanceId);
            //TODO:  m2m transfer unit之后,此unit会dispose,就有bug了

            //战斗服===================
            //通知战斗服创建副本
            var IceZone = BattleIceAgentComponent.Instance.IceZoneManager;
            var ret = IceZone.createZoneRequest("", Global.GameServerId.ToString(), startSceneConfig.TemplateId, scnInstance, false, toJSON4CreateZone());
            Log.Info($"Battle ice createZoneRequest ret: {ret}");

            //player进入副本,把player基本信息上报给战斗服
            IceZone.begin_playerEnterRequest(unit.Id.ToString(), scnInstance, toJSON4EnterScene(ref unit)).whenCompleted(() =>
            {
                response.SceneId = scene.InstanceId;
                reply();
                WaitPlayerReady(session.DomainScene(), player.Id).Coroutine();

                //TODO:DELETE, 只是将player置入到游戏服的场景管理数据中,并无实际transfer动作。
                //TODO:删除Map服,战斗服取代了map服地位
                //TransferHelper.Transfer(unit, startSceneConfig.InstanceId, startSceneConfig.Name).Coroutine();
            },
            (Ice.Exception ex) => {
                if (ex != null)
                {
                    Log.Error(ex.Message);

                    //TODO:进入场景失败ErrCode
                    response.Error = -1;
                    response.Message = ex.Message;
                    reply();
                    return;
                }
            });
        }

        private async ETTask WaitPlayerReady(Scene scn, long playerid)
        {
            //等待client ready消息
            await scn.GetComponent<ObjectWait>().Wait<Wait_PlayerReady>();
            //告诉战斗服 i am ready

            //设置ice战斗服中player状态为ready
            var IceXmds = BattleIceAgentComponent.Instance.IceXmdsManager;
            IceXmds.playerReady(playerid.ToString());
        }

        //TODO:按照hotfix--model框架,这段逻辑应该放到modelComponet对应的ComponetSystem中
        private string toJSON4CreateZone()
        {
            //TODO:从配置中读取副本数据
            var json = new
            {
                monsterHard = "",
                calPKValue = false,
                allowAutoGuard = 1,
                usespaceDiv = false,
                sceneType = 1,
                areaType = 0,
                canRiding = false,
                killInterval = 5000,
                killFullNum = 0,
                killFullCollSec = 0,
                averageLevel = 0,
            };
            return System.Text.Json.JsonSerializer.Serialize(json);
        }

        //TODO:按照hotfix--model框架,这段逻辑应该放到modelComponet对应的ComponetSystem中
        //对应WNPlayer.java/toJSON4EnterScene
        private string toJSON4EnterScene(ref Unit info)
        {
            var json = new
            {
                effects = new {
                    MaxHP = 666,
                    HPPer = 1,
                    HP = 233,
                    Attack = 5,
                    AttackPer = 1,

                },
                effectsExt = new { },
                skills = new List<SkillInfo>(){
                    new SkillInfo {id = 110000, level = 1, type = 1, skillTime = 10000, cdTime = 5000, flag = 0 },
                    new SkillInfo { id = 310000, level = 1, type = 1, skillTime = 10000, cdTime = 5000, flag = 0},
                },
                tasks = new { },
                flags = new { },
                playerEntered = false,
                avatars = new
                {
                },
                basic = new
                {
                    name = "nickname",
                    alliesForce = 0,
                    force = 0,
                    pro = 1,
                    serverId = 101,
                    titleId = 0,
                    level = 1,
                    vip = 0,
                    upLevel = 1,
                    beReward = 0,
                    logicServerId = Global.GameServerId,
                    sex = 0,
                    uuid = info.Id.ToString(),
                    potionAddition = 0
                },
                connectServerId = "bs-" + Global.GameServerId.ToString(),
                uid = info.Id.ToString(),
                unitTemplateID = 1,
                robot = false,
                tempData = new
                {
                    //x = this.getPlayerAreaData().bornX,
                    //y = this.getPlayerAreaData().bornY,
                    x = 3,
                    y = 4,
                    direction = 0.1,
                    hp = 1000,
                    mp = 0,
                },
                pkInfo = new
                {
                    mode = 0,
                    value = 0,
                    level = 1,
                },
                //petBase,
                addTestPetData = 0,
                sceneData = new
                {
                    allowAutoGuard = 1,
                },
            };
            var retjson = System.Text.Json.JsonSerializer.Serialize(json, new JsonSerializerOptions { IncludeFields = true });
            Log.Debug("===================================");
            Log.Debug(retjson.ToString());
            Log.Debug("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");

            return retjson;
        }
    }
}