using System;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using PolyTrader.Modules.CopyTrading.Persistence;
using PolyTraderSharp;
using PolyTraderSharp.Models;
namespace PolyTrader.Modules.CopyTrading.Ui
{
///
/// Verwaltung der Master-Trader (mod_copytrading_traders): Liste, Detail-Editor
/// (PropertyGrid) und Account-Zuweisung (welche Accounts diesen Trader kopieren).
/// Persistiert über das Repo und hält den Hot-Path-State
/// () synchron.
/// Layout im Designer (MasterTradersView.Designer.cs), Daten/Logik hier.
///
public partial class MasterTradersView : Form
{
private ITrackedTraderRepository? _repo;
private TradingState? _state;
private CopyTradingState? _copyState;
private BindingList _binding = new();
private TrackedTrader? _current;
// Parameterloser Konstruktor für den WinForms-Designer.
public MasterTradersView()
{
InitializeComponent();
colWinrate.DefaultCellStyle.Format = "F1";
colPnl.DefaultCellStyle.Format = "F2";
tsNew.Click += (_, _) => AddNew();
tsSave.Click += (_, _) => SaveCurrent();
tsDelete.Click += (_, _) => DeleteCurrent();
tsRefresh.Click += (_, _) => LoadData();
grid.SelectionChanged += (_, _) => OnSelectionChanged();
}
/// Injiziert die Abhängigkeiten (nach der DI-Auflösung) und lädt die Trader.
public void Initialize(ITrackedTraderRepository repo, TradingState state, CopyTradingState copyState)
{
_repo = repo;
_state = state;
_copyState = copyState;
LoadData();
}
private void LoadData()
{
if (_repo == null) return;
var traders = _repo.GetAll().OrderBy(t => t.Id).ToList();
_binding = new BindingList(traders);
grid.DataSource = _binding;
if (traders.Count > 0)
grid.CurrentCell = grid.Rows[0].Cells[0];
else
ClearDetail();
lblHint.Text = $"{traders.Count} Master-Trader geladen.";
}
private void OnSelectionChanged()
{
if (grid.CurrentRow?.DataBoundItem is TrackedTrader t)
BindDetail(t);
}
private void BindDetail(TrackedTrader trader)
{
_current = trader;
pgDetail.SelectedObject = trader;
clbAccounts.Items.Clear();
if (_state == null) return;
foreach (var acc in _state.Accounts.Values.OrderBy(a => a.AccountId))
{
string label = string.IsNullOrEmpty(acc.Name) ? $"#{acc.AccountId}" : $"{acc.Name} (#{acc.AccountId}){(acc.IsDemo ? " · Demo" : "")}";
int idx = clbAccounts.Items.Add(new AccountItem(acc.AccountId, label));
clbAccounts.SetItemChecked(idx, trader.AssignedAccountIds.Contains(acc.AccountId));
}
}
private void ClearDetail()
{
_current = null;
pgDetail.SelectedObject = null;
clbAccounts.Items.Clear();
}
private void AddNew()
{
int nextId = _binding.Count > 0 ? _binding.Max(t => t.Id) + 1 : 1;
var trader = new TrackedTrader { Id = nextId, DisplayName = $"Neuer Trader {nextId}" };
_binding.Add(trader);
grid.CurrentCell = grid.Rows[_binding.Count - 1].Cells[0];
lblHint.Text = $"Neuer Master-Trader #{nextId} – Felder ausfüllen und Speichern.";
}
private void SaveCurrent()
{
if (_current == null || _repo == null || _copyState == null) { lblHint.Text = "Kein Trader ausgewählt."; return; }
_current.AssignedAccountIds = clbAccounts.CheckedItems.Cast().Select(a => a.Id).ToHashSet();
_repo.Upsert(_current);
_copyState.Traders[_current.Id] = _current;
grid.Refresh();
lblHint.Text = $"Gespeichert: #{_current.Id} {_current.DisplayName} ({_current.AssignedAccountIds.Count} Account(s)) um {DateTime.Now:HH:mm:ss}.";
}
private void DeleteCurrent()
{
if (_current == null || _repo == null || _copyState == null) { lblHint.Text = "Kein Trader ausgewählt."; return; }
var id = _current.Id;
if (MessageBox.Show($"Master-Trader #{id} ({_current.DisplayName}) wirklich löschen?",
"Löschen bestätigen", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes)
return;
_repo.Delete(id);
_copyState.Traders.TryRemove(id, out _);
_binding.Remove(_current);
ClearDetail();
lblHint.Text = $"Master-Trader #{id} gelöscht.";
}
private sealed record AccountItem(int Id, string Label)
{
public override string ToString() => Label;
}
}
}