using Microsoft.EntityFrameworkCore;
using NexusReader.Application.Abstractions.Persistence;
using NexusReader.Data.Persistence;
using NexusReader.Domain.Entities;

namespace NexusReader.Infrastructure.Persistence;

/// <summary>
/// EF Core implementation of <see cref="IEbookRepository"/>.
/// Uses a scoped <see cref="AppDbContext"/> created via the factory for long-running operations.
/// </summary>
internal sealed class EbookRepository : IEbookRepository
{
    private readonly AppDbContext _context;

    public EbookRepository(AppDbContext context)
    {
        _context = context;
    }

    /// <inheritdoc />
    public async Task<Author?> FindAuthorByNameAsync(string name, CancellationToken cancellationToken = default)
    {
        // Use PostgreSQL ILike for case-insensitive searching if on Npgsql provider, 
        // otherwise fallback to string comparison.
        if (_context.Database.IsNpgsql())
        {
            return await _context.Authors
                .FirstOrDefaultAsync(a => EF.Functions.ILike(a.Name, name), cancellationToken);
        }

        return await _context.Authors
            .FirstOrDefaultAsync(
                a => a.Name.ToLower() == name.ToLower(),
                cancellationToken);
    }

    /// <inheritdoc />
    public void AddAuthor(Author author) => _context.Authors.Add(author);

    /// <inheritdoc />
    public void AddEbook(Ebook ebook)
    {
        // Explicitly set the readiness flag to false upon addition
        ebook.IsReadyForReading = false;
        _context.Ebooks.Add(ebook);
    }

    /// <inheritdoc />
    public async Task<Ebook?> FindByIdAsync(Guid id, CancellationToken cancellationToken = default)
    {
        return await _context.Ebooks.FindAsync(new object[] { id }, cancellationToken);
    }

    /// <inheritdoc />
    public Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
        => _context.SaveChangesAsync(cancellationToken);
}
