using System.Threading.Tasks; using System.Windows; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using HC_APTBS.Services; namespace HC_APTBS.ViewModels.Dialogs { /// /// ViewModel for the WKlineErrors dialog. /// /// /// Displays the raw DTC (Diagnostic Trouble Code) text returned by the VP44 ECU /// over K-Line and provides commands to read or clear fault codes. /// /// public sealed partial class KlineErrorsViewModel : ObservableObject { // ── Services ────────────────────────────────────────────────────────────── private readonly IKwpService _kwp; private readonly IConfigurationService _config; private readonly ILocalizationService _loc; // ── Constructor ─────────────────────────────────────────────────────────── /// Initialises the ViewModel and shows the initially known error text. public KlineErrorsViewModel( IKwpService kwpService, IConfigurationService configService, ILocalizationService loc, string initialErrors = "") { _kwp = kwpService; _config = configService; _loc = loc; ErrorText = initialErrors; _kwp.ProgressChanged += OnProgress; } // ── Properties ──────────────────────────────────────────────────────────── /// Raw DTC string returned by the ECU, shown in the text box. [ObservableProperty] private string _errorText = string.Empty; /// True while a K-Line read or clear operation is in progress. [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(ReadErrorsCommand))] [NotifyCanExecuteChangedFor(nameof(ClearErrorsCommand))] private bool _isBusy; /// Progress percentage (0–100) for the current K-Line operation. [ObservableProperty] private int _progressPercent; /// Verbose status message for the current K-Line operation. [ObservableProperty] private string _progressMessage = string.Empty; // ── Commands ────────────────────────────────────────────────────────────── /// Reads the current fault codes from the ECU. [RelayCommand(CanExecute = nameof(CanOperate))] private async Task ReadErrorsAsync() { string? port = GetPort(); if (port == null) return; IsBusy = true; try { ErrorText = await _kwp.ReadFaultCodesAsync(port); } finally { IsBusy = false; ProgressPercent = 0; ProgressMessage = string.Empty; } } /// Clears fault codes on the ECU, then reads back the updated list. [RelayCommand(CanExecute = nameof(CanOperate))] private async Task ClearErrorsAsync() { string? port = GetPort(); if (port == null) return; IsBusy = true; try { ErrorText = await _kwp.ClearFaultCodesAsync(port); // Re-read after clearing to confirm ErrorText = await _kwp.ReadFaultCodesAsync(port); } finally { IsBusy = false; ProgressPercent = 0; ProgressMessage = string.Empty; } } /// Closes the dialog. [RelayCommand] private void Close() { _kwp.ProgressChanged -= OnProgress; RequestClose?.Invoke(); } // ── Events ──────────────────────────────────────────────────────────────── /// Raised when the dialog should close itself. public event System.Action? RequestClose; // ── Helpers ─────────────────────────────────────────────────────────────── private bool CanOperate() => !IsBusy; private string? GetPort() { string? port = _kwp.DetectKLinePort(); if (!string.IsNullOrEmpty(port)) return port; MessageBox.Show( _loc.GetString("Error.KLineNotFound"), _loc.GetString("Error.KLineTitle"), MessageBoxButton.OK, MessageBoxImage.Warning); return null; } private void OnProgress(int pct, string msg) { Application.Current.Dispatcher.Invoke(() => { ProgressPercent = pct; ProgressMessage = msg; }); } } }