using Blazored.Toast.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using ReAct_PME.Domain;
using ReAct_PME.WebUI.ServicesUI;
using System.Net.Http.Json;
using System.Text.Json;


namespace ReAct_PME.WebUI.Pages.ChatRoom
{
    public partial class ChatRoom_base: ComponentBase
    {
        [Parameter] public int TypeLLM { get; set; }

        [Inject] public HttpClient Http { get; set; } = default!;
        [Inject] private ReAct_PME.WebUI.ServicesUI.AuthService AuthService { get; set; } = default!;
        [Inject] private AuthenticationStateProvider AuthenticationStateProvider { get; set; } = default!;
        [Inject] private NavigationManager Navigation { get; set; } = default!;
        [Inject] private IToastService ToastService { get; set; } = default!;

        public class UploadedDoc
        {
            public string FileName { get; set; } = "";
            public byte[] Bytes { get; set; } = Array.Empty<byte>();
        }
        public List<UploadedDoc> UploadedDocuments { get; set; } = new();
        // État de l'UI
        public List<ConversationDto> Conversations { get; set; } = new();
        public ConversationDto? SelectedConversation { get; set; }
        public string SelectedConversationId { get; set; } = "";
        public List<MessageDto> Messages { get; set; } = new();
        private bool IsWithHistorique { get; set; }

        public string CurrentInput { get; set; } = "";

        // Options
        public List<string> RagDomains { get; set; } = new();
        public List<string> OllamaModels { get; set; } = new();
        public string SelectedModel { get; set; } = "";
        public string SelectedMode { get; set; } = "";
        public string SelectedDomain { get; set; } = "";
        private bool IsNewConversation = false;
        public bool hiddenDomain = true;

        protected override async Task OnInitializedAsync()
        {
            #region Vérification si utilisateur est connecté et s''il a les droits

            var tok = await PagesInitializer.VerifConnexionAndRules(AuthenticationStateProvider, Navigation, Http, ToastService, "/api/ChatRoom/rag/listeDomaines");
            if (tok == null || tok.Length == 0)
                return;
            else
                AuthService.SetToken(tok);

            #endregion


            await LoadConversations();

            //await LoadOllamaModels();

            if (TypeLLM == 1)
            {
                SelectedMode = "llm";
                IsWithHistorique= true;
            }
            else if(TypeLLM == 2)
            {
                SelectedMode = "rag";
                IsWithHistorique = false;
                hiddenDomain = false;
                await LoadRagDomains();
                SelectedDomain = RagDomains[0];
            }
            else if (TypeLLM == 3)
            {
                SelectedMode = "code";
                IsWithHistorique = true;
            }
            else if (TypeLLM == 4)
            {
                SelectedMode = "image";
                IsWithHistorique = false;
            }
            else 
            {
                SelectedMode = "llm";
                IsWithHistorique = true;
            }


        }

        private async Task UploadDocuments(InputFileChangeEventArgs e)
        {
            foreach (var file in e.GetMultipleFiles())
            {
                using var stream = file.OpenReadStream(maxAllowedSize: 20 * 1024 * 1024); // 20 Mo
                using var ms = new MemoryStream();
                await stream.CopyToAsync(ms);

                UploadedDocuments.Add(new UploadedDoc
                {
                    FileName = file.Name,
                    Bytes = ms.ToArray()
                });
            }

            StateHasChanged();
        }
        
        private void RemoveDocument(UploadedDoc doc)
        {
            UploadedDocuments.Remove(doc);
        }

        private async Task LoadConversations()
        {
            Conversations = await Http.GetFromJsonAsync<List<ConversationDto>>($"/api/ChatRoom/conversations/{AuthService.ID}/{TypeLLM}")
                            ?? new();

            Conversations = Conversations.OrderByDescending(c => c.Messages.Any() ? c.Messages.Max(m => m.CreatedAt) : DateTime.MinValue).ToList();
            StateHasChanged();
        }

        private async Task LoadRagDomains()
        {
            RagDomains = await Http.GetFromJsonAsync<List<string>>("/api/ChatRoom/rag/listeDomaines")
                         ?? new();
        }

        private async Task LoadOllamaModels()
        {
            OllamaModels = await Http.GetFromJsonAsync<List<string>>("/api/ChatRoom/ollama/models")
                           ?? new();

            if (OllamaModels.Count > 0)
                SelectedModel = OllamaModels[0];
        }

        public void CreateConversation()
        {
            //var newConv = await Http.PostAsJsonAsync("/api/ChatRoom/conversation/create", new { });

            //var created = await newConv.Content.ReadFromJsonAsync<ConversationDto>();

            ConversationDto newConversation = new();

            if (newConversation != null)
            {
                IsNewConversation = true;
                Conversations.Add(newConversation);
                SelectConversation(newConversation.Id);
            }
        }

        public void SelectConversation(string id)
        {
            SelectedConversationId = id;

            SelectedConversation  = Conversations.Where(c => c.Id == id).FirstOrDefault();

            Messages = SelectedConversation?.Messages.OrderBy(m=>m.CreatedAt).ToList() ?? new();

            StateHasChanged();
        }

        public async Task SendMessage()
        {
            if (string.IsNullOrWhiteSpace(CurrentInput) || SelectedConversation == null)
                return;

            // Ajoute ton message dans l'UI immédiatement
            var userMsg = new MessageDto
            {
                IsUser = true,
                Text = CurrentInput
            };
            Messages.Add(userMsg);

            var payload = new SendMessageRequest
            {
                ConversationId = IsNewConversation ? Guid.NewGuid().ToString() : SelectedConversation.Id,
                IsNewConversation = IsNewConversation,
                IdWorkForce = AuthService!.ID!,
                Mode = SelectedMode.ToUpper(),
                Domain = SelectedDomain,
                Documents64 = UploadedDocuments.Select(d => Convert.ToBase64String(d.Bytes)).ToList(),
                Documents = UploadedDocuments.Select(d => d.FileName).ToList(),
                Role = "user",
                //Model = SelectedModel,
                Text = CurrentInput,
                Context = IsWithHistorique ? string.Join("\n ", Messages.Select(m => m.Text)) : ""

            };



            CurrentInput = "";

            var response = await Http.PostAsJsonAsync("/api/ChatRoom/sendMessage", payload);

            if (response.IsSuccessStatusCode)
            {
                var assistantMsg = await response.Content.ReadFromJsonAsync<MessageDto>();
                if (assistantMsg != null)
                {
                    Messages.Add(assistantMsg);
                }
            }

            if(IsNewConversation)
            {
                // Met à jour la liste des conversations
                await LoadConversations();
                SelectConversation(payload.ConversationId);
                IsNewConversation = false;
            }

            UploadedDocuments.Clear();
            StateHasChanged();
        }
    }
}

