using System;
using System.CodeDom.Compiler;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media.Imaging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace OLD_UKRAINE_GTA_Launcher;

public class MainWindow : Window, IComponentConnector
{
	public static string URL_SETTING_JSON = "https://c9fa20f8192d779c.cdn.express/launcher/settings.json";

	public static string URL_CHECK_GAMES = "https://c9fa20f8192d779c.cdn.express/launcher/check.txt";

	public static string URL_GAMES = "https://c9fa20f8192d779c.cdn.express/launcher/game.zip";

	public static string URL_SITE = "https://google.com/";

	public static string URL_FORUM = "https://google.com/";

	public static string URL_DONATE = "https://google.com/";

	public static string URL_LK = "https://google.com/";

	public static string URL_INST = "https://google.com/";

	public static string URL_DS = "https://google.com/";

	public static string URL_YT = "https://google.com/";

	public static string URL_TG = "https://google.com/";

	public static string URL_TT = "https://google.com/";

	public static string URL_SUPPORT = "https://google.com/";

	public static string LINK_IMG_News1 = null;

	public static string LINK_IMG_News2 = null;

	public static string LINK_IMG_News3 = null;

	public string SERVER_IP = "94.131.102.22";

	public int SERVER_PORT = 22003;

	private const string MasterApiUrl = "https://mtasa.com/api/";

	internal Button settings;

	internal Image news1;

	internal Image news2;

	internal Image news3;

	internal TextBlock online;

	internal Button buttonDownload;

	internal Button startGame;

	internal TextBlock info;

	internal TextBlock infoProcent;

	internal ProgressBar downloadProgressBar;

	internal Border settingPanel;

	private bool _contentLoaded;

	public MainWindow()
	{
		InitializeComponent();
		InitComponent();
	}

	public async void InitComponent()
	{
		try
		{
			await LoadSetting(URL_SETTING_JSON);
		}
		catch (Exception ex)
		{
			Exception ex2 = ex;
			info.Text = "помилка #001, зверніться до тех.підтримки!";
			LogsWriter("Ошибка отловлена в InitComponent. Суть ошибка: " + ex2);
		}
	}

	private void WindowsDragMove(object sender, MouseButtonEventArgs e)
	{
		DragMove();
	}

	private void WindowsClose(object sender, RoutedEventArgs e)
	{
		Close();
	}

	private void WindowsRollup(object sender, RoutedEventArgs e)
	{
		base.WindowState = WindowState.Minimized;
	}

	private void ButtonSettingsOpen(object sender, RoutedEventArgs e)
	{
		settingPanel.Visibility = Visibility.Visible;
	}

	private void ButtonSettingsClose(object sender, RoutedEventArgs e)
	{
		settingPanel.Visibility = Visibility.Hidden;
	}

	public async Task LoadSetting(string paths)
	{
		try
		{
			string json = null;
			try
			{
				using (HttpClient client = new HttpClient())
				{
					json = await client.GetStringAsync(paths);
				}
				if (json == null)
				{
					info.Text = "помилка #002, зверніться до тех.підтримки!";
					LogsWriter("Ошибка отловлена в LoadSetting. Суть ошибка: json был равен null");
					return;
				}
			}
			catch (HttpRequestException ex)
			{
				HttpRequestException e = ex;
				LogsWriter("Ошибка отловлена в LoadSetting. Суть ошибка: " + e.Message);
				Exception innerException = e.InnerException;
				if (innerException is SocketException { SocketErrorCode: var socketErrorCode } se)
				{
					switch (socketErrorCode)
					{
					case SocketError.NetworkDown:
						info.Text = "помилка #002.1, мережа не працює. Будь ласка, перевірте підключення до Інтернету.";
						LogsWriter("Ошибка отловлена в LoadSetting. Суть ошибка: Сеть не работает. Пожалуйста, проверьте подключение к Интернету.");
						break;
					case SocketError.HostNotFound:
						info.Text = "помилка #002.2, мережа не працює. Будь ласка, перевірте підключення до Інтернету.";
						LogsWriter("Ошибка отловлена в LoadSetting. Суть ошибка: Сеть не работает. Пожалуйста, проверьте подключение к Интернету.");
						break;
					default:
						info.Text = "помилка #002.3, зверніться до тех.підтримки!";
						LogsWriter("Ошибка отловлена в LoadSetting. Суть ошибка: Socket error: " + se.SocketErrorCode);
						break;
					}
				}
				return;
			}
			catch (Exception ex2)
			{
				Exception ex3 = ex2;
				info.Text = "помилка #002.4, зверніться до тех.підтримки!";
				LogsWriter("Ошибка отловлена в LoadSetting. Суть ошибка: " + ex3);
				return;
			}
			Settings SettingsList = JsonConvert.DeserializeObject<Settings>(json);
			if (SettingsList == null)
			{
				info.Text = "помилка #002.5, зверніться до тех.підтримки!";
				LogsWriter("Ошибка отловлена в LoadSetting. Суть ошибки: SettingsList был равен null");
				return;
			}
			URL_SITE = SettingsList.LinkSite;
			URL_FORUM = SettingsList.LinkForum;
			URL_DONATE = SettingsList.LinkDonate;
			URL_LK = SettingsList.LinkLk;
			URL_INST = SettingsList.LinkInst;
			URL_DS = SettingsList.LinkDs;
			URL_YT = SettingsList.LinkYt;
			URL_TG = SettingsList.LinkTg;
			URL_TT = SettingsList.LinkTt;
			URL_SUPPORT = SettingsList.LinkSup;
			LINK_IMG_News1 = SettingsList.LinkImgNews1;
			LINK_IMG_News2 = SettingsList.LinkImgNews2;
			LINK_IMG_News3 = SettingsList.LinkImgNews3;
			SERVER_IP = SettingsList.Ip;
			SERVER_PORT = SettingsList.Port;
			BitmapImage image1 = DownloadImage(SettingsList.LinkImgNews1);
			if (image1 != null)
			{
				news1.Source = image1;
			}
			BitmapImage image2 = DownloadImage(SettingsList.LinkImgNews2);
			if (image2 != null)
			{
				news2.Source = image2;
			}
			BitmapImage image3 = DownloadImage(SettingsList.LinkImgNews3);
			if (image3 != null)
			{
				news3.Source = image3;
			}
			await UpdateOnlineFromMasterSafe();
		}
		catch (Exception ex2)
		{
			Exception ex4 = ex2;
			info.Text = "помилка #002.6, зверніться до тех.підтримки!";
			LogsWriter("Ошибка отловлена в LoadSetting. Суть ошибка: " + ex4);
		}
	}

	private async Task UpdateOnlineFromMasterSafe()
	{
		try
		{
			using HttpClient client = new HttpClient
			{
				Timeout = TimeSpan.FromSeconds(8.0)
			};
			JArray arr = JArray.Parse(await client.GetStringAsync("https://mtasa.com/api/"));
			JToken match = arr.FirstOrDefault((JToken x) => string.Equals((string?)x["ip"], SERVER_IP, StringComparison.OrdinalIgnoreCase) && (int?)x["port"] == SERVER_PORT);
			if (match != null)
			{
				int players = ((int?)match["players"]).GetValueOrDefault();
				int maxplayers = ((int?)match["maxplayers"]).GetValueOrDefault();
				online.Text = $"{players}/{maxplayers}";
			}
			else
			{
				online.Text = "Невідомо";
			}
		}
		catch (Exception ex)
		{
			Exception ex2 = ex;
			LogsWriter("UpdateOnlineFromMasterSafe(): " + ex2.Message);
			online.Text = "Немає даних";
		}
	}

	private BitmapImage DownloadImage(string url)
	{
		try
		{
			WebClient webClient = new WebClient();
			byte[] buffer = webClient.DownloadData(url);
			BitmapImage bitmapImage = new BitmapImage();
			bitmapImage.BeginInit();
			bitmapImage.StreamSource = new MemoryStream(buffer);
			bitmapImage.EndInit();
			return bitmapImage;
		}
		catch (Exception ex)
		{
			info.Text = "помилка #003, зверніться до тех.підтримки!";
			LogsWriter("Ошибка отловлена в DownloadImage. Суть ошибка: " + ex);
			return null;
		}
	}

	private void ButtonLink(object sender, RoutedEventArgs e)
	{
		try
		{
			if (sender is Button { Tag: string tag })
			{
				switch (tag)
				{
				case "buttonSite":
					Process.Start(new ProcessStartInfo(URL_SITE)
					{
						UseShellExecute = true
					});
					break;
				case "buttonForum":
					Process.Start(new ProcessStartInfo(URL_FORUM)
					{
						UseShellExecute = true
					});
					break;
				case "buttonDonate":
					Process.Start(new ProcessStartInfo(URL_DONATE)
					{
						UseShellExecute = true
					});
					break;
				case "buttonLk":
					Process.Start(new ProcessStartInfo(URL_LK)
					{
						UseShellExecute = true
					});
					break;
				case "buttonInst":
					Process.Start(new ProcessStartInfo(URL_INST)
					{
						UseShellExecute = true
					});
					break;
				case "buttonDs":
					Process.Start(new ProcessStartInfo(URL_DS)
					{
						UseShellExecute = true
					});
					break;
				case "buttonYt":
					Process.Start(new ProcessStartInfo(URL_YT)
					{
						UseShellExecute = true
					});
					break;
				case "buttonTg":
					Process.Start(new ProcessStartInfo(URL_TG)
					{
						UseShellExecute = true
					});
					break;
				case "buttonTt":
					Process.Start(new ProcessStartInfo(URL_TT)
					{
						UseShellExecute = true
					});
					break;
				case "buttonSup":
					Process.Start(new ProcessStartInfo(URL_SUPPORT)
					{
						UseShellExecute = true
					});
					break;
				}
			}
		}
		catch (Exception ex)
		{
			info.Text = "помилка #004, зверніться до тех.підтримки!";
			LogsWriter("Ошибка отловлена в ButtonLink. Суть ошибка: " + ex);
		}
	}

	private async void ButtonStartGame(object sender, RoutedEventArgs e)
	{
		try
		{
			startGame.IsEnabled = false;
			settings.IsEnabled = false;
			await FindeGamesFile();
		}
		catch (Exception ex)
		{
			Exception ex2 = ex;
			info.Text = "помилка #005, зверніться до тех.підтримки!";
			LogsWriter("Ошибка отловлена в ButtonStartGame. Суть ошибка: " + ex2);
		}
	}

	public async Task FindeGamesFile()
	{
		try
		{
			string exePath = AppDomain.CurrentDomain.BaseDirectory;
			string path_config = Path.Combine(exePath, "bin\\resources\\check.txt");
			if (!File.Exists(path_config))
			{
				info.Text = "необхідно завантажити клієнт!";
				startGame.Visibility = Visibility.Hidden;
				buttonDownload.Visibility = Visibility.Visible;
				return;
			}
			using StreamReader local_path = new StreamReader(path_config, Encoding.Default);
			if (local_path == null)
			{
				info.Text = "помилка #006, зверніться до тех.підтримки!";
				LogsWriter("Ошибка отловлена в FindeGamesFile. Суть ошибка: local-text выдал значение null");
				return;
			}
			string local_text = await local_path.ReadToEndAsync();
			using WebClient wc = new WebClient();
			string web_text = await wc.DownloadStringTaskAsync(URL_CHECK_GAMES);
			if (web_text == null)
			{
				info.Text = "помилка #006.1, зверніться до тех.підтримки!";
				LogsWriter("Ошибка отловлена в FindeGamesFile. Суть ошибка: web-text выдал значение null");
				return;
			}
			if (local_text == web_text)
			{
				Start();
				return;
			}
			info.Text = "необхідно оновити клієнт!";
			startGame.Visibility = Visibility.Hidden;
			buttonDownload.Visibility = Visibility.Visible;
		}
		catch (Exception ex)
		{
			Exception ex2 = ex;
			info.Text = "помилка #006.2, зверніться до тех.підтримки!";
			LogsWriter("Ошибка отловлена в FindeGamesFile. Суть ошибка: " + ex2);
		}
	}

	private async void ButtonStartDonwload(object sender, RoutedEventArgs e)
	{
		try
		{
			buttonDownload.IsEnabled = false;
			settings.IsEnabled = false;
			await StartDonwloadGame();
		}
		catch (Exception ex)
		{
			Exception ex2 = ex;
			info.Text = "помилка #007, зверніться до тех.підтримки!";
			LogsWriter("Ошибка отловлена в ButtonStartDonwload. Суть ошибка: " + ex2);
		}
	}

	private async void ButtonReinstallGame(object sender, RoutedEventArgs e)
	{
		try
		{
			settingPanel.Visibility = Visibility.Hidden;
			startGame.Visibility = Visibility.Hidden;
			buttonDownload.Visibility = Visibility.Visible;
			buttonDownload.IsEnabled = false;
			settings.IsEnabled = false;
			await StartDonwloadGame();
		}
		catch (Exception ex)
		{
			Exception ex2 = ex;
			info.Text = "помилка #008, зверніться до тех.підтримки!";
			LogsWriter("Ошибка отловлена в ButtonReinstallGame. Суть ошибка: " + ex2);
		}
	}

	public async Task StartDonwloadGame()
	{
		try
		{
			string exePath = AppDomain.CurrentDomain.BaseDirectory;
			string bin = Path.Combine(exePath, "bin\\resources\\");
			WebClient webclient = new WebClient();
			string path = Path.Combine(exePath, "game.zip");
			Uri uri = new Uri(URL_GAMES);
			new Stopwatch();
			webclient.DownloadFileAsync(uri, path);
			webclient.DownloadProgressChanged += webClient_DownloadProgressChanged;
			webclient.DownloadFileCompleted += webClient_DownloadFileCompleted;
			async void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
			{
				string sourceArchiveFileName = "game.zip";
				downloadProgressBar.Value = 100.0;
				webclient.Dispose();
				bool IsFileTtf = false;
				if (Directory.Exists(bin))
				{
					string[] files = Directory.GetFiles(bin, "*.*", SearchOption.AllDirectories);
					string[] array = files;
					foreach (string file in array)
					{
						if (Path.GetFileName(file) == "gtaweap3.ttf" || Path.GetFileName(file) == "sampaux3.ttf")
						{
							IsFileTtf = true;
						}
						else
						{
							File.Delete(file);
							LogsWriter("Удалет файл: " + file);
						}
					}
				}
				info.Text = "розпакування...";
				await UnzipArchive(sourceArchiveFileName, bin, IsFileTtf);
				try
				{
					string outputFilePath = bin + "\\check.txt";
					using StreamWriter writer = new StreamWriter(outputFilePath, append: true);
					WebClient wc = new WebClient();
					string web_text = wc.DownloadString(URL_CHECK_GAMES);
					writer.Write(web_text);
					writer.Close();
				}
				catch (Exception ex3)
				{
					LogsWriter("Ошибка отловлена в CreateCheck. Суть ошибка: " + ex3);
				}
				File.Delete(path);
				info.Text = "завантаження гри завершено. можете грати!";
				startGame.Visibility = Visibility.Visible;
				buttonDownload.Visibility = Visibility.Hidden;
				buttonDownload.IsEnabled = true;
				startGame.IsEnabled = true;
				settings.IsEnabled = true;
				webclient.Dispose();
			}
		}
		catch (Exception ex)
		{
			Exception ex2 = ex;
			info.Text = "помилка #009, зверніться до тех.підтримки!";
			LogsWriter("Ошибка отловлена в StartDonwloadGame. Суть ошибка: " + ex2);
		}
		void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
		{
			downloadProgressBar.Value = e.ProgressPercentage;
			info.Text = "завантаження гри  " + (Convert.ToDouble(e.BytesReceived) / 1024.0 / 1024.0).ToString("0,00") + " МБ  /  " + (Convert.ToDouble(e.TotalBytesToReceive) / 1024.0 / 1024.0).ToString("0.00") + " МБ";
			double value = ((e.TotalBytesToReceive > 0) ? ((double)e.BytesReceived / (double)e.TotalBytesToReceive * 100.0) : 0.0);
			infoProcent.Text = $"{value:F0}%";
		}
	}

	public async Task UnzipArchive(string archiveFilePath, string outputDirectory, bool IsFileTtf)
	{
		try
		{
			Path.Combine(outputDirectory, archiveFilePath);
			if (!File.Exists(archiveFilePath))
			{
				info.Text = "помилка #010, зверніться до тех.підтримки!";
				LogsWriter("Ошибка отловлена в UnzipArchive. Суть ошибка: ахив для распаковки не найден");
				return;
			}
			using ZipArchive archive = ZipFile.OpenRead(archiveFilePath);
			foreach (ZipArchiveEntry entry in archive.Entries)
			{
				if (IsFileTtf && (entry.Name == "gtaweap3.ttf" || entry.Name == "sampaux3.ttf"))
				{
					continue;
				}
				string destinationPath = Path.Combine(outputDirectory, entry.FullName);
				if (entry.FullName.EndsWith("/"))
				{
					Directory.CreateDirectory(destinationPath);
					continue;
				}
				string directoryName = Path.GetDirectoryName(destinationPath);
				if (!Directory.Exists(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				entry.ExtractToFile(destinationPath, overwrite: true);
			}
		}
		catch (Exception ex)
		{
			Exception ex2 = ex;
			info.Text = "помилка #010.1, зверніться до тех.підтримки!";
			LogsWriter("Ошибка отловлена в UnzipArchive. Суть ошибка: " + ex2);
		}
	}

	public async Task Start()
	{
		try
		{
			info.Text = "запускаємо гру! очікуйте.";
			string exePath = AppDomain.CurrentDomain.BaseDirectory;
			string dirGame = Path.Combine(exePath, "bin\\resources\\");
			string pathMta = Path.Combine(dirGame, "OLD UKRAINE GTA.exe");
			if (!File.Exists(pathMta) && !File.Exists(Path.Combine(dirGame, "gta_sa.exe")) && !File.Exists(Path.Combine(dirGame, "proxy_sa.exe")))
			{
				info.Text = "файл не знайдено, підкачуємо...";
				try
				{
					using HttpClient client = new HttpClient();
					string downloadUrl = "https://c9fa20f8192d779c.cdn.express/launcher/OLD_UKRAINE_GTA.exe";
					Directory.CreateDirectory(dirGame);
					using (HttpResponseMessage response = await client.GetAsync(downloadUrl))
					{
						response.EnsureSuccessStatusCode();
						using FileStream fs = new FileStream(pathMta, FileMode.Create, FileAccess.Write, FileShare.None);
						await response.Content.CopyToAsync(fs);
					}
					info.Text = "Файл завантажено, запускаємо гру...";
				}
				catch (Exception ex)
				{
					Exception ex2 = ex;
					info.Text = "Не вдалося завантажити гру. Перевірте інтернет.";
					LogsWriter("Помилка при підкачці файлу: " + ex2);
					return;
				}
			}
			ProcessStartInfo startInfo = new ProcessStartInfo
			{
				FileName = pathMta,
				UseShellExecute = false,
				RedirectStandardOutput = false,
				RedirectStandardError = false,
				RedirectStandardInput = false,
				CreateNoWindow = false,
				WorkingDirectory = dirGame
			};
			using (Process process = new Process
			{
				StartInfo = startInfo
			})
			{
				process.Start();
			}
			startGame.IsEnabled = true;
			info.Text = "Все готово для запуску. Приємної гри!";
		}
		catch (Exception ex)
		{
			Exception ex3 = ex;
			info.Text = "помилка #011.1, зверніться в техпідтримку!";
			LogsWriter("Помилка відловлена в Start: " + ex3);
		}
	}

	public static void LogsWriter(string text)
	{
		DateTime now = DateTime.Now;
		string text2 = now.ToShortDateString();
		string text3 = now.ToShortTimeString();
		Console.WriteLine("Current Date: " + text2);
		Console.WriteLine("Current Time: " + text3);
		string path = "logs.log";
		using StreamWriter streamWriter = new StreamWriter(path, append: true);
		streamWriter.WriteLine("[" + text3 + " - " + text2 + "]: " + text + "\n");
		streamWriter.Close();
	}

	[DebuggerNonUserCode]
	[GeneratedCode("PresentationBuildTasks", "9.0.10.0")]
	public void InitializeComponent()
	{
		if (!_contentLoaded)
		{
			_contentLoaded = true;
			Uri resourceLocator = new Uri("/OLD_UKRAINE_GTA_Launcher;component/mainwindow.xaml", UriKind.Relative);
			Application.LoadComponent(this, resourceLocator);
		}
	}

	[DebuggerNonUserCode]
	[GeneratedCode("PresentationBuildTasks", "9.0.10.0")]
	[EditorBrowsable(EditorBrowsableState.Never)]
	void IComponentConnector.Connect(int connectionId, object target)
	{
		switch (connectionId)
		{
		case 1:
			((Grid)target).MouseLeftButtonDown += WindowsDragMove;
			break;
		case 2:
			((Button)target).Click += ButtonLink;
			break;
		case 3:
			((Button)target).Click += ButtonLink;
			break;
		case 4:
			((Button)target).Click += ButtonLink;
			break;
		case 5:
			((Button)target).Click += ButtonLink;
			break;
		case 6:
			settings = (Button)target;
			settings.Click += ButtonSettingsOpen;
			break;
		case 7:
			((Button)target).Click += WindowsRollup;
			break;
		case 8:
			((Button)target).Click += WindowsClose;
			break;
		case 9:
			((Button)target).Click += ButtonLink;
			break;
		case 10:
			((Button)target).Click += ButtonLink;
			break;
		case 11:
			((Button)target).Click += ButtonLink;
			break;
		case 12:
			((Button)target).Click += ButtonLink;
			break;
		case 13:
			((Button)target).Click += ButtonLink;
			break;
		case 14:
			news1 = (Image)target;
			break;
		case 15:
			news2 = (Image)target;
			break;
		case 16:
			news3 = (Image)target;
			break;
		case 17:
			online = (TextBlock)target;
			break;
		case 18:
			buttonDownload = (Button)target;
			buttonDownload.Click += ButtonStartDonwload;
			break;
		case 19:
			startGame = (Button)target;
			startGame.Click += ButtonStartGame;
			break;
		case 20:
			info = (TextBlock)target;
			break;
		case 21:
			infoProcent = (TextBlock)target;
			break;
		case 22:
			downloadProgressBar = (ProgressBar)target;
			break;
		case 23:
			settingPanel = (Border)target;
			break;
		case 24:
			((Button)target).Click += ButtonSettingsClose;
			break;
		case 25:
			((Button)target).Click += ButtonLink;
			break;
		case 26:
			((Button)target).Click += ButtonReinstallGame;
			break;
		default:
			_contentLoaded = true;
			break;
		}
	}
}
