using Lactose.Context;
using Lactose.Models;
using System.Data;

namespace Lactose.Repositories;

public class AssetRepository(LactoseDbContext context) : IAssetRepository {
    
    public Asset? Find(Guid id) => context.Assets.Find(id);

    public IEnumerable<Asset> FindByDateRange(DateTime from, DateTime to) => 
        context.Assets.Where(x => x.CreatedAt >= from && x.UpdatedAt <= to);

    public IEnumerable<Asset> FindByDateRange(DateTime from, DateTime to, int pageNumber, int pageSize) => 
        context.Assets.Where(x => x.CreatedAt >= from && x.UpdatedAt <= to)
            .Skip((pageNumber - 1) * pageSize)
            .Take(pageSize);
    
    public void Save() => context.SaveChanges();

    public void Insert(Asset asset) {
        if(!context.Assets.Any(x => x.OriginalPath == asset.OriginalPath))
            context.Assets.Add(asset);
        else
            throw new DuplicateNameException("The required asset already exists in the database.");
    }

    public void Update(Asset asset) {
        asset.UpdatedAt = DateTime.Now;
        context.Assets.Update(asset);
    }

    public void UpdateBulk(IEnumerable<Asset> assets) {
        foreach (var asset in assets) {
            asset.UpdatedAt = DateTime.Now;
            context.Assets.Update(asset);
        }
    }

    public IEnumerable<Asset> FindByOwner(Guid ownerId) => context.Assets.Where(a => a.Owner!.Id == ownerId);

    public IEnumerable<Asset> FindBulk(IEnumerable<Guid> ids) => context.Assets.Where(a => ids.Contains(a.Id));
    
    public Asset? FindByPath(string path) => context.Assets.FirstOrDefault(a => a.OriginalPath == path);
    
    public void Dispose() => context.Dispose();
}