using BPA.SingleDevice.Interface;

namespace BPA.SingleDevice.Services
{
    public class LogService : ILogService
    {
        private readonly ISqlHelper sqlHelper;

        private static readonly object runLock = new object();
        private static readonly object userlock = new object();
        private static readonly object alarmlock = new object();
        private static readonly object recipeLogslock = new object();
        private static readonly object debugLock = new object();

        public ObservableCollection<RunLogTB> RunLogs { get; set; } = new();
        public ObservableCollection<UserLogTB> UserLogs { get; set; } = new();
        public ObservableCollection<RecipeCompleteLogTB> RecipeCompleteLogs { get; set; } = new();
        public ObservableCollection<AlarmLogTB> AlarmLogs { get; set; } = new();
        public ObservableCollection<DebugLogTB> DebugLogs { get; set; } = new();

        public LogService()
        {
            this.sqlHelper = SqlHelper.GetInstance;
        }

        public void LogAlarmInfo(string info)
        {
            throw new NotImplementedException();
        }

        public void LogDebugInfo(string info)
        {
            lock (debugLock)
            {
                try
                {
                    DebugLogTB log = new()
                    {
                        Date = DateTime.Now.ToString("yyyy-MM-dd"),
                        Time = DateTime.Now.ToString("HH:mm:ss"),
                        DebugInfo = info
                    };

                    sqlHelper.AddAsync(log);
                    App.Current.Dispatcher.Invoke(() => { DebugLogs.Insert(0, log); });
                }
                catch (Exception)
                {
                    // throw;
                }
            }
        }

        public void LogRecipeCompleteInfo(string info)
        {
            lock (recipeLogslock)
            {
                try
                {
                    RecipeCompleteLogTB log = new()
                    {
                        Date = DateTime.Now.ToString("yyyy-MM-dd"),
                        Time = DateTime.Now.ToString("HH:mm:ss"),
                        RecipeName = info
                    };

                    sqlHelper.AddAsync(log);
                    App.Current.Dispatcher.Invoke(() => { RecipeCompleteLogs.Insert(0, log); });
                }
                catch (Exception)
                {
                    // throw;
                }
            }
        }

        public void LogRunInfo(string info)
        {
            lock (runLock)
            {
                try
                {
                    RunLogTB runLog = new()
                    {
                        Date = DateTime.Now.ToString("yyyy-MM-dd"),
                        Time = DateTime.Now.ToString("HH:mm:ss"),
                        RunLogInfo = info
                    };

                    sqlHelper.AddAsync(runLog);
                    App.Current.Dispatcher.Invoke(() => { RunLogs.Insert(0, runLog); });
                }
                catch (Exception)
                {
                    // throw;
                }
            }
        }

        public void LogUserInfo(string info, string userName = "")
        {
            lock (userlock)
            {
                try
                {
                    UserLogTB log = new()
                    {
                        Date = DateTime.Now.ToString("yyyy-MM-dd"),
                        Time = DateTime.Now.ToString("HH:mm:ss"),
                        UserName = userName,
                        UserLogInfo = info
                    };

                    sqlHelper.AddAsync(log);
                    App.Current.Dispatcher.Invoke(() => { UserLogs.Insert(0, log); });
                }
                catch (Exception)
                {
                    // throw;
                }
            }
        }

        public async Task<List<T>> GetAllLog<T>() where T : LogBase
        {
            var logs = await sqlHelper.GetListAsync<T>();
            if (logs.IsSuccess)
            {
                return logs.Content;
            }
            return null;
        }
    }
}