﻿using System;
using System.Collections.Generic;
using JLGames.RocketDriver.CSharp.Event;

namespace JLGames.RocketDriver.Games.NetManager.Virtual
{
    public class VirtualClient : EventDispatcher, IVirtualClient
    {
        private static readonly Dictionary<string, string> m_MaterialProto2Event = new Dictionary<string, string>()
        {
            {VirtualServerProtos.ProtoNotifyUserData, VirtualClientEvents.NotifyUserData},
            {VirtualServerProtos.ProtoNotifyUserNum, VirtualClientEvents.NotifyUserNum},
            {VirtualServerProtos.ProtoNotifyUserOffset, VirtualClientEvents.NotifyUserOffset},
            {VirtualServerProtos.ProtoNotifyUserDatas, VirtualClientEvents.NotifyUserDatas},
            {VirtualServerProtos.ProtoNotifyUserNums, VirtualClientEvents.NotifyUserNums},
            {VirtualServerProtos.ProtoNotifyUserOffsets, VirtualClientEvents.NotifyUserOffsets},
        };

        private readonly string m_Name;
        private readonly string m_GroupName;
        private IVirtualServerProxy m_ServerProxy;

        public string Name => m_Name;
        public string GroupName => m_GroupName;

        public VirtualClient()
        {
            m_Name = "VirtualClient";
            m_Name = "Default";
        }

        public VirtualClient(string name, string groupName)
        {
            m_Name = name;
            m_GroupName = groupName;
        }

        public void Destroy()
        {
            Disconnect();
        }

        public void Connect(IVirtualServerProxy server)
        {
            if (null == server) return;
            m_ServerProxy = server;
            AddListeners();
        }

        public void Disconnect()
        {
            if (null == m_ServerProxy) return;
            RemoveListeners();
            m_ServerProxy = null;
        }

        public void Reconnect(IVirtualServerProxy server)
        {
            Disconnect();
            Connect(server);
        }

        public void Request(string protoId, object data)
        {
            if (null == m_ServerProxy) throw new Exception("VirtualServerProxy is null. ");
            m_ServerProxy.OnRequest(protoId, data);
        }

        private void AddListeners()
        {
            m_ServerProxy.AddEventListener(VirtualServerEvents.EventResponse, OnServerResponse);
            m_ServerProxy.AddEventListener(VirtualServerEvents.EventNotify, OnServerNotify);
            m_ServerProxy.AddEventListener(VirtualServerEvents.EventMaterialNotify, OnServerMaterialNotify);
        }

        private void RemoveListeners()
        {
            m_ServerProxy.RemoveEventListener(VirtualServerEvents.EventMaterialNotify, OnServerMaterialNotify);
            m_ServerProxy.RemoveEventListener(VirtualServerEvents.EventNotify, OnServerNotify);
            m_ServerProxy.RemoveEventListener(VirtualServerEvents.EventResponse, OnServerResponse);
        }

        private void OnServerMaterialNotify(EventData evd)
        {
            var data = (VirtualServerNotify) evd.Data;
            DispatchEvent(m_MaterialProto2Event[data.Pid], data.Data);
        }

        private void OnServerNotify(EventData evd)
        {
            var data = (VirtualServerNotify) evd.Data;
            DispatchEvent(VirtualClientEvents.EventNotify, new VirtualClientNotify {Pid = data.Pid, Data = data.Data});
        }

        /// <summary>
        /// Data Format: 
        /// 数据格式：VirtualClientResponse
        /// </summary>
        /// <param name="evd"></param>
        private void OnServerResponse(EventData evd)
        {
            var data = (VirtualServerResponse) evd.Data;
            DispatchEvent(VirtualClientEvents.EventResponse, new VirtualClientResponse {Pid = data.Pid, RsCode = data.RsCode, Data = data.Data});
        }
    }
}