using qtcnet_client.Properties;
using qtcnet_client.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;

namespace qtcnet_client.Services
{
    public class UpdateService
    {
        public async Task CheckForUpdatesAsync()
        {
            if (Debugger.IsAttached) return;

            // get client update info
            HttpClient client = new()
            {
                BaseAddress = new Uri("https://qtcclient.alanmoon.net")
            };

            try
            {
                ClientUpdateInfo? updateInfo = await client.GetFromJsonAsync<ClientUpdateInfo>("clientinfo.json");
                if (updateInfo != null)
                {
                    var serverVersion = Version.Parse(updateInfo.Version);
                    var clientVersion = Version.Parse(Resources.AssemblyVersion);

                    int relativeComparison = clientVersion.CompareTo(serverVersion);

                    if (relativeComparison > 0) return; // probably a version being developed or tested without a debugger, so don't do anything

                    if (relativeComparison < 0)
                    {
                        // inform the user an update is available
                        if (!updateInfo.IsUpdateMandatory)
                        {
                            var result = MessageBox.Show(
                                $"An Update For QtC.NET Is Available. You Can View The Changelog At {updateInfo.DownloadUrl}. Do You Want To Update Now?",
                                "Update Available",
                                MessageBoxButtons.YesNo,
                                MessageBoxIcon.Information);
                            if (result == DialogResult.Yes) await UpdateAsync(updateInfo);
                        }
                        else
                        {
                            var result = MessageBox.Show(
                                "Your QtC.NET Client Is Not Up To Date. Using This Version Of The Client With The Current Version Of The Server Could Lead To Data Loss.\n" +
                                $"You Can View The Changelog At {updateInfo.DownloadUrl}. Do You Want To Update Now?",
                                "Update Required",
                                MessageBoxButtons.YesNo,
                                MessageBoxIcon.Error);
                            if (result == DialogResult.Yes) await UpdateAsync(updateInfo);
                            else Environment.Exit(1);
                        }
                    }
                }
            }
            catch (HttpRequestException ex)
            {
                Debug.WriteLine("Client Update HTTP Request Failed - " + ex.Message);
            }
            catch (JsonException)
            {
                Debug.WriteLine("Client Update Info From Server Invalid");
            }
        }

        private async Task UpdateAsync(ClientUpdateInfo updateInfo)
        {
            HttpClient client = new();
            client.BaseAddress = new Uri("https://qtcclient.alanmoon.net");

            try
            {
                // if bak file already exists, delete it
                if (File.Exists($"/{updateInfo.ClientFileName}.bak")) File.Delete($"/{updateInfo.ClientFileName}.bak");

                // move old client to backup file
                File.Move($"./{updateInfo.ClientFileName}", $"{updateInfo.ClientFileName}.bak");

                // download new client version
                var clientFileStream = await client.GetStreamAsync(updateInfo.ClientFileName);
                using (var fs = new FileStream($"./{updateInfo.ClientFileName}", FileMode.Create))
                {
                    clientFileStream.CopyTo(fs);
                    fs.Dispose();
                }
                clientFileStream.Dispose();

                // restart the process
                Process process = new Process();
                process.StartInfo = new ProcessStartInfo { FileName = $"./{updateInfo.ClientFileName}", WorkingDirectory = Environment.CurrentDirectory };

                process.Start();
                Environment.Exit(0);
            }
            catch (HttpRequestException ex)
            {
                MessageBox.Show($"Update Failed. Please Check Your Internet Connection.\n{ex.Message}",
                    "Update Failed",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
            catch (UnauthorizedAccessException ex)
            {
                MessageBox.Show($"Update Failed. Permissions In Client Folder Are Wrong.\n{ex.Message}",
                    "Update Failed",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }
    }
}
