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.";
}
}
}