using System;
using System.Collections.Generic;
using System.Text;
using QCRPG.Framework;

namespace QCRPG.TSL.BT.Packets;

public class QbceSetQhsHostMode : PacketBase
{
	public class UserFieldsWrapper
	{
		public enum TransportEnum
		{
			Classic,
			LE,
			LE_ISO,
			InvalidTransportValue
		}

		public static class TransportInfo
		{
			public static TransportEnum ValueToTransport(uint value)
			{
				return value switch
				{
					0u => TransportEnum.Classic, 
					1u => TransportEnum.LE, 
					2u => TransportEnum.LE_ISO, 
					_ => TransportEnum.InvalidTransportValue, 
				};
			}

			public static uint TransportToValue(TransportEnum enumItem)
			{
				return enumItem switch
				{
					TransportEnum.Classic => 0u, 
					TransportEnum.LE => 1u, 
					TransportEnum.LE_ISO => 2u, 
					_ => uint.MaxValue, 
				};
			}

			public static string TransportToString(TransportEnum enumItem)
			{
				return enumItem switch
				{
					TransportEnum.Classic => "BR/EDR transport", 
					TransportEnum.LE => "LE transport", 
					TransportEnum.LE_ISO => "ISO transport", 
					_ => "Invalid Transport Value", 
				};
			}

			public static string TransportToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = BR/EDR transport");
				stringBuilder.AppendLine("0x1 = LE transport");
				stringBuilder.AppendLine("0x2 = ISO transport");
				return stringBuilder.ToString();
			}
		}

		public enum QhsHostModeEnum
		{
			Disabled,
			QHS_4_LE2M_Classic,
			QHS_4_LE1M_2M,
			Host_aware,
			InvalidQhsHostModeValue
		}

		public static class QhsHostModeInfo
		{
			public static QhsHostModeEnum ValueToQhsHostMode(uint value)
			{
				return value switch
				{
					0u => QhsHostModeEnum.Disabled, 
					1u => QhsHostModeEnum.QHS_4_LE2M_Classic, 
					2u => QhsHostModeEnum.QHS_4_LE1M_2M, 
					3u => QhsHostModeEnum.Host_aware, 
					_ => QhsHostModeEnum.InvalidQhsHostModeValue, 
				};
			}

			public static uint QhsHostModeToValue(QhsHostModeEnum enumItem)
			{
				return enumItem switch
				{
					QhsHostModeEnum.Disabled => 0u, 
					QhsHostModeEnum.QHS_4_LE2M_Classic => 1u, 
					QhsHostModeEnum.QHS_4_LE1M_2M => 2u, 
					QhsHostModeEnum.Host_aware => 3u, 
					_ => uint.MaxValue, 
				};
			}

			public static string QhsHostModeToString(QhsHostModeEnum enumItem)
			{
				return enumItem switch
				{
					QhsHostModeEnum.Disabled => "QHS disabled", 
					QhsHostModeEnum.QHS_4_LE2M_Classic => "Substitute QHS for LE2M and Classic", 
					QhsHostModeEnum.QHS_4_LE1M_2M => "Substitute QHS for LE1M, LE2M", 
					QhsHostModeEnum.Host_aware => "Host aware of QHS", 
					_ => "Invalid QhsHostMode Value", 
				};
			}

			public static string QhsHostModeToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = QHS disabled");
				stringBuilder.AppendLine("0x1 = Substitute QHS for LE2M and Classic");
				stringBuilder.AppendLine("0x2 = Substitute QHS for LE1M, LE2M");
				stringBuilder.AppendLine("0x3 = Host aware of QHS");
				return stringBuilder.ToString();
			}
		}

		private const uint _Subopcode = 1u;

		private uint _Transport;

		private uint _QhsHostMode;

		public uint Subopcode => 1u;

		public uint Transport
		{
			get
			{
				return _Transport;
			}
			set
			{
				if (value > 255)
				{
					throw new Exception("Maximum possible value for Transport is 0xFF");
				}
				_Transport = value;
			}
		}

		public uint QhsHostMode
		{
			get
			{
				return _QhsHostMode;
			}
			set
			{
				if (value > 255)
				{
					throw new Exception("Maximum possible value for QhsHostMode is 0xFF");
				}
				_QhsHostMode = value;
			}
		}

		public TransportEnum GetTransportAsTransportEnum()
		{
			return TransportInfo.ValueToTransport(_Transport);
		}

		public void SetTransportAsTransportEnum(TransportEnum enumItem)
		{
			Transport = TransportInfo.TransportToValue(enumItem);
		}

		public QhsHostModeEnum GetQhsHostModeAsQhsHostModeEnum()
		{
			return QhsHostModeInfo.ValueToQhsHostMode(_QhsHostMode);
		}

		public void SetQhsHostModeAsQhsHostModeEnum(QhsHostModeEnum enumItem)
		{
			QhsHostMode = QhsHostModeInfo.QhsHostModeToValue(enumItem);
		}
	}

	private const uint _Opcode = 64593u;

	private Type[] expectedResponseTypes = new Type[1] { typeof(CommandCompleteForQbceSetQhsHostMode) };

	private PacketInfoBase info;

	private uint _PayloadLength;

	public UserFieldsWrapper _UserFields = new UserFieldsWrapper();

	public override PacketType Type => PacketType.Command;

	public override Type[] ExpectedResponseTypes => expectedResponseTypes;

	public override PacketInfoBase Info
	{
		get
		{
			if (info == null)
			{
				info = new QbceSetQhsHostModeInfo(this);
			}
			return info;
		}
	}

	public uint Opcode => 64593u;

	public uint PayloadLength
	{
		get
		{
			ToBitString();
			return _PayloadLength;
		}
	}

	public UserFieldsWrapper UserFields => _UserFields;

	public override void SetDefaultValues()
	{
		UserFields.Transport = 0u;
		UserFields.QhsHostMode = 0u;
	}

	protected override bool FromBitBuilder(ref BitBuilder bitBuilder)
	{
		if (bitBuilder.RemoveBitsAsUintLittleEndian(16) != Opcode)
		{
			return false;
		}
		_PayloadLength = bitBuilder.RemoveBitsAsUint(8);
		int numberOfBits = bitBuilder.GetNumberOfBits();
		if (numberOfBits > _PayloadLength * 8 + 7)
		{
			return false;
		}
		if (numberOfBits < _PayloadLength * 8)
		{
			return false;
		}
		if (bitBuilder.RemoveBitsAsUint(8) != UserFields.Subopcode)
		{
			return false;
		}
		UserFields.Transport = bitBuilder.RemoveBitsAsUint(8);
		UserFields.QhsHostMode = bitBuilder.RemoveBitsAsUint(8);
		if (bitBuilder.GetNumberOfBits() > 7)
		{
			return false;
		}
		return true;
	}

	public override string ToBitString()
	{
		BitBuilder bitBuilder = new BitBuilder();
		bitBuilder.AddBitsAsUintLittleEndian(Opcode, 16);
		int numberOfBits = bitBuilder.GetNumberOfBits();
		bitBuilder.AddBitsAsUint(0u, 8);
		bitBuilder.AddBitsAsUint(UserFields.Subopcode, 8);
		bitBuilder.AddBitsAsUint(UserFields.Transport, 8);
		bitBuilder.AddBitsAsUint(UserFields.QhsHostMode, 8);
		_PayloadLength = (uint)((bitBuilder.GetNumberOfBits() - numberOfBits - 8) / 8);
		if ((bitBuilder.GetNumberOfBits() - numberOfBits - 8) % 8 != 0)
		{
			_PayloadLength++;
		}
		bitBuilder.ChangeBitsAsUint(numberOfBits, _PayloadLength, 8);
		return bitBuilder.ToString();
	}

	public override List<string> GetWarnings()
	{
		List<string> list = new List<string>();
		if (UserFields.Transport < 0)
		{
			list.Add("Minimum allowed value for Transport is 0x0");
		}
		if (UserFields.Transport > 2)
		{
			list.Add("Maximum allowed value for Transport is 0x2");
		}
		if (UserFields.QhsHostMode < 0)
		{
			list.Add("Minimum allowed value for QHS_host_mode is 0x0");
		}
		if (UserFields.QhsHostMode > 3)
		{
			list.Add("Maximum allowed value for QHS_host_mode is 0x3");
		}
		return list;
	}
}
