using ReAct_PME.ViewModels;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using ToolsServices;

namespace ReAct_PME
{
    /// <summary>
    /// Logique d'interaction pour ChatRoom.xaml
    /// </summary>
    public partial class ChatRoom : Window, IToastNotifier
    {
        private bool _shouldScroll = true;
        private ChatRoom_VM _VM;

        public ChatRoom(bool isRAG, bool isGenerateImg, bool isCoder)
        {
            InitializeComponent();
            _VM = new(this);
            this.DataContext = _VM;

            _VM.IsRAG = isRAG;
            _VM.IsGenerateImg = isGenerateImg;
            _VM.IsCODER = isCoder;

            ChkApiExterne.Visibility = Visibility.Collapsed;
            ChkIsWithAssistant.Visibility = Visibility.Collapsed;
            if (_VM.IsRAG)
            {
                ChkRAG.IsEnabled = false;
                ChkGenerateImg.Visibility = Visibility.Collapsed;

                this.Title = "ChatRoom - RAG";
            }
            else if (_VM.IsGenerateImg)
            {
                ChkGenerateImg.IsEnabled = false;
                ChkRAG.Visibility = Visibility.Collapsed;
                ChkIsWithAssistant.Visibility = Visibility.Visible;

                BtnSelectDoc.IsEnabled = true;
                SelectedDocumentsListView.IsEnabled = true;
                BtnDeleteDoc.IsEnabled = true;
                
                this.Title = "ChatRoom - Génération d'images";
            }
            else
            {
                ChkRAG.Visibility = Visibility.Collapsed;
                ChkGenerateImg.Visibility = Visibility.Collapsed;
                this.Title = "ChatRoom - LLM";
                if(isCoder)
                {
                    this.Title = "ChatRoom - Codeur";
                }

                if (System.IO.File.Exists(FichiersInternesService.ParamsApiExterne))
                {
                    var txt = System.IO.File.ReadAllText(FichiersInternesService.ParamsApiExterne);
                    if(txt.Trim().Length > 0)
                    {
                        ChkApiExterne.Visibility = Visibility.Visible;
                    }
                }
            }
            _VM.LoadModeles();
            _VM.LoadConversations();

        }

        private void ChatScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            // Si l'utilisateur scroll manuellement vers le haut, ne pas forcer le scroll
            _shouldScroll = e.ExtentHeight - e.ViewportHeight - e.VerticalOffset < 20;
        }
        
        private void ScrollToBottom()
        {
            if (_shouldScroll)
            {
                ChatScrollViewer.ScrollToEnd();
            }
        }
        
        private void OnMessageAdded()
        {
            ScrollToBottom();
        }

        private void OnConversationSelected(object sender, SelectionChangedEventArgs e)
        {
            if(_VM.SelectedConversation!=null)
                _VM.LoadConversation(_VM.SelectedConversation);
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            try 
            { 
                BtnEnvoyer.IsEnabled = false;
                BtnNewConv.IsEnabled = false;
                CboModels.IsEnabled = false;
                if(_VM.IsGenerateImg && _VM.IsWithAssistant && _VM.SelectedDocumentsListe.Count == 0)
                {
                    var rep = MessageBox.Show("Voulez-vous également que l'assistant IA génère lui-même les paramètres de génération de l'image ? Si non, ce seront vos paramètres qui seront pris en compte.", "Avec génération des pamaètres ?", MessageBoxButton.YesNo, MessageBoxImage.Question);
                    if(rep == MessageBoxResult.Yes)
                    {
                        _VM.IsGenerateParametres = true;
                    }
                    else
                    {
                        _VM.IsGenerateParametres = false;
                    }
                }

                var b = await _VM.SendMessage();
                if(b)
                {
                    OnMessageAdded();
                    BtnEnvoyer.IsEnabled = true;
                    BtnNewConv.IsEnabled = true;

                    if (_VM.IsGenerateImg)
                    {
                        ProcessStartInfo psi = new ProcessStartInfo
                        {
                            FileName = _VM.ImageURL,
                            UseShellExecute = true
                        };
                        Process.Start(psi);
                    }

                }
                else
                {
                    //MessageBox.Show($"Votre requête est vide ou vous n'avez pas sélectionné de modèle.", "Attention !", MessageBoxButton.OK, MessageBoxImage.Warning);
                    BtnEnvoyer.IsEnabled = true;
                    BtnNewConv.IsEnabled = true;
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show($"Erreur lors de l'envoi du message : {ex.Message}", "Erreur", MessageBoxButton.OK, MessageBoxImage.Error);
                BtnEnvoyer.IsEnabled = true;
                BtnNewConv.IsEnabled = true;
            }
        }

        private void BtnNewConv_Click(object sender, RoutedEventArgs e)
        {
            CboModels.IsEnabled = true;
            _VM.NewConversation();

        }

        private void BtnDeleteConv_Click(object sender, RoutedEventArgs e)
        {
            _VM.DeleteConversation();
        }

        private void BtnSelectDocumentsClick(object sender, RoutedEventArgs e)
        {
            string filter = "Fichiers supportés (*.png;*.jpg;*.jpeg;*.bmp;*.pdf;*.docx;*.xlsx;*.txt)|*.png;*.jpg;*.jpeg;*.bmp;*.pdf;*.docx;*.xlsx;*.txt";
            if (_VM.IsGenerateImg)
            {
                filter = "Images (*.png;*.jpg;*.jpeg)|*.png;*.jpg;*.jpeg";
            }
            else if(_VM.IsCODER)
            {
                filter =
                    "Fichiers de développement|*.cs;*.csproj;*.sln;*.vb;*.vbproj;*.fs;*.fsproj;*.config;*.resx;" +
                    "*.py;*.pyw;*.ipynb;*.pyi;*.pyd;" +
                    "*.c;*.h;*.cpp;*.cxx;*.cc;*.hpp;*.hh;*.ino;" +
                    "*.html;*.htm;*.css;*.js;*.ts;*.json;*.razor;" +
                    "*.xml;*.yml;*.yaml;*.toml;*.ini;*.sql;" +
                    "*.sh;*.bat;*.ps1;" +
                    "*.md;Dockerfile;*.dockerfile|" +
                    "Tous les fichiers (*.*)|*.*";
            }

            var dialog = new Microsoft.Win32.OpenFileDialog
                {
                    Filter = filter,

                    Multiselect = true
                };

            if (dialog.ShowDialog() == true)
            {
                foreach (var file in dialog.FileNames)
                {
                    // chemin complet pour le prompt
                    _VM.SelectedDocumentsPaths.Add(file);
                    // nom du fichier pour la listview
                    _VM.SelectedDocumentsListe.Add(System.IO.Path.GetFileName(file));
                }
            }
        }

        private void BtnDeleteDoc_Click(object sender, RoutedEventArgs e)
        {
            _VM.SelectedDocumentsPaths.Clear();
            _VM.SelectedDocumentsListe.Clear();
        }

        // Pour envoyer un message avec le clavier : CTRL + ENTREE
        private void TextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter && Keyboard.Modifiers == ModifierKeys.Control)
            {
                Button_Click(BtnEnvoyer, new RoutedEventArgs());
                e.Handled = true; // empêche l'ajout de la nouvelle ligne
            }
        }

        private void CopierMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if (sender is MenuItem menuItem &&
                menuItem.Parent is ContextMenu contextMenu &&
                contextMenu.PlacementTarget is System.Windows.Controls.TextBlock textBlock)
            {
                Clipboard.SetText(textBlock.Text);
            }
        }

        #region Implémentation de IToastNotifier
        public void ShowToast(string message, int durationMs = 10000)
        {
            Dispatcher.Invoke(() =>
            {
                ToastMessage.Text = message;
                ToastPopup.IsOpen = true;
            });

            Task.Delay(durationMs).ContinueWith(_ =>
            {
                Dispatcher.Invoke(() => ToastPopup.IsOpen = false);
            });
        }

        #endregion
    }
}
