﻿using JLGames.RocketDriver.Games.NetManager.Virtual;
using JLGames.RocketDriver.Games.RpgMaterial.Common;
using JLGames.RocketDriver.Samples.RpgMaterialDemo.Service;
using JLGames.RocketDriver.Samples.RpgMaterialDemo.Service.Material;

namespace JLGames.RocketDriver.Samples.RpgMaterialDemo.Server.Extensions
{
    internal static class MaterialGmExtension
    {
        internal class MaterialGmParams
        {
            private readonly int[] m_Params;

            public int Type => m_Params[0];
            public int Id => m_Params[1];
            public int Count => m_Params.Length > 2 ? m_Params[2] : 0;
            public int ParamsLength => m_Params?.Length ?? 0;

            public override string ToString()
            {
                return $"GMParams[Type={Type}, Id={Id}, Count={Count}]";
            }

            public MaterialGmParams(int[] @params)
            {
                m_Params = @params;
            }
        }

        /// <summary>
        /// 插入材料 
        /// </summary>
        /// <param name="server"></param>
        /// <param name="protoId"></param>
        /// <param name="data"></param>
        public static void HandleInsertMaterial(IVirtualServer server, string protoId, object data)
        {
            var gmParams = ParseParams(data);
//            DebugUtil.Log("MaterialGmExtension.HandleInsertMaterial:", data, gmParams);
            if (null == gmParams || gmParams.ParamsLength != 3)
            {
                server.ResponseToClient(protoId, VirtualResultCodes.Fail, null);
                return;
            }

            if (gmParams.Count <= 0)
            {
                server.ResponseToClient(protoId, VirtualResultCodes.Fail, null);
                return;
            }

            var offset = new DataOffset(gmParams.Type, gmParams.Id, 0, gmParams.Count);
            server.NotifyMaterialEntryUpdate(offset);
            server.ResponseToClient(protoId, VirtualResultCodes.Succ, null);
        }

        /// <summary>
        /// 更新材料数量 
        /// </summary>
        /// <param name="server"></param>
        /// <param name="protoId"></param>
        /// <param name="data"></param>
        public static void HandleUpdateMaterial(IVirtualServer server, string protoId, object data)
        {
            var gmParams = ParseParams(data);
//            DebugUtil.Log("MaterialGmExtension.HandleUpdateMaterial:", data, gmParams);
            if (null == gmParams || gmParams.ParamsLength != 3)
            {
                server.ResponseToClient(protoId, VirtualResultCodes.Fail, null);
                return;
            }

            if (GameMaterialUtils.CheckMaterialUnique(gmParams.Type))
            {
                server.ResponseToClient(protoId, VirtualResultCodes.Fail, null);
                return;
            }

            if (gmParams.Count < 0)
            {
                server.ResponseToClient(protoId, VirtualResultCodes.Fail, null);
                return;
            }

            var num = new DataNum(gmParams.Type, gmParams.Id, 0, gmParams.Count);
            server.NotifyMaterialEntryUpdate(num);
            server.ResponseToClient(protoId, VirtualResultCodes.Succ, null);
        }

        /// <summary>
        /// 删除材料数量 
        /// </summary>
        /// <param name="server"></param>
        /// <param name="protoId"></param>
        /// <param name="data"></param>
        public static void HandleDeleteMaterial(IVirtualServer server, string protoId, object data)
        {
            var gmParams = ParseParams(data);
//            DebugUtil.Log("MaterialGmExtension.HandleDeleteMaterial:", data, gmParams);
            if (null == gmParams || gmParams.ParamsLength < 2)
            {
                server.ResponseToClient(protoId, VirtualResultCodes.Fail, null);
                return;
            }

            var um = ServiceCenter.GetMaterialService(gmParams.Type)
                .GetUserMaterialAs<IGameUserMaterial>(gmParams.Id);
            if (null == um)
            {
                server.ResponseToClient(protoId, VirtualResultCodes.Fail, null);
                return;
            }

            if (gmParams.Count == 0)
            {
                var num = new DataNum(gmParams.Type, gmParams.Id, 0, 0);
                server.NotifyMaterialEntryUpdate(num);
            }
            else
            {
                var offset = new DataOffset(gmParams.Type, gmParams.Id, 0, -gmParams.Count);
                server.NotifyMaterialEntryUpdate(offset);
            }

            server.ResponseToClient(protoId, VirtualResultCodes.Succ, null);
        }

        private static MaterialGmParams ParseParams(object data)
        {
            var str = (string) data;
            if (string.IsNullOrEmpty(str))
            {
                return null;
            }

            var values = str.Split('_');
            if (values.Length == 0)
            {
                return null;
            }

            var rs = new int[values.Length];
            for (var index = 0; index < values.Length; index++)
            {
                var value = values[index];
                rs[index] = int.Parse(value);
            }

            return new MaterialGmParams(rs);
        }
    }
}