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;
});
}
}
}