using Fiesta.Networking;
using Fiesta.Networking.Packets;
using Fiesta.Worlds;
using Fiesta.Worlds.Networking;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Villain.Networking.Packets;

namespace Login.Worlds.Networking.Packets
{
	public sealed class Misc
	{
		public enum In : UInt16
		{
			Authentication = 0x0101,
			StatusUpdate = 0x0104
		}

		public enum Out : UInt16
		{
			AuthenticationFail = 0x0102,
			AuthenticationSuccess = 0x0103,

		}

		[PacketHandler("World", In.Authentication)]
		public static void Authentication(WorldConnection worldConnection, InPacket packet)
		{
			if (worldConnection.World == null)
			{
				byte worldID = packet.ReadByte();

				World world = WorldManager.Worlds.Find(x => x.ID == worldID);

				if (world != null && world.Status == World.WorldStatus.Offline)
				{
					worldConnection.World = world;
				}
			}

			if (worldConnection.World != null)
			{
				using (AuthenticationSuccess authenticationSuccess = new AuthenticationSuccess())
				{
					worldConnection.Send(authenticationSuccess);
				}
			}
			else
			{
				using (AuthenticationFail authenticationFail = new AuthenticationFail(AuthenticationFail.Reason.WorldIDAlreadyConnected))
				{
					worldConnection.Send(authenticationFail);
				}

				worldConnection.Disconnect();
			}
		}

		[PacketHandler("World", In.StatusUpdate)]
		public static void StatusUpdate(WorldConnection client, InPacket packet)
		{
			if (client.World != null)
			{
				client.World.Status = (World.WorldStatus)packet.ReadByte();
			}
			else
			{
				client.Disconnect();
			}
		}

		public class AuthenticationSuccess : OutPacket
		{
			public AuthenticationSuccess() : base(Out.AuthenticationSuccess)
			{

			}
		}

		public class AuthenticationFail : OutPacket
		{
			public enum Reason : byte
			{
				Unknown = 0x00,
				WorldIDAlreadyConnected = 0x01
			}

			public AuthenticationFail(Reason reason = Reason.Unknown) : base(Out.AuthenticationFail)
			{
				WriteByte((byte)reason);
			}
		}
	}
}