using System.Linq; using Avalonia.Controls; using Avalonia.Interactivity; using UnifiedFarmLauncher.Models; using UnifiedFarmLauncher.Services; using UnifiedFarmLauncher.ViewModels; using Avalonia.Controls.Primitives; using MsBox.Avalonia; using MsBox.Avalonia.Enums; namespace UnifiedFarmLauncher.Views { public partial class MainWindow : Window { private readonly ConfigService _configService = new(); private readonly SshService _sshService = new(); private readonly WorkerControllerService _controllerService; private readonly AttachService _attachService; public MainWindow() { InitializeComponent(); _controllerService = new WorkerControllerService(_sshService, _configService); _attachService = new AttachService(_sshService, _controllerService); DataContext = new MainWindowViewModel(); SetupEventHandlers(); } private void InitializeComponent() { Avalonia.Markup.Xaml.AvaloniaXamlLoader.Load(this); } private void SetupEventHandlers() { AddWorkerButton.Click += AddWorkerButton_Click; EditWorkerButton.Click += EditWorkerButton_Click; DeleteWorkerButton.Click += DeleteWorkerButton_Click; StartWorkerButton.Click += StartWorkerButton_Click; StopWorkerButton.Click += StopWorkerButton_Click; AttachWorkerButton.Click += AttachWorkerButton_Click; WorkerTypeTabs.SelectionChanged += WorkerTypeTabs_SelectionChanged; WorkersGrid.SelectionChanged += WorkersGrid_SelectionChanged; } private async void AddWorkerButton_Click(object? sender, RoutedEventArgs e) { var dialog = new WorkerEditWindow(); if (await dialog.ShowDialogAsync(this)) { ((MainWindowViewModel)DataContext!).RefreshWorkers(); } } private async void EditWorkerButton_Click(object? sender, RoutedEventArgs e) { if (WorkersGrid.SelectedItem is WorkerConfig worker) { var dialog = new WorkerEditWindow(worker); if (await dialog.ShowDialogAsync(this)) { ((MainWindowViewModel)DataContext!).RefreshWorkers(); } } } private async void DeleteWorkerButton_Click(object? sender, RoutedEventArgs e) { if (WorkersGrid.SelectedItem is WorkerConfig worker) { var box = MessageBoxManager.GetMessageBoxStandard("Delete Worker", $"Are you sure you want to delete worker '{worker.Name}'?", ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Warning); var result = await box.ShowAsync(); if (result == ButtonResult.Yes) { _configService.DeleteWorker(worker.Id); ((MainWindowViewModel)DataContext!).RefreshWorkers(); } } } private async void StartWorkerButton_Click(object? sender, RoutedEventArgs e) { if (WorkersGrid.SelectedItem is WorkerConfig worker) { try { string? workerType = null; if (worker.WorkerTypes.SheepIt != null) workerType = "sheepit"; else if (worker.WorkerTypes.Flamenco != null) workerType = "flamenco"; if (workerType == null) { var box = MessageBoxManager.GetMessageBoxStandard("Error", "Worker has no configured worker type.", ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error); await box.ShowAsync(); return; } await _controllerService.StartWorkerAsync(worker, workerType); var successBox = MessageBoxManager.GetMessageBoxStandard("Start Worker", $"Worker '{worker.Name}' started successfully.", ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Success); await successBox.ShowAsync(); ((MainWindowViewModel)DataContext!).RefreshWorkers(); } catch (System.Exception ex) { var errorBox = MessageBoxManager.GetMessageBoxStandard("Error", $"Failed to start worker: {ex.Message}", ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error); await errorBox.ShowAsync(); } } } private async void StopWorkerButton_Click(object? sender, RoutedEventArgs e) { if (WorkersGrid.SelectedItem is WorkerConfig worker) { try { string? workerType = null; if (worker.WorkerTypes.SheepIt != null) workerType = "sheepit"; else if (worker.WorkerTypes.Flamenco != null) workerType = "flamenco"; if (workerType == null) { var box = MessageBoxManager.GetMessageBoxStandard("Error", "Worker has no configured worker type.", ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error); await box.ShowAsync(); return; } await _controllerService.StopWorkerAsync(worker, workerType); var successBox = MessageBoxManager.GetMessageBoxStandard("Stop Worker", $"Stop command sent to worker '{worker.Name}'.", ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Info); await successBox.ShowAsync(); } catch (System.Exception ex) { var errorBox = MessageBoxManager.GetMessageBoxStandard("Error", $"Failed to stop worker: {ex.Message}", ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error); await errorBox.ShowAsync(); } } } private async void AttachWorkerButton_Click(object? sender, RoutedEventArgs e) { if (WorkersGrid.SelectedItem is WorkerConfig worker) { try { string? workerType = null; if (worker.WorkerTypes.SheepIt != null) workerType = "sheepit"; else if (worker.WorkerTypes.Flamenco != null) workerType = "flamenco"; if (workerType == null) { var box = MessageBoxManager.GetMessageBoxStandard("Error", "Worker has no configured worker type.", ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error); await box.ShowAsync(); return; } await _attachService.AttachToWorkerAsync(worker, workerType); } catch (System.Exception ex) { var errorBox = MessageBoxManager.GetMessageBoxStandard("Error", $"Failed to attach to worker: {ex.Message}", ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error); await errorBox.ShowAsync(); } } } private void WorkerTypeTabs_SelectionChanged(object? sender, SelectionChangedEventArgs e) { if (WorkerTypeTabs.SelectedItem is TabItem tab) { var type = tab.Header?.ToString() ?? "All"; if (type == "All Workers") type = "All"; ((MainWindowViewModel)DataContext!).SelectedWorkerType = type; } } private void WorkersGrid_SelectionChanged(object? sender, SelectionChangedEventArgs e) { if (DataContext is MainWindowViewModel vm) { vm.SelectedWorker = WorkersGrid.SelectedItem as WorkerConfig; } } } }