using Newtonsoft.Json;
using System;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Text;


namespace SolviaOneDriveKillerLib.Helpers
{
    public static class Logging
    {
        public enum LogLevel
        {
            Info,
            Error,
            Warning,
            Debug,
            Fatal
        }

        private static readonly string logDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
        private static readonly object lockObj = new object(); // Object used for thread synchronization

        public static void Log(LogLevel level, string message)
        {
            lock (lockObj) // Ensure only one thread can enter this block at a time
            {
                EnsureLogDirectoryExists();

                var logFilePath = GetLogFilePath();
                var caller = GetCallerMethodName();
                var logMessage = FormatLogMessage(level, message, caller);

                File.AppendAllText(logFilePath, logMessage + Environment.NewLine);
            }
        }

        private static void EnsureLogDirectoryExists()
        {
            if (!Directory.Exists(logDirectory))
            {
                Directory.CreateDirectory(logDirectory);
            }
        }

        private static string GetLogFilePath()
        {
            // Get the name of the executing assembly
            var assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;

            // Combine the assembly name with the current date to form the file name
            var fileName = $"{assemblyName}_{DateTime.Now:yyyy-MM-dd}.txt";

            return Path.Combine(logDirectory, fileName);
        }


        private static string FormatLogMessage(LogLevel level, string message, string caller)
        {
            return $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [{level}] ({caller}) {message}";
        }

        private static string GetCallerMethodName()
        {
            var stackTrace = new StackTrace();
            // Skip the current method (GetCallerMethodName) and the Log method, hence start with index 2
            var frame = stackTrace.GetFrame(2); // Adjust the index based on your call stack
            if (frame != null)
            {
                var method = frame.GetMethod();
                return method.DeclaringType.FullName + "." + method.Name;
            }
            return "Unknown";
        }

        public static void SendToLog(string message)
        {
            Log(LogLevel.Info, $"Will SendToLog: {message}");
            // Sample data to send
            var body = new
            {
                hostname = Environment.MachineName,
                message,
                client = "Solvia",
                notes = Environment.UserName,
                custom1 = "Custom data 1",
                custom2 = "Custom data 2",
                custom3 = "Custom data 3",
                custom4 = "Custom data 4",
                custom5 = "Custom data 5",
                secret = "Solvia-2024!"
            };

            string jsonString = JsonConvert.SerializeObject(body);


            // API endpoint directly pointing to the PHP file
            string uri = "https://logging.solvia.ch/put_operation.php";

            using (var client = new HttpClient())
            {
                try
                {
                    var content = new StringContent(jsonString, Encoding.UTF8, "application/json");
                    HttpResponseMessage response = client.PutAsync(uri, content).Result; // Use Result for synchronous call
                    string responseContent = response.Content.ReadAsStringAsync().Result;

                    string successMessage = "Success: " + DateTime.Now.ToString() + " - Response: " + responseContent;
                    Log(LogLevel.Info, successMessage);

                }
                catch (Exception ex)
                {
                    Log(LogLevel.Error, "Error: " + ex.Message);
                }
            }
        }
    }
}
