using FieldLogger.Models; namespace FieldLogger.Services; /// Persisted app settings: paired device identities, active job, map key. public sealed class SettingsService { private const string LocatorIdKey = "device.locator.id"; private const string LocatorNameKey = "device.locator.name"; private const string RtkIdKey = "device.rtk.id"; private const string RtkNameKey = "device.rtk.name"; private const string ActiveJobKey = "job.active.id"; private const string MapsApiKeyKey = "maps.apikey"; private const string MqttEnabledKey = "mqtt.enabled"; private const string MqttHostKey = "mqtt.host"; private const string MqttPortKey = "mqtt.port"; private const string MqttOrgIdKey = "mqtt.org.id"; private const string MqttClientIdKey = "mqtt.client.id"; private const string MqttPasswordKey = "mqtt.password"; public Guid? GetSavedDeviceId(DeviceKind kind) { var raw = Preferences.Default.Get(IdKey(kind), string.Empty); return Guid.TryParse(raw, out var id) ? id : null; } public string? GetSavedDeviceName(DeviceKind kind) { var name = Preferences.Default.Get(NameKey(kind), string.Empty); return string.IsNullOrEmpty(name) ? null : name; } public void SaveDevice(DeviceKind kind, Guid id, string name) { Preferences.Default.Set(IdKey(kind), id.ToString()); Preferences.Default.Set(NameKey(kind), name); } public void ClearDevice(DeviceKind kind) { Preferences.Default.Remove(IdKey(kind)); Preferences.Default.Remove(NameKey(kind)); } public int? ActiveJobId { get { var id = Preferences.Default.Get(ActiveJobKey, 0); return id > 0 ? id : null; } set => Preferences.Default.Set(ActiveJobKey, value ?? 0); } /// Google Maps JavaScript API key used by the Windows WebView map. public string GoogleMapsApiKey { get => Preferences.Default.Get(MapsApiKeyKey, string.Empty); set => Preferences.Default.Set(MapsApiKeyKey, value); } public bool MqttEnabled { get => Preferences.Default.Get(MqttEnabledKey, false); set => Preferences.Default.Set(MqttEnabledKey, value); } public string MqttHost { get => Preferences.Default.Get(MqttHostKey, "dev.hub.umagul.net"); set => Preferences.Default.Set(MqttHostKey, value.Trim()); } public int MqttPort { get => Preferences.Default.Get(MqttPortKey, 8884); set => Preferences.Default.Set(MqttPortKey, value); } /// The interim MQTT username is the organization id. public string MqttOrgId { get => Preferences.Default.Get(MqttOrgIdKey, string.Empty); set => Preferences.Default.Set(MqttOrgIdKey, value.Trim()); } public string MqttClientId { get { var existing = Preferences.Default.Get(MqttClientIdKey, string.Empty); if (!string.IsNullOrWhiteSpace(existing)) return existing; var created = $"fieldlogger-{Guid.NewGuid():N}"; Preferences.Default.Set(MqttClientIdKey, created); return created; } } public Task GetMqttPasswordAsync() => SecureStorage.Default.GetAsync(MqttPasswordKey); public Task SetMqttPasswordAsync(string password) => string.IsNullOrWhiteSpace(password) ? throw new ArgumentException("MQTT password cannot be empty.", nameof(password)) : SecureStorage.Default.SetAsync(MqttPasswordKey, password); public void ClearMqttPassword() => SecureStorage.Default.Remove(MqttPasswordKey); private static string IdKey(DeviceKind kind) => kind == DeviceKind.Locator ? LocatorIdKey : RtkIdKey; private static string NameKey(DeviceKind kind) => kind == DeviceKind.Locator ? LocatorNameKey : RtkNameKey; }