using System; using System.Reflection; using System.Windows.Input; using DesktopBot.Models; using DesktopBot.Services; namespace DesktopBot.ViewModels { /// /// ViewModel per la schermata di configurazione credenziali Alpaca e logging /// public class SettingsViewModel : BaseViewModel { private readonly ITradingService _tradingService; private readonly Action _onCredentialsSaved; private readonly Action _onLoggingConfigSaved; private LoggingSettingsViewModel _loggingSettings; private string _apiKey; private string _apiSecret; private bool _isPaper = true; private string _statusMessage; private bool _isConnecting; private bool _isConnected; public string ApiKey { get => _apiKey; set => SetProperty(ref _apiKey, value); } /// /// Il secret non è bindabile direttamente (PasswordBox non supporta binding). /// Viene impostato dal code-behind tramite questa proprietà. /// public string ApiSecret { get => _apiSecret; set => SetProperty(ref _apiSecret, value); } public bool IsPaper { get => _isPaper; set => SetProperty(ref _isPaper, value); } public string StatusMessage { get => _statusMessage; set => SetProperty(ref _statusMessage, value); } public bool IsConnecting { get => _isConnecting; set => SetProperty(ref _isConnecting, value); } public bool IsConnected { get => _isConnected; set => SetProperty(ref _isConnected, value); } /// ViewModel per la configurazione dei log public LoggingSettingsViewModel LoggingSettings { get => _loggingSettings; set => SetProperty(ref _loggingSettings, value); } public ICommand SaveCommand { get; } public ICommand TestConnectionCommand { get; } public ICommand DeleteCredentialsCommand { get; } public ICommand SaveLoggingCommand { get; } public ICommand ResetLoggingCommand { get; } // ── Informazioni applicazione ────────────────────────────────────────── public string AppVersion { get; } = Assembly.GetExecutingAssembly() .GetName().Version?.ToString() ?? "1.0.0.0"; public string BuildDate { get; } = System.IO.File.GetLastWriteTime( Assembly.GetExecutingAssembly().Location) .ToString("dd/MM/yyyy HH:mm"); public string Author { get; } = "Alberto Balbo"; public string Framework { get; } = ".NET Framework 4.8.1"; public string Description { get; } = "Trading Bot automatico per Alpaca Markets API v2. " + "Supporta paper trading e live trading con strategia EMA Crossover + RSI."; public SettingsViewModel(ITradingService tradingService, Action onCredentialsSaved, Action onLoggingConfigSaved = null) { _tradingService = tradingService; _onCredentialsSaved = onCredentialsSaved; _onLoggingConfigSaved = onLoggingConfigSaved; SaveCommand = new RelayCommand( _ => SaveCredentials(), _ => !string.IsNullOrWhiteSpace(ApiKey) && !string.IsNullOrWhiteSpace(ApiSecret) ); TestConnectionCommand = new RelayCommand( async _ => await TestConnectionAsync(), _ => !string.IsNullOrWhiteSpace(ApiKey) && !string.IsNullOrWhiteSpace(ApiSecret) && !IsConnecting ); DeleteCredentialsCommand = new RelayCommand(_ => DeleteCredentials()); SaveLoggingCommand = new RelayCommand(_ => SaveLoggingConfiguration()); ResetLoggingCommand = new RelayCommand(_ => ResetLoggingConfiguration()); // Carica credenziali esistenti (mostra solo la key, non il secret) var saved = CredentialService.LoadCredentials(); if (saved != null) { ApiKey = saved.ApiKey; ApiSecret = saved.ApiSecret; IsPaper = saved.IsPaper; StatusMessage = "✓ Credenziali caricate da configurazione salvata"; IsConnected = true; } else { StatusMessage = "Inserisci le credenziali API di Alpaca"; } // Inizializza logging settings con configurazione di default LoggingSettings = new LoggingSettingsViewModel(new LoggingConfiguration()); } /// /// Imposta la configurazione di logging iniziale dal bot /// public void SetLoggingConfiguration(LoggingConfiguration config) { LoggingSettings = new LoggingSettingsViewModel(config); } /// /// Salva la configurazione di logging /// private void SaveLoggingConfiguration() { var updatedConfig = LoggingSettings.GetUpdatedConfig(); _onLoggingConfigSaved?.Invoke(updatedConfig); StatusMessage = "✓ Configurazione log salvata"; } /// /// Ripristina i limiti di logging ai valori di default /// private void ResetLoggingConfiguration() { LoggingSettings.ResetToDefaults(); StatusMessage = "✓ Limiti log ripristinati ai valori di default"; } /// /// Salva le credenziali cifrate e notifica il ViewModel principale /// private void SaveCredentials() { if (string.IsNullOrWhiteSpace(ApiKey) || string.IsNullOrWhiteSpace(ApiSecret)) { StatusMessage = "⚠ API Key e Secret sono obbligatori"; return; } try { CredentialService.SaveCredentials(ApiKey, ApiSecret, IsPaper); _tradingService.Initialize(ApiKey, ApiSecret, IsPaper); _onCredentialsSaved?.Invoke(ApiKey, ApiSecret, IsPaper); StatusMessage = "✓ Credenziali salvate e connessione configurata"; IsConnected = true; } catch (Exception ex) { StatusMessage = $"✗ Errore nel salvataggio: {ex.Message}"; } } /// /// Testa la connessione alle API Alpaca con le credenziali inserite /// private async System.Threading.Tasks.Task TestConnectionAsync() { IsConnecting = true; IsConnected = false; StatusMessage = "⟳ Test connessione in corso..."; try { _tradingService.Initialize(ApiKey, ApiSecret, IsPaper); var equity = await _tradingService.GetAvailableEquityAsync(); StatusMessage = $"✓ Connessione riuscita! Equity disponibile: ${equity:N2}"; IsConnected = true; } catch (Exception ex) { StatusMessage = $"✗ Connessione fallita: {ex.Message}"; IsConnected = false; } finally { IsConnecting = false; } } /// /// Elimina le credenziali salvate /// private void DeleteCredentials() { CredentialService.DeleteCredentials(); ApiKey = string.Empty; ApiSecret = string.Empty; IsConnected = false; StatusMessage = "Credenziali eliminate. Inserisci nuove credenziali."; } } }