using System.Text.Json;
using Lumi.Companion.Protocol;

namespace Lumi.Companion.App;

public sealed record CompanionSettings(
    bool AutoStartWithWindows = false,
    bool StartWithObs = true,
    bool AdvancedMode = false,
    string? PrimarySourceUuid = null,
    string? PrimarySourceName = null,
    DateTimeOffset? PathTestPassedAt = null,
    string? PathTestFingerprint = null);

public sealed class CompanionSettingsStore
{
    private readonly string _path;
    private readonly SemaphoreSlim _gate = new(1, 1);

    public CompanionSettingsStore(string path) => _path = path;
    public CompanionSettings Current { get; private set; } = new();
    public event Action<CompanionSettings>? Changed;

    public async Task LoadAsync(CancellationToken cancellationToken = default)
    {
        if (!File.Exists(_path)) return;
        try
        {
            Current = JsonSerializer.Deserialize<CompanionSettings>(await File.ReadAllBytesAsync(_path, cancellationToken), ProtocolV1.JsonOptions) ?? new();
        }
        catch (JsonException)
        {
            Current = new();
        }
        Changed?.Invoke(Current);
    }

    public async Task SaveAsync(CompanionSettings settings, CancellationToken cancellationToken = default)
    {
        await _gate.WaitAsync(cancellationToken);
        try
        {
            Directory.CreateDirectory(Path.GetDirectoryName(_path)!);
            var temporary = $"{_path}.{Environment.ProcessId}.tmp";
            try
            {
                await File.WriteAllBytesAsync(temporary, JsonSerializer.SerializeToUtf8Bytes(settings, ProtocolV1.JsonOptions), cancellationToken);
                File.Move(temporary, _path, true);
            }
            finally { File.Delete(temporary); }
            Current = settings;
        }
        finally { _gate.Release(); }
        Changed?.Invoke(settings);
    }
}
