using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using NexusReader.Application.Abstractions.Persistence;
using NexusReader.Data.Persistence;

namespace NexusReader.Infrastructure.Persistence;

/// <summary>
/// EF Core implementation of <see cref="IUserReadingStateStore"/>.
/// </summary>
internal sealed class UserReadingStateStore : IUserReadingStateStore
{
    private readonly IDbContextFactory<AppDbContext> _dbContextFactory;

    public UserReadingStateStore(IDbContextFactory<AppDbContext> dbContextFactory)
    {
        _dbContextFactory = dbContextFactory;
    }

    /// <inheritdoc />
    public async Task<(Guid? EbookId, string? ChapterId, string? TenantId)> GetActiveReadingStateAsync(string userId, CancellationToken cancellationToken = default)
    {
        await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);

        var userState = await dbContext.Users
            .Where(u => u.Id == userId)
            .Select(u => new
            {
                u.TenantId,
                u.LastReadPageId,
                LastReadBookId = u.Ebooks.OrderByDescending(e => e.LastReadDate).Select(e => (Guid?)e.Id).FirstOrDefault()
            })
            .FirstOrDefaultAsync(cancellationToken);

        if (userState == null)
        {
            return (null, null, null);
        }

        return (userState.LastReadBookId, userState.LastReadPageId, userState.TenantId);
    }

    /// <inheritdoc />
    public async Task<string?> GetChapterContentAsync(string chapterId, CancellationToken cancellationToken = default)
    {
        await using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);

        return await dbContext.KnowledgeUnits
            .Where(ku => ku.Id == chapterId)
            .Select(ku => ku.Content)
            .FirstOrDefaultAsync(cancellationToken);
    }
}
