using AsbCloudApp.Services;
using AsbCloudDb.Model;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace AsbCloudInfrastructure.Repository;

public class UserSettingsRepository : IUserSettingsRepository
{
    private readonly IAsbCloudDbContext context;

    public UserSettingsRepository(IAsbCloudDbContext context)
    {
        this.context = context;
    }

    public Task<System.Text.Json.JsonDocument?> GetOrDefaultAsync(int userId, string key, CancellationToken token)
        => context.Set<UserSetting>()
            .Where(s => s.IdUser == userId && s.Key == key)
            .Select(s => s.Value)
            .FirstOrDefaultAsync(token);

    public async Task<int> UpsertAsync(int userId, string key, System.Text.Json.JsonDocument value, CancellationToken token)
    {
        var set = context.Set<UserSetting>();
        var updatingItem = await set
            .FirstOrDefaultAsync(s => s.IdUser == userId && s.Key == key, token);

        if (updatingItem is null)
        {
            var settings = new UserSetting
            {
                IdUser = userId,
                Key = key,
                Value = value,
            };
            set.Add(settings);
        }
        else
        {
            updatingItem.Value = value;
            set.Update(updatingItem);
        }

        return await context.SaveChangesAsync(token);
    }
    
    public async Task<int> DeleteAsync(int userId, string key, CancellationToken token)
    {
        var set = context.Set<UserSetting>();
        var removingItem = await set
            .FirstOrDefaultAsync(s => s.IdUser == userId && s.Key == key, token);

        if (removingItem is null)
            return IUserSettingsRepository.ErrorKeyNotFound;

        set.Remove(removingItem);
        return await context.SaveChangesAsync(token);
    }
    
    public async Task<int> DeleteAsync(int userId, CancellationToken token)
    {
        var set = context.Set<UserSetting>();
        var removingItems = set
            .Where(s => s.IdUser == userId);

        set.RemoveRange(removingItems);
        return await context.SaveChangesAsync(token);
    }
}