using Microsoft.AspNetCore.Components; using CredentialManager.Models; using CredentialManager.Services; using Microsoft.JSInterop; using System.Text.Json; namespace Data_Coupler.Pages; public partial class ProfilesManagement : ComponentBase { [Inject] private IDataCouplerProfileService ProfileService { get; set; } = null!; [Inject] private IJSRuntime JSRuntime { get; set; } = null!; [Inject] private ILogger Logger { get; set; } = null!; // State delle liste private List allProfiles = new(); // State dei filtri private string searchTerm = ""; private string selectedSourceType = ""; private string selectedUsageFilter = ""; private string sortOrder = "name"; // State delle modali private bool showDetailsModal = false; private bool showDeleteModal = false; private DataCouplerProfile? selectedProfile = null; private DataCouplerProfile? profileToDelete = null; // State operazioni private bool isLoading = true; private bool isDeleting = false; // Toast notifications private string toastMessage = ""; private string toastType = "info"; // Statistiche private int totalProfiles => allProfiles.Count; private int activeProfiles => allProfiles.Count(p => p.LastUsedAt.HasValue && p.LastUsedAt.Value > DateTime.Now.AddDays(-30)); private int profilesThisWeek => allProfiles.Count(p => p.CreatedAt > DateTime.Now.AddDays(-7)); private int unusedProfiles => allProfiles.Count(p => !p.LastUsedAt.HasValue); protected override async Task OnInitializedAsync() { await LoadProfiles(); } private async Task LoadProfiles() { try { isLoading = true; var profiles = await ProfileService.GetAllProfilesAsync(); allProfiles = profiles.ToList(); } catch (Exception ex) { Logger.LogError(ex, "Errore nel caricamento dei profili"); ShowToast("Errore nel caricamento dei profili: " + ex.Message, "error"); } finally { isLoading = false; StateHasChanged(); } } private async Task RefreshProfiles() { await LoadProfiles(); } // Filtri e ricerca private IEnumerable GetFilteredProfiles() { var filtered = allProfiles.AsEnumerable(); // Filtro per testo if (!string.IsNullOrEmpty(searchTerm)) { filtered = filtered.Where(p => p.Name.Contains(searchTerm, StringComparison.OrdinalIgnoreCase) || (p.Description?.Contains(searchTerm, StringComparison.OrdinalIgnoreCase) ?? false)); } // Filtro per tipo sorgente if (!string.IsNullOrEmpty(selectedSourceType)) { filtered = filtered.Where(p => p.SourceType.Equals(selectedSourceType, StringComparison.OrdinalIgnoreCase)); } // Filtro per utilizzo if (!string.IsNullOrEmpty(selectedUsageFilter)) { filtered = selectedUsageFilter switch { "used" => filtered.Where(p => p.LastUsedAt.HasValue), "unused" => filtered.Where(p => !p.LastUsedAt.HasValue), "recent" => filtered.Where(p => p.LastUsedAt.HasValue && p.LastUsedAt.Value > DateTime.Now.AddDays(-7)), _ => filtered }; } // Ordinamento filtered = sortOrder switch { "created" => filtered.OrderByDescending(p => p.CreatedAt), "lastused" => filtered.OrderByDescending(p => p.LastUsedAt ?? DateTime.MinValue), _ => filtered.OrderBy(p => p.Name) }; return filtered; } private void FilterProfiles() { StateHasChanged(); } private void ClearSearch() { searchTerm = ""; FilterProfiles(); } // Operazioni sui profili private void ShowDetails(DataCouplerProfile profile) { selectedProfile = profile; showDetailsModal = true; StateHasChanged(); } private void CloseDetailsModal() { showDetailsModal = false; selectedProfile = null; StateHasChanged(); } private void ConfirmDelete(DataCouplerProfile profile) { profileToDelete = profile; showDeleteModal = true; StateHasChanged(); } private void CancelDelete() { showDeleteModal = false; profileToDelete = null; StateHasChanged(); } private async Task DeleteProfile() { if (profileToDelete == null) return; try { isDeleting = true; StateHasChanged(); await ProfileService.DeleteProfileAsync(profileToDelete.Id); allProfiles.Remove(profileToDelete); ShowToast("Profilo eliminato con successo", "success"); CancelDelete(); } catch (Exception ex) { Logger.LogError(ex, "Errore nell'eliminazione del profilo {ProfileId}", profileToDelete.Id); ShowToast("Errore nell'eliminazione: " + ex.Message, "error"); } finally { isDeleting = false; StateHasChanged(); } } private async Task ExportProfiles() { try { var profilesToExport = GetFilteredProfiles().ToList(); var json = JsonSerializer.Serialize(profilesToExport, new JsonSerializerOptions { WriteIndented = true }); var fileName = $"profiles_export_{DateTime.Now:yyyyMMdd_HHmmss}.json"; var bytes = System.Text.Encoding.UTF8.GetBytes(json); var stream = new MemoryStream(bytes); using var streamRef = new DotNetStreamReference(stream); await JSRuntime.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef); ShowToast("Esportazione completata", "success"); } catch (Exception ex) { Logger.LogError(ex, "Errore nell'esportazione dei profili"); ShowToast("Errore nell'esportazione: " + ex.Message, "error"); } } // Helper methods per la UI private string GetSourceTypeBadgeClass(string sourceType) { return sourceType?.ToLower() switch { "database" => "primary", "file" => "success", "rest" => "info", _ => "secondary" }; } private string GetSourceTypeDisplayName(string sourceType) { return sourceType?.ToLower() switch { "database" => "Database", "file" => "File", "rest" => "REST API", _ => "Sconosciuto" }; } private int GetMappingCount(DataCouplerProfile profile) { if (string.IsNullOrEmpty(profile.FieldMappingJson)) return 0; try { var mappings = JsonSerializer.Deserialize>(profile.FieldMappingJson); return mappings?.Count ?? 0; } catch { return 0; } } private List GetProfileMappings(DataCouplerProfile profile) { if (string.IsNullOrEmpty(profile.FieldMappingJson)) return new List(); try { return JsonSerializer.Deserialize>(profile.FieldMappingJson) ?? new List(); } catch { return new List(); } } // Toast notifications private void ShowToast(string message, string type = "info") { toastMessage = message; toastType = type; StateHasChanged(); // Auto-hide dopo 5 secondi _ = Task.Delay(5000).ContinueWith(_ => ClearToast()); } private void ClearToast() { toastMessage = ""; toastType = "info"; InvokeAsync(StateHasChanged); } }