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

namespace QCRPG.TSL.ZigBee.Packets;

public class MlmeScanConfirmationEd : PacketBase
{
	public class UserFieldsWrapper
	{
		private const uint _EventCode = 40u;

		private uint _Packetlength;

		private uint _Protocolid;

		private uint _Length;

		private uint _Status;

		private uint _Scantype;

		private uint _Chpage;

		private uint _Unscannedchannels;

		private uint _Resultlistsize;

		private List<PayloadSubField> _PayloadList = new List<PayloadSubField>();

		public uint Packetlength
		{
			get
			{
				return _Packetlength;
			}
			set
			{
				_Packetlength = value;
			}
		}

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

		public uint EventCode => 40u;

		public uint Length
		{
			get
			{
				return _Length;
			}
			set
			{
				if (value > 65535)
				{
					throw new Exception("Maximum possible value for Length is 0xFFFF");
				}
				_Length = value;
			}
		}

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

		public uint Scantype
		{
			get
			{
				return _Scantype;
			}
			set
			{
				if (value > 255)
				{
					throw new Exception("Maximum possible value for Scantype is 0xFF");
				}
				if (MlmeScanTypeInfo.ValueToMlmeScanType(value) == MlmeScanTypeEnum.InvalidMlmeScanTypeValue)
				{
					throw new Exception("Invalid Scantype value");
				}
				_Scantype = value;
			}
		}

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

		public uint Unscannedchannels
		{
			get
			{
				return _Unscannedchannels;
			}
			set
			{
				_Unscannedchannels = value;
			}
		}

		public uint Resultlistsize
		{
			get
			{
				return _Resultlistsize;
			}
			set
			{
				if (value > 255)
				{
					throw new Exception("Maximum possible value for Resultlistsize is 0xFF");
				}
				_Resultlistsize = value;
				while (_PayloadList.Count < _Resultlistsize)
				{
					_PayloadList.Add(new PayloadSubField());
				}
				while (_PayloadList.Count > _Resultlistsize)
				{
					_PayloadList.RemoveAt(_PayloadList.Count - 1);
				}
			}
		}

		public List<PayloadSubField> PayloadList => _PayloadList;

		public ProtocolIdEnum GetProtocolidAsProtocolIdEnum()
		{
			return ProtocolIdInfo.ValueToProtocolId(_Protocolid);
		}

		public void SetProtocolidAsProtocolIdEnum(ProtocolIdEnum enumItem)
		{
			Protocolid = ProtocolIdInfo.ProtocolIdToValue(enumItem);
		}

		public CommandOpcodeEnum GetEventCodeAsCommandOpcodeEnum()
		{
			return CommandOpcodeInfo.ValueToCommandOpcode(40u);
		}

		public ErrorCodeEnum GetStatusAsErrorCodeEnum()
		{
			return ErrorCodeInfo.ValueToErrorCode(_Status);
		}

		public void SetStatusAsErrorCodeEnum(ErrorCodeEnum enumItem)
		{
			Status = ErrorCodeInfo.ErrorCodeToValue(enumItem);
		}

		public MlmeScanTypeEnum GetScantypeAsMlmeScanTypeEnum()
		{
			return MlmeScanTypeInfo.ValueToMlmeScanType(_Scantype);
		}

		public void SetScantypeAsMlmeScanTypeEnum(MlmeScanTypeEnum enumItem)
		{
			Scantype = MlmeScanTypeInfo.MlmeScanTypeToValue(enumItem);
		}
	}

	public class PayloadSubField
	{
		private uint _Ch;

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

		public bool FromBitBuilder(ref BitBuilder bitBuilder)
		{
			Ch = bitBuilder.RemoveBitsAsUint(8);
			return true;
		}

		public string ToBitString()
		{
			BitBuilder bitBuilder = new BitBuilder();
			bitBuilder.AddBitsAsUint(Ch, 8);
			return bitBuilder.ToString();
		}
	}

	private Type[] expectedResponseTypes = new Type[0];

	private PacketInfoBase info;

	public UserFieldsWrapper _UserFields = new UserFieldsWrapper();

	public override PacketType Type => PacketType.Response;

	public override Type[] ExpectedResponseTypes => expectedResponseTypes;

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

	public UserFieldsWrapper UserFields => _UserFields;

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

	protected override bool FromBitBuilder(ref BitBuilder bitBuilder)
	{
		UserFields.Packetlength = bitBuilder.RemoveBitsAsUintLittleEndian(32);
		UserFields.Protocolid = bitBuilder.RemoveBitsAsUint(8);
		if (bitBuilder.RemoveBitsAsUint(8) != UserFields.EventCode)
		{
			return false;
		}
		UserFields.Length = bitBuilder.RemoveBitsAsUintLittleEndian(16);
		UserFields.Status = bitBuilder.RemoveBitsAsUint(8);
		UserFields.Scantype = bitBuilder.RemoveBitsAsUint(8);
		UserFields.Chpage = bitBuilder.RemoveBitsAsUint(8);
		UserFields.Unscannedchannels = bitBuilder.RemoveBitsAsUintLittleEndian(32);
		UserFields.Resultlistsize = bitBuilder.RemoveBitsAsUint(8);
		for (int i = 0; i < UserFields.PayloadList.Count; i++)
		{
			UserFields.PayloadList[i].FromBitBuilder(ref bitBuilder);
		}
		if (bitBuilder.GetNumberOfBits() > 7)
		{
			return false;
		}
		return true;
	}

	public override string ToBitString()
	{
		BitBuilder bitBuilder = new BitBuilder();
		bitBuilder.AddBitsAsUintLittleEndian(UserFields.Packetlength, 32);
		bitBuilder.AddBitsAsUint(UserFields.Protocolid, 8);
		bitBuilder.AddBitsAsUint(UserFields.EventCode, 8);
		bitBuilder.AddBitsAsUintLittleEndian(UserFields.Length, 16);
		bitBuilder.AddBitsAsUint(UserFields.Status, 8);
		bitBuilder.AddBitsAsUint(UserFields.Scantype, 8);
		bitBuilder.AddBitsAsUint(UserFields.Chpage, 8);
		bitBuilder.AddBitsAsUintLittleEndian(UserFields.Unscannedchannels, 32);
		bitBuilder.AddBitsAsUint(UserFields.Resultlistsize, 8);
		for (int i = 0; i < UserFields.PayloadList.Count; i++)
		{
			bitBuilder.AddBitsAsString(UserFields.PayloadList[i].ToBitString());
		}
		return bitBuilder.ToString();
	}

	public override List<string> GetWarnings()
	{
		List<string> list = new List<string>();
		if (UserFields.Scantype < 0)
		{
			list.Add("Minimum allowed value for ScanType is 0x0");
		}
		if (UserFields.Scantype != 0)
		{
			list.Add("Maximum allowed value for ScanType is 0x0");
		}
		return list;
	}
}
