using System.ComponentModel; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Windows.Input; using CORP_MAUI.Models; using CORP_MAUI.Pages; using CORP_MAUI.Services; namespace CORP_MAUI.ViewModels; public class ProfileViewModel : INotifyPropertyChanged { private User? _user; private bool _isLoading; public ProfileViewModel() { LoadProfileCommand = new Command(async () => await LoadProfileAsync()); LogoutCommand = new Command(async () => await LogoutAsync()); } public User? User { get => _user; set { _user = value; OnPropertyChanged(); OnPropertyChanged(nameof(FullName)); OnPropertyChanged(nameof(Username)); OnPropertyChanged(nameof(Email)); OnPropertyChanged(nameof(Phone)); OnPropertyChanged(nameof(HasPhone)); OnPropertyChanged(nameof(Position)); OnPropertyChanged(nameof(Department)); OnPropertyChanged(nameof(Departments)); OnPropertyChanged(nameof(HasDepartments)); OnPropertyChanged(nameof(StatusText)); OnPropertyChanged(nameof(StatusColor)); OnPropertyChanged(nameof(Skills)); OnPropertyChanged(nameof(HasSkills)); OnPropertyChanged(nameof(DisplayImageSource)); // Обновляем изображение при изменении пользователя } } public bool IsLoading { get => _isLoading; set { _isLoading = value; OnPropertyChanged(); } } // Wrappers for UI binding public string FullName => _user?.FullName ?? "Загрузка..."; public string Username => _user != null ? $"@{_user.Username}" : ""; public string Email => _user?.Email ?? "-"; public string Phone => _user?.PhoneNumber ?? "-"; public bool HasPhone => !string.IsNullOrEmpty(_user?.PhoneNumber); public string Position => _user?.PositionName ?? "-"; public string Department => _user?.DepartmentName ?? "-"; public List? Departments => _user?.Departments; public bool HasDepartments => _user?.Departments != null && _user.Departments.Any(); public bool IsOnline => _user?.IsOnline ?? false; public string StatusText => IsOnline ? "В сети" : "Не в сети"; public Color StatusColor => IsOnline ? Colors.LimeGreen : Colors.Gray; public List Skills => _user?.Skills ?? new List(); public bool HasSkills => Skills.Any(); // Image Logic public ImageSource? DisplayImageSource { get { // Используем DisplayAvatarSource из модели User (работает с файловым кэшем) if (_user != null) { return _user.DisplayAvatarSource; } // Default placeholder return ImageSource.FromFile("dotnet_bot.png"); } } public ICommand LoadProfileCommand { get; } public ICommand LogoutCommand { get; } public async Task LoadProfileAsync() { if (IsLoading) return; IsLoading = true; try { Trace.WriteLine("[ProfileViewModel] >>> Начало загрузки профиля"); User? loadedUser = await ServiceProvider.ApiService.GetCurrentUserAsync(); if (loadedUser != null) { Trace.WriteLine($"[ProfileViewModel] ✅ Пользователь загружен: {loadedUser.FullName}"); User = loadedUser; try { Trace.WriteLine("[ProfileViewModel] >>> Загрузка аватара"); await LoadAvatarAsync(); Trace.WriteLine("[ProfileViewModel] ✅ Аватар загружен успешно"); } catch (Exception avatarEx) { Trace.WriteLine($"[ProfileViewModel] ⚠️ Ошибка загрузки аватара (не критично): {avatarEx.Message}"); // Ошибка загрузки аватара не критична - продолжаем работу } } else { Trace.WriteLine("[ProfileViewModel] ❌ loadedUser == null"); Page? mainPage = Application.Current?.Windows.FirstOrDefault()?.Page; if (mainPage != null) await mainPage.DisplayAlert("Ошибка", "Не удалось загрузить профиль", "OK"); } } catch (Exception ex) { Trace.WriteLine($"[ProfileViewModel] ❌ Исключение при загрузке профиля:"); Trace.WriteLine($" Type: {ex.GetType().Name}"); Trace.WriteLine($" Message: {ex.Message}"); Trace.WriteLine($" StackTrace: {ex.StackTrace}"); Page? mainPage = Application.Current?.Windows.FirstOrDefault()?.Page; if (mainPage != null) await mainPage.DisplayAlert("Ошибка", $"Не удалось загрузить профиль: {ex.Message}", "OK"); } finally { IsLoading = false; Trace.WriteLine("[ProfileViewModel] <<< Завершение загрузки профиля"); } } private async Task LoadAvatarAsync() { if (_user == null) { Trace.WriteLine("[ProfileViewModel] Нет пользователя для загрузки аватара"); return; } try { Trace.WriteLine($"[ProfileViewModel] >>> Загрузка аватара для {_user.FullName}, URL: {_user.DisplayAvatarUrl}"); // Используем централизованный метод загрузки аватара await ServiceProvider.ApiService.LoadUserAvatarAsync(_user); Trace.WriteLine($"[ProfileViewModel] IsAvatarLoaded: {_user.IsAvatarLoaded}, CachedPath: {_user.CachedAvatarFilePath}"); // Обновляем UI на главном потоке await MainThread.InvokeOnMainThreadAsync(() => { OnPropertyChanged(nameof(DisplayImageSource)); }); Trace.WriteLine("[ProfileViewModel] ✅ Аватар загружен и UI обновлен"); } catch (Exception ex) { Trace.WriteLine($"[ProfileViewModel] ❌ Ошибка загрузки аватара: {ex.Message}"); // Ошибка загрузки аватара не критична } } private async Task LogoutAsync() { Page? mainPage = Application.Current?.Windows.FirstOrDefault()?.Page; if (mainPage == null) return; bool result = await mainPage.DisplayAlert("Выход", "Вы уверены, что хотите выйти?", "Да", "Нет"); if (result) { try { await ServiceProvider.ApiService.UpdateStatusAsync(false); await ServiceProvider.WebSocketService.DisconnectAsync(); ServiceProvider.ApiService.Logout(); SecureStorage.Remove("user_id"); SecureStorage.Remove("username"); if (Application.Current?.Windows.Count > 0) { Application.Current.Windows[0].Page = new NavigationPage(new LoginPage()); } } catch(Exception ex) { await mainPage.DisplayAlert("Ошибка", $"Ошибка при выходе: {ex.Message}", "OK"); } } } public event PropertyChangedEventHandler? PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string? name = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); }