using System;
using System.Collections.Generic;

namespace QCRPG.Framework;

public class SharedConnectionManager
{
	private Dictionary<ConnectionBase, SharedConnectionRouter> connectionToRouterMap = new Dictionary<ConnectionBase, SharedConnectionRouter>();

	private Dictionary<string, ConnectionBase> idToConnectionMap = new Dictionary<string, ConnectionBase>();

	public void AddConnection(ConnectionBase connection, string id, int timeout = -1)
	{
		if (!connectionToRouterMap.ContainsKey(connection))
		{
			connectionToRouterMap.Add(connection, new SharedConnectionRouter(connection, timeout));
			idToConnectionMap.Add(id, connection);
		}
	}

	public void RemoveConnection(string id, bool close = false)
	{
		if (!idToConnectionMap.ContainsKey(id))
		{
			return;
		}
		ConnectionBase connectionBase = idToConnectionMap[id];
		if (connectionToRouterMap.ContainsKey(connectionBase))
		{
			connectionToRouterMap[connectionBase].UnregisterAllReceiveProtocols();
			connectionToRouterMap[connectionBase] = null;
			connectionToRouterMap.Remove(connectionBase);
			idToConnectionMap.Remove(id);
			if (close)
			{
				connectionBase.Close();
			}
		}
	}

	public ConnectionBase GetConnection(string id)
	{
		if (!idToConnectionMap.ContainsKey(id))
		{
			throw new Exception("ID does not exist");
		}
		return idToConnectionMap[id];
	}

	public void AddRoute(string id, byte b, ProtocolBase protocol, int subIdOffset = 0)
	{
		if (idToConnectionMap.ContainsKey(id))
		{
			ConnectionBase key = idToConnectionMap[id];
			if (connectionToRouterMap.ContainsKey(key))
			{
				connectionToRouterMap[key].RegisterReceiveProtocol(b, protocol, subIdOffset);
			}
		}
	}

	public void AddRoute(string id, ushort us, ProtocolBase protocol)
	{
		if (idToConnectionMap.ContainsKey(id))
		{
			ConnectionBase key = idToConnectionMap[id];
			if (connectionToRouterMap.ContainsKey(key))
			{
				connectionToRouterMap[key].RegisterReceiveProtocol(us, protocol);
			}
		}
	}

	public void RemoveRoute(string id, byte b)
	{
		if (idToConnectionMap.ContainsKey(id))
		{
			ConnectionBase key = idToConnectionMap[id];
			if (connectionToRouterMap.ContainsKey(key))
			{
				connectionToRouterMap[key].UnregisterReceiveProtocol(b);
			}
		}
	}

	public void RemoveRoute(string id, ushort us)
	{
		if (idToConnectionMap.ContainsKey(id))
		{
			ConnectionBase key = idToConnectionMap[id];
			if (connectionToRouterMap.ContainsKey(key))
			{
				connectionToRouterMap[key].UnregisterReceiveProtocol(us);
			}
		}
	}

	public void RemoveAllRoutes(string id)
	{
		if (idToConnectionMap.ContainsKey(id))
		{
			ConnectionBase key = idToConnectionMap[id];
			if (connectionToRouterMap.ContainsKey(key))
			{
				connectionToRouterMap[key].UnregisterAllReceiveProtocols();
			}
		}
	}

	public void ResetConnectionRouterState(string id)
	{
		if (idToConnectionMap.ContainsKey(id))
		{
			ConnectionBase key = idToConnectionMap[id];
			if (connectionToRouterMap.ContainsKey(key))
			{
				connectionToRouterMap[key].ResetState();
			}
		}
	}
}
