using System; using System.ComponentModel; using System.Linq; using System.Windows.Forms; using PolyTrader.Core.Persistence; using PolyTraderSharp.Models; using PolyTraderSharp.Services; namespace PolyTraderSharp.Ui.Views { /// /// Core-Settings-Fenster: allgemeine Server-Einstellungen (PropertyGrid) und die /// allgemeine Verwaltung der Polymarket-Accounts (Wallets, API-Keys …). /// Die copytrading-spezifischen Detail-Limits werden NICHT hier, sondern im /// Copytrading-Modul-View bearbeitet (AccountState ist bewusst general-only). /// public partial class SettingsView : Form { private const string SettingsPath = "server_settings.xml"; private ServerSettings _settings = new(); private ThreemaService? _threema; private MullvadVpnService? _vpn; private TerminalLogger? _logger; private IAccountRepository? _accountRepo; private TradingState? _state; private BindingList _accounts = new(); public SettingsView() { InitializeComponent(); btn_save.Click += (_, _) => Save(); btn_loadsettings.Click += (_, _) => Reload(); btnAccNew.Click += (_, _) => AddAccount(); btnAccDelete.Click += (_, _) => DeleteAccount(); dgvAccounts.SelectionChanged += (_, _) => { pgAccount.SelectedObject = dgvAccounts.CurrentRow?.DataBoundItem as AccountState; }; pgAccount.PropertyValueChanged += (_, _) => { if (pgAccount.SelectedObject is AccountState acc) SaveAccount(acc); }; } public void Initialize(ThreemaService threema, MullvadVpnService vpn, TerminalLogger logger, IAccountRepository accountRepo, TradingState state) { _threema = threema; _vpn = vpn; _logger = logger; _accountRepo = accountRepo; _state = state; Reload(); LoadAccounts(); } // ===== Server-Settings ===== private void Reload() { _settings = ServerSettings.Load(SettingsPath); propertyGrid.SelectedObject = _settings; } private void Save() { try { _settings.Save(SettingsPath); _threema?.ReloadSettings(); _vpn?.ReloadSettings(); _logger?.Info("Server-Einstellungen gespeichert und Services neu geladen."); MessageBox.Show("Server-Einstellungen gespeichert.", "Erfolg", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show($"Fehler beim Speichern: {ex.Message}", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error); } } // ===== Polymarket Accounts (allgemeine Einstellungen) ===== private void LoadAccounts() { if (_state == null) return; _accounts = new BindingList(_state.Accounts.Values.OrderBy(a => a.AccountId).ToList()); dgvAccounts.DataSource = _accounts; pgAccount.SelectedObject = dgvAccounts.CurrentRow?.DataBoundItem as AccountState; } private void AddAccount() { if (_state == null || _accountRepo == null) return; int newId = _state.Accounts.Count > 0 ? _state.Accounts.Keys.Max() + 1 : 1; var acc = new AccountState { AccountId = newId, Name = "Neuer Account" }; _state.Accounts[acc.AccountId] = acc; _accountRepo.Upsert(acc); _accounts.Add(acc); dgvAccounts.CurrentCell = dgvAccounts.Rows[dgvAccounts.Rows.Count - 1].Cells[0]; } private void DeleteAccount() { if (_state == null || _accountRepo == null) return; if (dgvAccounts.CurrentRow?.DataBoundItem is not AccountState acc) return; if (MessageBox.Show($"Account '{acc.Name}' (ID {acc.AccountId}) wirklich löschen?", "Löschen bestätigen", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes) return; _state.Accounts.TryRemove(acc.AccountId, out _); _accountRepo.Delete(acc.AccountId); _accounts.Remove(acc); } private void SaveAccount(AccountState acc) { _accountRepo?.Upsert(acc); _state?.Accounts.AddOrUpdate(acc.AccountId, acc, (_, _) => acc); dgvAccounts.Refresh(); } } }