using System.Text.Json;
using ClawdDotNet.App.Models;

namespace ClawdDotNet.App.Services;

/// <summary>
/// Thread-safe JSON persistence for job execution history.
/// Uses file locking to handle concurrent access from multiple schedulers.
/// </summary>
public sealed class JobHistoryService
{
    private readonly string _filePath;
    private readonly Lock _lock = new();
    private readonly int _maxEntries;
    private List<JobHistoryEntry> _entries = new();

    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        WriteIndented = true
    };

    public JobHistoryService(string instancePath, int maxEntries = 500)
    {
        _filePath = Path.Combine(instancePath, "job_history.json");
        _maxEntries = maxEntries;
        Load();
    }

    /// <summary>
    /// Adds a new entry to the history (thread-safe, persists immediately).
    /// </summary>
    public void Add(JobHistoryEntry entry)
    {
        lock (_lock)
        {
            _entries.Insert(0, entry); // newest first

            // Trim old entries
            if (_entries.Count > _maxEntries)
                _entries = _entries.Take(_maxEntries).ToList();

            Save();
        }
    }

    /// <summary>
    /// Returns a snapshot of all entries (newest first).
    /// </summary>
    public List<JobHistoryEntry> GetAll()
    {
        lock (_lock)
            return new List<JobHistoryEntry>(_entries);
    }

    private void Load()
    {
        lock (_lock)
        {
            try
            {
                if (!File.Exists(_filePath))
                {
                    _entries = new List<JobHistoryEntry>();
                    return;
                }

                using var stream = new FileStream(_filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                _entries = JsonSerializer.Deserialize<List<JobHistoryEntry>>(stream, JsonOptions)
                    ?? new List<JobHistoryEntry>();
            }
            catch
            {
                _entries = new List<JobHistoryEntry>();
            }
        }
    }

    private void Save()
    {
        try
        {
            var tmpPath = _filePath + ".tmp";
            using (var stream = new FileStream(tmpPath, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                JsonSerializer.Serialize(stream, _entries, JsonOptions);
            }

            File.Move(tmpPath, _filePath, overwrite: true);
        }
        catch
        {
            // Silently ignore write failures — next save will retry
        }
    }
}
