using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Windows;
using Zerolauncher.Defender;

namespace Zerolauncher.Manager
{

    class UpDateManager
    {
        public static bool state = false;
        static bool isCheeking = false;
        static SingleGame? updateProcess;

        public static void DoCheckUpdate(bool checkMain=true, bool needEngine = false)
        {
            if (isCheeking) return;
            isCheeking=true;
            bool needMian= false;
            if(checkMain)
            {
                string filePath = Process.GetCurrentProcess().MainModule.FileName;
                string? now_bit;
                using (SHA256 sha256 = SHA256.Create())
                {
                    using (FileStream fileStream = File.OpenRead(filePath))
                    {
                        byte[] hashBytes = sha256.ComputeHash(fileStream);
                        now_bit = BitConverter.ToString(hashBytes).Replace("-", string.Empty);
                    }
                }
                //now_bit = "170CD25DCCF3FFCCFAA423B85E1715E7CD28959333C4C5F86FB1E73666359998";
                needMian = now_bit == CacheSha.GetM() && now_bit != null;
            }
            if(!needEngine) 
            {
                string? now_bit;
                using (SHA256 sha256 = SHA256.Create())
                {
                    using (FileStream fileStream = File.OpenRead(@"ZeroEngine.exe"))
                    {
                        byte[] hashBytes = sha256.ComputeHash(fileStream);
                        now_bit = BitConverter.ToString(hashBytes).Replace("-", string.Empty);
                    }
                }
                needEngine = now_bit == CacheSha.GetE() && now_bit != null;
            }
            state = !(needEngine && needMian);
            isCheeking = false;
        }

        public static void DoUpdate()
        {
            if (CacheSha.errorCode != 0)
            {
                switch (CacheSha.errorCode)
                {
                    case 1:
                        MessageBox.Show("检查更新出错。\n 请检查网络", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                        break;
                    case 2:
                        MessageBox.Show("软件已停止服务或服务错误。\n 请联系管理员", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                        break;
                    default:
                        MessageBox.Show("检查更新出错。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                        break;
                }
                return;
            }
            MessageBoxResult result = MessageBox.Show($"大厅组件需要更新\n是否更新?", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning);
            if (result == MessageBoxResult.OK)
            {
                try
                {
                    updateProcess = new SingleGame(null, StaticHandleA.UpdateMode);
                    return;
                }
                catch (Exception _ex)
                {
                    MessageBox.Show("执行自动更新失败！，\n请手动访问链接重新下载大厅文件或联系管理员。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        public static void DoUpdate1()
        {
            updateProcess.Send($"{StaticHandleS.ShowWindow} 自助更新");
        }

        public static void DoUpdate2()
        {
            updateProcess.Send($"{StaticHandleS.UpdateInfo} {UpDateData.tis}");
            updateProcess.Send($"{StaticHandleS.UseBrowser} {UpDateData.lanzou + UpDateData.auto_packet_url}");
        }

        public static void OnDownLoadDone(string path)
        {
            updateProcess.Send(StaticHandleS.CloseGame);
            try
            {
                if (Directory.Exists("./cache/")) Directory.Delete("./cache/", true);
                ZipFile.ExtractToDirectory(path, "./cache/");
                File.Delete(path);
            }catch(Exception e)
            {
                MessageBox.Show($"尝试更新文件时发生错误\n{e.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            App.needUpdate = true;
            Application.Current.Dispatcher.Invoke(() => Application.Current.Shutdown());
        }

    }
}
