using ToolsServices;
using Services;
using ReAct_PME.WPF_FrameWork;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Threading;
using Services.ReActAgent;

namespace ReAct_PME.ViewModels
{
    #region ViewModel ListeEmails_VM
    public class ListeEmails_VM : BaseViewModel
    {
        #region Propriétés
        public ObservableCollection<EmailMessage>? ListeItems { get; set; } = new();
        private ObservableCollection<EmailMessage>? ListeItemsNoFiltered { get; set; } = new();

        private string _RechercheString = "";
        public string RechercheString
        {
            get => _RechercheString;
            set
            {
                _RechercheString = value;
                OnPropertyChanged();
            }
        }

        private EmailMessage? _selectedItem;
        public EmailMessage? SelectedItem
        {
            get => _selectedItem;
            set
            {
                if (_selectedItem != value)
                {
                    _selectedItem = value;
                    OnPropertyChanged();
                }
            }
        }

        private bool _IsOnlyImportants { get; set; } = false;
        public bool IsOnlyImportants
        {
            get => _IsOnlyImportants;
            set
            {
                _IsOnlyImportants = value;
                OnPropertyChanged(nameof(IsOnlyImportants));
                FiltrerListe();
            }
        }


        private bool _IsOnlyUrgents { get; set; } = false;
        public bool IsOnlyUrgents
        {
            get => _IsOnlyUrgents;
            set
            {
                _IsOnlyUrgents = value;
                OnPropertyChanged(nameof(IsOnlyUrgents));
                FiltrerListe();
            }
        }

        public string MessageEnteteTotal
        {
            get
            {
                if (ListeItems == null)
                    return "0";
                int total = ListeItems!.Count;
                return $"{total}";
            }
        }
        public string MessageEnteteImportant
        {
            get
            {
                if (ListeItems == null)
                    return "0";
                int importants = ListeItems.Count(e => e.IsImportant && !e.IsUrgent);
                return $"{importants}";
            }
        }
        public string MessageEnteteUrgent
        {
            get
            {
                if (ListeItems == null)
                    return "0";
                int urgents = ListeItems.Count(e => e.IsUrgent && !e.IsImportant);
                return $"{urgents}";
            }
        }
        public string MessageEnteteImportantEtUrgent
        {
            get
            {
                if (ListeItems == null)
                    return "0";
                int urgentsEtImportants = ListeItems.Count(e => e.IsUrgent && e.IsImportant);
                return $"{urgentsEtImportants}";
            }
        }
        public string MessageEntete
        {
            get
            {
                int total = ListeItems!.Count;
                int importants = ListeItems.Count(e => e.IsImportant && !e.IsUrgent);
                int urgents = ListeItems.Count(e => e.IsUrgent && !e.IsImportant);
                int urgentsEtImportants = ListeItems.Count(e => e.IsUrgent && e.IsImportant);

                string Pluriel(int n, string mot) => n > 1 ? $"{mot}s" : mot;

                return $"{total} mail{(total > 1 ? "s" : "")} non lu{(total > 1 ? "s" : "")} dont " +
                       $"{urgentsEtImportants} {Pluriel(urgentsEtImportants, "important et urgent")}, " + 
                       $"{importants} {Pluriel(importants, "important")}, " +
                       $"{urgents} {Pluriel(urgents, "urgent")}, " +
                       $" -- Mise à jour : {DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss")}";
            }
        }
        #endregion

        #region Variables
        private DispatcherTimer _emailCheckTimerStart;
        private DispatcherTimer _emailCheckTimer;
        private double _DelaySeekMails = 15; // temps de rafrachissement de la boite mails, en minutes
        private readonly IToastNotifier _Notifier;
        #endregion

        #region Constructeur
        public ListeEmails_VM(IToastNotifier notifier)
        {
            var paramUser = Services.EmailService.LoadParametres();
            if(paramUser != null)
                _DelaySeekMails = paramUser.DelayRefresh;

            _Notifier = notifier;

            // 1 minute après le chargement, on lance une première récup (une seule fois)
            _emailCheckTimerStart = new DispatcherTimer
            {
                Interval = TimeSpan.FromMinutes(15)
            };
            _emailCheckTimerStart.Tick += async (s, e) => await CheckForNewEmails();
            _emailCheckTimerStart.Start();

            // Le chargement initial (json ou boite mail, selon si json existe ou pas)
            LoadEmails();

            // On programme une récup récurente toutes les x minutes
            _emailCheckTimer = new DispatcherTimer
            {
                Interval = TimeSpan.FromMinutes(_DelaySeekMails)
            };
            _emailCheckTimer.Tick += async (s, e) => await CheckForNewEmails();
            _emailCheckTimer.Start();

        }
        #endregion

        #region Méthodes publiques
        public void Quit()
        {
            _emailCheckTimerStart.Stop();
            _emailCheckTimer.Stop();
        }

        public void ShowSelectedItem()
        {
            if (SelectedItem == null)
            {
                MessageBox.Show("Veuillez sélectionner un email pour voir les détails.");
                return;
            }

            var f = new DetailEmail(SelectedItem);
            f.ShowDialog();

            if(SelectedItem.ToRemove)
            {
                ListeItems!.Remove(SelectedItem);
                MAJ_Messages();
            }
            Services.EmailService.SauvegarderEmails(ListeItems!);


        }

        public async Task RefreshEmails()
        {
            try
            {
                await CheckForNewEmails();
                _Notifier.ShowToast("Liste des emails rafraîchie.", 3000);
            }
            catch (Exception ex)
            {
                _Notifier.ShowToast($"Erreur lors du rafraîchissement : {ex.Message}", 5000);
                LoggerService.LogError($"Erreur lors du rafraîchissement : {ex.Message}");
            }
        }

        public async Task<string> SeekByKeyWord()
        {
            var reponse = await Services.EmailService.SeekByKeyWord(RechercheString);
            return reponse;
        }
        #endregion

        #region Méthodes privées
        private void MAJ_Messages()
        {
            OnPropertyChanged(nameof(MessageEnteteTotal));
            OnPropertyChanged(nameof(MessageEnteteImportant));
            OnPropertyChanged(nameof(MessageEnteteUrgent));
            OnPropertyChanged(nameof(MessageEnteteImportantEtUrgent));
            OnPropertyChanged(nameof(MessageEntete));
        }

        private async void LoadEmails()
        {
            ListeItems = Services.EmailService.ChargerEmailsDepuisJson();

            // Si rien dans le json, on regarde dans la boite mails
            if (ListeItems.Count == 0)
            {
                // Dans ce cas, on annule la première récup (car on la fait en ce moment)
                await Task.Delay(1);
                //await CheckForNewEmails();
                if (ListeItems == null)
                    ListeItems = new();

                Services.EmailService.SauvegarderEmails(ListeItems);
            }
            ListeItems = new ObservableCollection<EmailMessage>(ListeItems.OrderByDescending(e => e.Date));
            ListeItemsNoFiltered = ListeItems;
            OnPropertyChanged(nameof(ListeItems));
            MAJ_Messages();

            string pluriel = "";
            if(ListeItems.Count > 1)
                pluriel = "s";
            _Notifier.ShowToast($"{ListeItems.Count} email{pluriel} dans la liste.",5000);
        }

        private bool IsTraitementActif = false;
        private async Task CheckForNewEmails()
        {
            LoggerService.LogInfo("ListeEmails_VM.CheckForNewEmails");
            if(IsTraitementActif)
            {
                LoggerService.LogDebug("Traitement déjà en cours, on sort.");
                return;
            }
            IsTraitementActif = true;

            var b = await ReActAgent.IsOllamaActif(false);
            if (!b)
            {
                var msg = "Ollama n'est pas démarré. Veuillez lancer Ollama Desktop ou le service Ollama.";
                LoggerService.LogWarning(msg);
                _Notifier.ShowToast($"{msg}", 5000);
                return;
            }

            _emailCheckTimerStart.Stop();
            _emailCheckTimer.Stop();
            try
            {
                int nbrMsgImportant = 0;
                int nbrMsgUrgent = 0;
                int nbrMsgImportantEtUrgent = 0;

                var newEmails = await Services.EmailService.LireEmailsAsync(ListeItems);

                if (newEmails != null && newEmails.Count > 0)
                {
                    if (ListeItems != null && ListeItems.Count > 0)
                    {
                        // Ajouter ceux qui n'y sont pas
                        foreach (var email in newEmails)
                        {
                            if (!ListeItems.Any(e => e.Id == email.Id))
                            {
                                ListeItems.Insert(0, email); // ajoute en haut de la liste

                                if (email.IsImportant && email.IsUrgent)
                                    nbrMsgImportantEtUrgent++;
                                if (email.IsImportant && !email.IsUrgent)
                                    nbrMsgImportant++;
                                if (!email.IsImportant && email.IsUrgent)
                                    nbrMsgUrgent++;
                            }
                        }
                    }
                    else
                    {
                        ListeItems = newEmails;
                    }

                }

                // Les mails présents dans la liste mais absents de la boite mail : à enlever de la liste
                if (ListeItems != null)
                {
                    var tempListeItems = new ObservableCollection<EmailMessage>();
                    foreach (var email in ListeItems)
                    {
                        if(!email.ToRemove)
                        {
                            tempListeItems.Add(email);
                        }
                    }

                    ListeItems = new ObservableCollection<EmailMessage>(tempListeItems!.OrderByDescending(e => e.Date));
                    ListeItemsNoFiltered = ListeItems;
                    OnPropertyChanged(nameof(ListeItems));
                    MAJ_Messages();

                    Services.EmailService.SauvegarderEmails(ListeItems);
                }

                // Envoyer message
                if(nbrMsgImportantEtUrgent>0 || nbrMsgImportant > 0 || nbrMsgUrgent > 0)
                {
                    string message = "";
                    if(nbrMsgImportantEtUrgent > 0)
                        message += $"Important Et Urgent  : {nbrMsgImportantEtUrgent }\n";
                    if (nbrMsgImportant > 0)
                        message += $"Important            : {nbrMsgImportant}\n";
                    if (nbrMsgUrgent > 0)
                        message += $"Urgent               : {nbrMsgUrgent}\n";


                    NotificationManager.ShowNotification(message, "Recherche de nouveaux mails");
                }
            }
            catch (Exception ex)
            {
                // Log ou notifier l’erreur
                LoggerService.LogError($"Erreur lors de la vérification des nouveaux emails : {ex.Message}");
            }
            finally
            {
                _emailCheckTimer.Start();
                IsTraitementActif = false;
                LoggerService.LogInfo("Vérification des nouveaux emails terminées...");
            }
        }

        private void FiltrerListe()
        {
            if (ListeItemsNoFiltered == null || ListeItemsNoFiltered.Count == 0)
                return;

            if (IsOnlyImportants && IsOnlyUrgents)
            {
                ListeItems = new ObservableCollection<EmailMessage>(ListeItemsNoFiltered!.Where(e => e.IsImportant && e.IsUrgent).OrderByDescending(e => e.Date));
            }
            else if (IsOnlyImportants && !IsOnlyUrgents)
            {
                ListeItems = new ObservableCollection<EmailMessage>(ListeItemsNoFiltered!.Where(e => e.IsImportant).OrderByDescending(e => e.Date));
            }
            else if (!IsOnlyImportants && IsOnlyUrgents)
            {
                ListeItems = new ObservableCollection<EmailMessage>(ListeItemsNoFiltered!.Where(e => e.IsUrgent).OrderByDescending(e => e.Date));
            }
            else
            {
                ListeItems = new ObservableCollection<EmailMessage>(ListeItemsNoFiltered!.OrderByDescending(e => e.Date));
            }
            OnPropertyChanged(nameof(ListeItems));

            OnPropertyChanged(nameof(MessageEnteteTotal));
            OnPropertyChanged(nameof(MessageEnteteImportant));
            OnPropertyChanged(nameof(MessageEnteteUrgent));
            OnPropertyChanged(nameof(MessageEnteteImportantEtUrgent));
            OnPropertyChanged(nameof(MessageEntete));
        }

        #endregion
    }
    #endregion
}
