using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using MauiAppStock.Models;
using MauiAppStock.Data;
using MauiAppStock.Helpers;

namespace MauiAppStock.ViewModels
{
    public class AppareilPiecesViewModel : BaseViewModel
    {
        private Appareil _appareil;
        private List<AppareilPiece> _allAssociations;

        public ObservableCollection<AppareilPiece> AppareilPieces { get; set; }
        public ICommand LoadAssociationsCommand { get; }

        private string _searchText;
        public string SearchText
        {
            get => _searchText;
            set
            {
                if (SetProperty(ref _searchText, value))
                {
                    ApplyFilterAndSort();
                }
            }
        }

        private bool _isAscending = true;
        public bool IsAscending
        {
            get => _isAscending;
            set
            {
                if (SetProperty(ref _isAscending, value))
                {
                    ApplyFilterAndSort();
                }
            }
        }

        public AppareilPiecesViewModel(Appareil appareil)
        {
            _appareil = appareil;
            AppareilPieces = new ObservableCollection<AppareilPiece>();
            _allAssociations = new List<AppareilPiece>();
            LoadAssociationsCommand = new AsyncCommand(LoadAssociations);
        }

        private async Task LoadAssociations()
        {
            _allAssociations = await Database.GetAppareilPiecesForAppareilAsync(_appareil.Id);
            ApplyFilterAndSort();
        }

        private void ApplyFilterAndSort()
        {
            IEnumerable<AppareilPiece> filtered = _allAssociations;

            // Filtrage par SearchText sur le nom de la pièce, en supprimant les diacritiques et en convertissant en minuscules.
            if (!string.IsNullOrWhiteSpace(SearchText))
            {
                string searchNormalized = RemoveDiacritics(SearchText).ToLowerInvariant();
                filtered = filtered.Where(a =>
                    !string.IsNullOrEmpty(a.NomPiece) &&
                    RemoveDiacritics(a.NomPiece).ToLowerInvariant().Contains(searchNormalized)
                );
            }

            // Séparation des associations recommandées et non recommandées
            var recommended = filtered.Where(a => a.EstRecommandee);
            var nonRecommended = filtered.Where(a => !a.EstRecommandee);

            // Tri dans chaque groupe par ordre numérique (PieceId) puis alphabétique (NomPiece)
            if (IsAscending)
            {
                recommended = recommended.OrderBy(a => a.PieceId).ThenBy(a => a.NomPiece);
                nonRecommended = nonRecommended.OrderBy(a => a.PieceId).ThenBy(a => a.NomPiece);
            }
            else
            {
                recommended = recommended.OrderByDescending(a => a.PieceId).ThenByDescending(a => a.NomPiece);
                nonRecommended = nonRecommended.OrderByDescending(a => a.PieceId).ThenByDescending(a => a.NomPiece);
            }

            // Les associations recommandées apparaissent en premier.
            var sorted = recommended.Concat(nonRecommended);

            AppareilPieces.Clear();
            foreach (var assoc in sorted)
            {
                AppareilPieces.Add(assoc);
            }
        }

        // Méthode pour supprimer les diacritiques (accents, cédilles, etc.)
        private string RemoveDiacritics(string text)
        {
            if (string.IsNullOrWhiteSpace(text))
                return text;

            var normalizedString = text.Normalize(NormalizationForm.FormD);
            var stringBuilder = new StringBuilder();

            foreach (var c in normalizedString)
            {
                if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                    stringBuilder.Append(c);
            }
            return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
        }
    }
}