using qtc_net_client_2.ClientModel;
using qtc_net_client_2.Services;
using QtCNETAPI.Services;
using QtCNETAPI.Services.ApiService;
using QtCNETAPI.Services.GatewayService;
using System.Text.Json;
using System.Threading.Tasks;

namespace qtc_net_client_2
{
    internal static class Program
    {
        /// <summary>
        ///  The main entry point for the application.
        /// </summary>
        [STAThread]
        static async Task Main()
        {
            // first thing, create a new log
            LoggingService loggingService = new();

            Config clientConfig = new Config();

            if(System.Diagnostics.Debugger.IsAttached)
            {
                // use localhost
                clientConfig.ServerUrl = "http://localhost:5268";
            }

            // find config file
            if(!File.Exists("./config.json"))
            {
                // create it using default config model
                string configJson = JsonSerializer.Serialize(clientConfig, options: new JsonSerializerOptions { WriteIndented = true });
                File.WriteAllText("./config.json", configJson);
            } else
            {
                try
                {
                    // use config in file
                    Config? fileConfig = JsonSerializer.Deserialize<Config>(File.ReadAllText("./config.json"));
                    if (fileConfig != null)
                    {
                        clientConfig = fileConfig;
                    }
                } catch (JsonException)
                {
                    // there was a missing property, reset config to default
                    string configJson = JsonSerializer.Serialize(clientConfig, options: new JsonSerializerOptions { WriteIndented = true });
                    File.WriteAllText("./config.json", configJson);
                }
            }

            // instantiate new ApiService and GatewayService for this session
            // this will keep the gateway thread in the main thread (i think)
            IApiService api = new ApiService($"{clientConfig.ServerUrl}/api", loggingService);
            IGatewayService gateway = new GatewayService($"{clientConfig.ServerUrl}/chat", api, loggingService);

            // ping api
            var pingResult = await api.PingServerAsync();
            if (!pingResult.Success)
            {
                MessageBox.Show("The Server Specified In The Config Could Not Be Reached.\nCheck The URL Specified, Otherwise Contact The Server Admin.", "Uh Oh.", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(1);
            }

            // check for updates
            UpdateService updateService = new();
            await updateService.CheckForUpdatesAsync();

            // To customize application configuration such as set high DPI settings or default font,
            // see https://aka.ms/applicationconfiguration.
            ApplicationConfiguration.Initialize();
            Application.Run(new Main(api, gateway, clientConfig, loggingService));

            // if application loop is exited, dispose everything
            await gateway.DisposeAsync();
            loggingService.Dispose();

            api = null!; // shut up compiler >:(
            gateway = null!;

            Environment.Exit(0);
        }
    }
}