using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using QuantEngine.Core.Interfaces;
using QuantEngine.Core.Models;

namespace QuantEngine.Application.Services
{
    public class WorkspaceService
    {
        private readonly IWorkspaceRepository _repository;
        private readonly IPostgresqlHistoryStore _historyStore;

    public WorkspaceService(IWorkspaceRepository repository, IPostgresqlHistoryStore historyStore)
    {
        _repository = repository;
        _historyStore = historyStore;
    }

    public Task<IEnumerable<Setting>> GetSettingsAsync() => _repository.GetSettingsAsync();
    public Task<Setting?> GetSettingByKeyAsync(string key) => _repository.GetSettingByKeyAsync(RequireValue(key, nameof(key)));
    public Task<bool> UpsertSettingAsync(Setting setting)
    {
        ArgumentNullException.ThrowIfNull(setting);
        return _repository.UpsertSettingAsync(setting);
    }
    public Task<bool> DeleteSettingAsync(string key) => _repository.DeleteSettingAsync(RequireValue(key, nameof(key)));

    public Task<IEnumerable<AccountSnapshot>> GetAccountSnapshotsAsync() => _repository.GetAccountSnapshotsAsync();
    public Task<bool> InsertAccountSnapshotsAsync(IEnumerable<AccountSnapshot> snapshots) => _repository.InsertAccountSnapshotsAsync(snapshots);
    public Task<bool> ClearAccountSnapshotsAsync() => _repository.ClearAccountSnapshotsAsync();

    public Task<int> AppendHistoryAsync(string domain, IDictionary<string, object?> payload)
        => _historyStore.AppendAsync(RequireValue(domain, nameof(domain)), payload);

    public Task<IReadOnlyList<IDictionary<string, object?>>> ReadHistorySnapshotAsync(string domain, int limit = 500)
        => _historyStore.SnapshotAsync(RequireValue(domain, nameof(domain)), Math.Clamp(limit, 1, 2000));

    private static string RequireValue(string value, string parameterName)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new ArgumentException("Value is required.", parameterName);
        }

        return value.Trim();
    }
}
}
