using System.Text.Json;
using System.Text.Json.Serialization;
using ClaudeDo.Data;
namespace ClaudeDo.Ui;
public sealed class AppSettings
{
public string DbPath { get; set; } = "~/.claudeDo/todo.db";
public string SignalRUrl { get; set; } = "http://127.0.0.1:47821/hub";
public string Language { get; set; } = "";
public string AccentPreset { get; set; } = "";
/// Diff viewer layout: "unified" or "split". A view preference, so it lives here in
/// ui.config.json rather than in the worker-owned AppSettingsEntity.
public string DiffViewMode { get; set; } = "unified";
public bool DiffWrapLines { get; set; }
/// Mission Control overview column count; 0 = auto (derived from the pane count).
public int MissionControlColumns { get; set; }
private static readonly string DefaultConfigPath = Paths.Expand("~/.claudeDo/ui.config.json");
/// Where this instance persists. Instance-level (not static) so tests can redirect it —
/// the diff-viewer toggles call Save() on every flip.
[JsonIgnore]
public string ConfigPath { get; set; } = DefaultConfigPath;
public static AppSettings Load(string? configPath = null)
{
var path = configPath ?? DefaultConfigPath;
try
{
if (File.Exists(path))
{
var json = File.ReadAllText(path);
var loaded = JsonSerializer.Deserialize(json,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
if (loaded is not null)
{
loaded.ConfigPath = path;
return loaded;
}
}
}
catch
{
// Fall through to defaults
}
return new AppSettings { ConfigPath = path };
}
public void Save()
{
var dir = Path.GetDirectoryName(ConfigPath);
if (!string.IsNullOrEmpty(dir)) Directory.CreateDirectory(dir);
var json = JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(ConfigPath, json);
}
}