using Microsoft.EntityFrameworkCore;
using Modules.Library.Database.Database;
using Modules.Library.Database.Database.Models.Genre;
using System.Linq;
using System.Linq.Expressions;

namespace Modules.Library.Database.Repositories;

//public class GenreRepository(LibraryDbContext context) : RepositoryBase<Genre>(context)
public class GenreRepository(LibraryDbContext context)
{
    protected readonly LibraryDbContext _context = context;

    internal async Task<Genre> FirstWhereAsync(Expression<Func<Genre, bool>> predicate) =>
        await _context.Genres.FirstAsync(predicate);
    internal async Task<Genre?> FirstOrDefaultWhereAsync(Expression<Func<Genre, bool>> predicate) =>
        await _context.Genres.FirstOrDefaultAsync(predicate);

    internal async Task<Guid> AddAsync(Genre genre)
    {
        if (await AnyWhere(q => q.Name.ToLower() == genre.Name.Trim().ToLower())) throw new Exception("Genre is already exists");
        _context.Genres.Add(genre);
        await _context.SaveChangesAsync();
        return genre.Id;
    }

    internal async Task<IEnumerable<Genre>> GetAllAsync() => await _context.Genres.ToListAsync();

    internal async Task<bool> AnyWhere(Expression<Func<Genre, bool>> predicate) =>
        await _context.Genres.AnyAsync(predicate);

    internal async Task<List<Genre>> GetWhere(Expression<Func<Genre, bool>> predicate) =>
        await _context.Genres.Where(predicate).ToListAsync();

    internal async Task<bool> DeleteAsync(Guid genreId)
    {
        var genre = await FirstOrDefaultWhereAsync(q => q.Id == genreId && !q.Deleted);
        if (genre == null) return false;
        genre.Deleted = true;
        await _context.SaveChangesAsync();
        return true;
    }

    internal async Task UpdateAsync() => await _context.SaveChangesAsync();
}