using DomainResults.Common;

using DataProviders.Collections;

using Core.Abstractions;

using WeatherForecast.Models.Responses;
using WeatherForecast.Models.Shop.Requests;
using DomainObjects.Documents;
using DomainObjects.Enumerations;

namespace WeatherForecast.Services;

/// <summary>
/// 
/// </summary>
public interface IShopCartItemService {

  /// <summary>
  /// 
  /// </summary>
  /// <param name="siteId"></param>
  /// <param name="userId"></param>
  /// <param name="sku"></param>
  /// <param name="requestModel"></param>
  /// <returns></returns>
  (Guid?, IDomainResult) Post(Guid siteId, Guid userId, string sku, ShopCartItemRequestModel requestModel);
    
  /// <summary>
  /// 
  /// </summary>
  /// <param name="siteId"></param>
  /// <param name="userId"></param>
  /// <param name="sku"></param>
  /// <param name="locale"></param>
  /// <returns></returns>
  (ShopCartItemResponseModel?, IDomainResult) Get(ShopCartDocument cartItem, string? locale);
    
  /// <summary>
  /// 
  /// </summary>
  /// <param name="siteId"></param>
  /// <param name="userId"></param>
  /// <param name="sku"></param>
  /// <param name="requestData"></param>
  /// <returns></returns>
  (Guid?, IDomainResult) Update(ShopCartDocument cartItem, ShopCartItemRequestModel requestData);
}

/// <summary>
/// 
/// </summary>
public class ShopCartItemService : ServiceBase<ShopCartItemService>, IShopCartItemService {

  private readonly IShopCatalogDataProvider _shopCatalogDataProvider;
  private readonly IShopCartDataProvider _shopCartDataProvider;

  /// <summary>
  /// 
  /// </summary>
  /// <param name="logger"></param>
  /// <param name="shopCatalogDataProvider"></param>
  /// <param name="shopCartDataprovider"></param>
  public ShopCartItemService(
    ILogger<ShopCartItemService> logger,
    IShopCatalogDataProvider shopCatalogDataProvider,
    IShopCartDataProvider shopCartDataprovider
  ) : base(logger) {
    _shopCatalogDataProvider = shopCatalogDataProvider;
    _shopCartDataProvider = shopCartDataprovider;
  }

  /// <summary>
  /// 
  /// </summary>
  /// <param name="siteId"></param>
  /// <param name="userId"></param>
  /// <param name="sku"></param>
  /// <param name="requestModel"></param>
  /// <returns></returns>
  public (Guid?, IDomainResult) Post(Guid siteId, Guid userId, string sku, ShopCartItemRequestModel requestModel) {

      var (_, getResult) = _shopCartDataProvider.Get(siteId, userId, sku);
      if (getResult.IsSuccess)
        return IDomainResult.Failed<Guid?>();

      var item = requestModel.ToDomainObject();

      item.SiteId = siteId;
      item.UserId = userId;
      item.Sku = sku;

      var (id, insertResult) = _shopCartDataProvider.Insert(item);

      if (!insertResult.IsSuccess)
        return IDomainResult.Failed<Guid?>();

      return IDomainResult.Success(id);

  }

  /// <summary>
  /// 
  /// </summary>
  /// <param name="cartItem"></param>
  /// <param name="locale"></param>
  /// <returns></returns>
  public (ShopCartItemResponseModel?, IDomainResult) Get(ShopCartDocument cartItem, string? locale) {



      var (item, result) = _shopCatalogDataProvider.Get(cartItem.SiteId, cartItem.Sku);
      if (!result.IsSuccess || item == null) {
        var delteResult = _shopCartDataProvider.Delete(cartItem.Id);
        if (!delteResult.IsSuccess)
          return (null, delteResult);

        return IDomainResult.NotFound<ShopCartItemResponseModel?>();
      }
      else
        return IDomainResult.Success(new ShopCartItemResponseModel(item, cartItem, Enumeration.FromDisplayName<Locales>(locale ?? "en-US")));
    
  }

  /// <summary>
  /// 
  /// </summary>
  /// <param name="cartItem"></param>
  /// <param name="requestData"></param>
  /// <returns></returns>
  public (Guid?, IDomainResult) Update(ShopCartDocument cartItem, ShopCartItemRequestModel requestData) {

      // construct domain object from model
      var newItem = requestData.ToDomainObject();
      newItem.Id = cartItem.Id;
      newItem.SiteId = cartItem.SiteId;
      newItem.UserId = cartItem.UserId;
      newItem.Sku = cartItem.Sku;
      newItem.Created = cartItem.Created;

      if (!cartItem.Equals(newItem)) {
        var (id, updateResult) = _shopCartDataProvider.Update(newItem);
        if (!updateResult.IsSuccess || id == null)
          return (null, updateResult);
      }

      return IDomainResult.Success(cartItem.Id);
  }
}
