using Microsoft.Extensions.Logging;

using DomainResults.Common;

using MongoDB.Bson.Serialization;
using MongoDB.Driver;

using DataProviders.Abstractions;

using DomainObjects.Documents;

namespace DataProviders.Collections {

  public interface IShopCartDataProvider {
    (Guid?, IDomainResult) Insert(ShopCartDocument obj);
    (List<ShopCartDocument>?, IDomainResult) GetAll(Guid siteId, Guid userId);
    (ShopCartDocument?, IDomainResult) Get(Guid siteId, Guid userId, string sku);
    (Guid?, IDomainResult) Update(ShopCartDocument shopCart);
    IDomainResult Delete(Guid id);
    IDomainResult DeleteAll(Guid siteId, Guid userId);
  }

  public class ShopCartDataProvider : CollectionDataProviderBase<ShopCartDocument>, IShopCartDataProvider {

    private const string _databaseName = "reactredux";
    private const string _collectionName = "shopcart";

    public ShopCartDataProvider(
      ILogger<CollectionDataProviderBase<ShopCartDocument>> logger,
      IMongoClient client,
      IIdGenerator idGenerator,
      ISessionService sessionService) : base(logger, client, idGenerator, sessionService, _databaseName, _collectionName) {
    }

    public (List<ShopCartDocument>?, IDomainResult) GetAll(Guid siteId, Guid userId) =>
      GetWithPredicate(x => x.SiteId == siteId && x.UserId == userId, 0, 0);

    public (ShopCartDocument?, IDomainResult) Get(Guid siteId, Guid userId, string sku) {
      var (list, result) = GetWithPredicate(x => x.SiteId == siteId && x.UserId == userId && x.Sku == sku, 0, 0);

      if (!result.IsSuccess || list == null)
        return (null, result);

      return (list.First(), result);
    }

    public (Guid?, IDomainResult) Update(ShopCartDocument shopCart) =>
      UpdateWithPredicate(shopCart, x => x.Id == shopCart.Id);

    public IDomainResult Delete(Guid id) =>
      DeleteWithPredicate(x => x.Id == id);

    public IDomainResult DeleteAll(Guid siteId, Guid userId) =>
      DeleteManyWithPredicate(x => x.SiteId == siteId && x.UserId == userId);
  }
}
