namespace InABox.DigitalMatter
{
    public class DMBluetoothTagData : DMField
    {
        public override byte Type => 0x1E;

        public byte DataLength { get; set; }
        public byte LogReason { get; set; }
        public byte TagType { get; set; }
        public sbyte RSSI { get; set; }
        public uint TimeStamp { get; set; }
        public int Latitude { get; set; }
        public int Longitude { get; set; }
        public byte GPSAccuracy { get; set; }

        public DMBluetoothTag Tag { get; set; }

        public override bool IsValid()
        {
            return true;
        }

        protected override void DoDecode(IDMReadBuffer buffer)
        {
            var header = buffer.TakeByte();
            DataLength = IDMBuffer.EncodeByte(IDMBuffer.DecodeByte(header, 0, 6));
            LogReason = IDMBuffer.EncodeByte(IDMBuffer.DecodeByte(header, 6, 2));
            TagType = buffer.TakeByte();
            RSSI = buffer.TakeInt8();
            TimeStamp = buffer.TakeUInt32();
            Latitude = buffer.TakeInt32();
            Longitude = buffer.TakeInt32();
            GPSAccuracy = buffer.TakeByte();
            var data = buffer.TakeBytes(DataLength);
            Tag = DMFactory.ParseBluetoothTag(TagType, data);
        }

        protected override void DoEncode(IDMWriteBuffer buffer)
        {
            buffer.AddByte(TagType);
            buffer.AddInt8(RSSI);
            buffer.AddUInt32(TimeStamp);
            buffer.AddInt32(Latitude);
            buffer.AddInt32(Longitude);
            buffer.AddByte(GPSAccuracy);

            var data = Tag.EncodeArray();
            buffer.AddBytes(data);

            DataLength = (byte)data.Length;
            var header = IDMBuffer.EncodeByte(IDMBuffer.DecodeByte(DataLength, 0, 6));
            header = IDMBuffer.UpdateByte(header, 6, IDMBuffer.DecodeByte(LogReason, 0, 2));
            buffer.InsertByte(0, header);
        }

        public override string ToString()
        {
            return string.Format("{0} {1} {2:dd MMM yy hh-mm-ss} Lat: {3:F6} Lng: {4:F6} RSSI: {5}", Tag,
                LogReason == 1 ? "Found" : LogReason == 2 ? "Lost" : "Updated", TimeStampToDateTime(TimeStamp), (double)Latitude / 10000000.0F,
                (double)Longitude / 10000000.0F, RSSI);
        }
    }
}