using ReAct_PME.WPF_FrameWork;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Data;
using ToolsServices;

namespace ReAct_PME.ViewModels
{
    public class VoirLogs_VM : BaseViewModel
    {
        #region Classe interne pour une entrée de log
        public class LogEntry
        {
            public string Part1 { get; set; } = "";
            public string Part2 { get; set; } = "";
            public string Part3 { get; set; } = "";
        }
        #endregion

        #region Variables
        private DateTime DateRef=DateTime.Now;
        private bool IsFirstPassage = true;
        #endregion

        #region Propriétés
        private bool _showDebug = false;
        public bool ShowDebug
        {
            get => _showDebug;
            set { _showDebug = value; OnPropertyChanged(); ApplyFilter(); }
        }

        private bool _showInfo = true;
        public bool ShowInfo
        {
            get => _showInfo;
            set { _showInfo = value; OnPropertyChanged(); ApplyFilter(); }
        }

        private bool _showWarning = true;
        public bool ShowWarning
        {
            get => _showWarning;
            set { _showWarning = value; OnPropertyChanged(); ApplyFilter(); }
        }

        private bool _showError = true;
        public bool ShowError
        {
            get => _showError;
            set { _showError = value; OnPropertyChanged(); ApplyFilter(); }
        }

        public string DateRefStr { get => DateRef.ToString("dd-MM-yyyy"); }

        public ObservableCollection<LogEntry> TexteLog { get; set; } = new();
        public ICollectionView LogsView { get; }
        #endregion

        #region Constructeur
        public VoirLogs_VM()
        {
            LogsView = CollectionViewSource.GetDefaultView(TexteLog);
            LogsView.Filter = LogFilter;

            MAJ_Liste();
        }
        #endregion

        #region Méthodes publiques
        public void GetLogPreviousDay()
        {
            DateRef = DateRef.AddDays(-1);
            MAJ_Liste();
        }

        public void GetLogNextDay()
        {
            DateRef = DateRef.AddDays(+1);
            MAJ_Liste();
        }
        #endregion

        #region Méthodes privées
        private bool LogFilter(object item)
        {
            if (item is not LogEntry log) return false;

            return (ShowDebug && log.Part1.Equals("[Debug]", StringComparison.OrdinalIgnoreCase)) ||
                   (ShowInfo && log.Part1.Equals("[Info]", StringComparison.OrdinalIgnoreCase)) ||
                   (ShowWarning && log.Part1.Equals("[Warning]", StringComparison.OrdinalIgnoreCase)) ||
                   (ShowError && log.Part1.Equals("[Error]", StringComparison.OrdinalIgnoreCase));
            
        }

        private void ApplyFilter()
        {
            LogsView.Refresh();
            OnPropertyChanged(nameof(LogsView));
        }

        private void MAJ_Liste()
        {
            var txt = LoggerService.GetLogDay(DateRef);
            var newLogs = ParseLogs(txt);

            TexteLog.Clear();
            
            foreach (var log in newLogs)
                TexteLog.Add(log);

            OnPropertyChanged(nameof(DateRefStr));
            OnPropertyChanged(nameof(TexteLog));

            LogsView.Refresh(); // applique le filtre sur les nouveaux logs
            OnPropertyChanged(nameof(LogsView));
        }

        private List<LogEntry> ParseLogs(string logContent)
        {
            var result = new List<LogEntry>();

            if (string.IsNullOrWhiteSpace(logContent))
            {
                result.Add(new LogEntry
                {
                    Part1 = "...",
                    Part2 = "...",
                    Part3 = "Aucun log pour cette date"
                });
                return result;
            }

            var knownLevels = new[] { "[Debug]", "[Info]", "[Warning]", "[Error]" };

            LogEntry? currentEntry = null;

            foreach (var line in logContent.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries))
            {
                var trimmed = line.Trim();

                // Cas : nouvelle ligne de log
                if (knownLevels.Any(lvl => trimmed.StartsWith(lvl, StringComparison.OrdinalIgnoreCase)))
                {
                    var parts = trimmed.Split('\t');

                    currentEntry = new LogEntry
                    {
                        Part1 = parts.ElementAtOrDefault(0) ?? "",
                        Part2 = parts.ElementAtOrDefault(1) ?? "",
                        Part3 = parts.ElementAtOrDefault(2) ?? ""
                    };
                    result.Add(currentEntry);
                }
                else
                {
                    // Ligne de continuation → on colle dans le message du log précédent
                    if (currentEntry != null)
                    {
                        if (!string.IsNullOrEmpty(currentEntry.Part3))
                            currentEntry.Part3 += Environment.NewLine;

                        currentEntry.Part3 += trimmed;
                    }
                    else
                    {
                        // Sécurité : si jamais on tombe sur une ligne avant la 1ère entrée
                        result.Add(new LogEntry { Part1 = "???", Part2 = "", Part3 = trimmed });
                    }
                }
            }

            return result;
        }

        private List<LogEntry> ParseLogs2(string logContent)
        {
            if(logContent == "")
            {
                var lst = new List<LogEntry>();
                var l = new LogEntry { Part1 = "...", Part2 = "...", Part3 = "Aucun log pour cette date" };
                lst.Add(l);
                return lst;
            }

            return logContent
                .Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(line =>
                {
                    var parts = line.Split('\t');
                    return new LogEntry
                    {
                        Part1 = parts!.ElementAtOrDefault(0)!,
                        Part2 = parts!.ElementAtOrDefault(1)!,
                        Part3 = parts!.ElementAtOrDefault(2)!
                    };
                })
                .ToList();
        }
        #endregion
    }
}
