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

namespace QCRPG.TSL.ZigBee.Packets;

public class MlmeReset : PacketBase
{
	public class UserFieldsWrapper
	{
		public enum ResetEnum
		{
			FLUSH_BUFFERS,
			FLUSH_BUFFERS_RESET_PIBS,
			RESET_BUFFERS_PIBS_PHY_NVM,
			InvalidResetValue
		}

		public static class ResetInfo
		{
			public static ResetEnum ValueToReset(uint value)
			{
				return value switch
				{
					0u => ResetEnum.FLUSH_BUFFERS, 
					1u => ResetEnum.FLUSH_BUFFERS_RESET_PIBS, 
					2u => ResetEnum.RESET_BUFFERS_PIBS_PHY_NVM, 
					_ => ResetEnum.InvalidResetValue, 
				};
			}

			public static uint ResetToValue(ResetEnum enumItem)
			{
				return enumItem switch
				{
					ResetEnum.FLUSH_BUFFERS => 0u, 
					ResetEnum.FLUSH_BUFFERS_RESET_PIBS => 1u, 
					ResetEnum.RESET_BUFFERS_PIBS_PHY_NVM => 2u, 
					_ => uint.MaxValue, 
				};
			}

			public static string ResetToString(ResetEnum enumItem)
			{
				return enumItem switch
				{
					ResetEnum.FLUSH_BUFFERS => "Flush outstanding buffers", 
					ResetEnum.FLUSH_BUFFERS_RESET_PIBS => "Flush outstanding buffers & reset PIBs to default", 
					ResetEnum.RESET_BUFFERS_PIBS_PHY_NVM => "Flush outstanding buffers, reset PIBs to default, & reset phy / reload NVMs", 
					_ => "Invalid Reset Value", 
				};
			}

			public static string ResetToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = Flush outstanding buffers");
				stringBuilder.AppendLine("0x1 = Flush outstanding buffers & reset PIBs to default");
				stringBuilder.AppendLine("0x2 = Flush outstanding buffers, reset PIBs to default, & reset phy / reload NVMs");
				return stringBuilder.ToString();
			}
		}

		private uint _Reset;

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

		public ResetEnum GetResetAsResetEnum()
		{
			return ResetInfo.ValueToReset(_Reset);
		}

		public void SetResetAsResetEnum(ResetEnum enumItem)
		{
			Reset = ResetInfo.ResetToValue(enumItem);
		}
	}

	private const uint _Packetcode = 38u;

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

	private PacketInfoBase info;

	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 MlmeResetInfo(this);
			}
			return info;
		}
	}

	public uint Packetcode => 38u;

	public UserFieldsWrapper UserFields => _UserFields;

	public override void SetDefaultValues()
	{
		UserFields.Reset = 2u;
	}

	protected override bool FromBitBuilder(ref BitBuilder bitBuilder)
	{
		if (bitBuilder.RemoveBitsAsUintLittleEndian(8) != Packetcode)
		{
			return false;
		}
		UserFields.Reset = bitBuilder.RemoveBitsAsUint(8);
		if (bitBuilder.GetNumberOfBits() > 7)
		{
			return false;
		}
		return true;
	}

	public override string ToBitString()
	{
		BitBuilder bitBuilder = new BitBuilder();
		bitBuilder.AddBitsAsUintLittleEndian(Packetcode, 8);
		bitBuilder.AddBitsAsUint(UserFields.Reset, 8);
		return bitBuilder.ToString();
	}

	public override List<string> GetWarnings()
	{
		List<string> list = new List<string>();
		if (UserFields.Reset > 2)
		{
			list.Add("Maximum allowed value for RESET is 0x2");
		}
		return list;
	}
}
