using DomainResults.Common;

using DataProviders;
using DataProviders.Buckets;
using DataProviders.Collections;

using ImageProvider;
using ImageProvider.Fonts;
using Core.Abstractions;
using WeatherForecast.Models.Responses;
using WeatherForecast.Models.File.Responses;

namespace WeatherForecast.Services {

  /// <summary>
  /// 
  /// </summary>
  public interface IImageService {
    /// <summary>
    /// 
    /// </summary>
    /// <param name="siteId"></param>
    /// <param name="width"></param>
    /// <param name="height"></param>
    /// <param name="imageId"></param>
    /// <returns></returns>
    (FileResponseModel?, IDomainResult) Get(Guid siteId, int width, int height, Guid imageId);
  }

  /// <summary>
  /// 
  /// </summary>
  public class ImageService : ServiceBase<ImageService>, IImageService {

    private readonly IImageBucketDataProvider _imageBucketDataProvider;
    private readonly IImageProvider _imageProvider;
    private readonly IContentDataProvider _contentDataProvider;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="logger"></param>
    /// <param name="imageBucketDataProvider"></param>
    /// <param name="imageProvider"></param>
    public ImageService(
      ILogger<ImageService> logger,
      IImageBucketDataProvider imageBucketDataProvider,
      IImageProvider imageProvider,
      IContentDataProvider contentDataProvider
    ) : base(logger) {
      _imageBucketDataProvider = imageBucketDataProvider;
      _imageProvider = imageProvider;
      _contentDataProvider = contentDataProvider;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="siteId"></param>
    /// <param name="width"></param>
    /// <param name="height"></param>
    /// <param name="imageId"></param>
    /// <returns></returns>
    public (FileResponseModel?, IDomainResult) Get(Guid siteId, int width, int height, Guid imageId) {
      try {
        var (file, downloadResult) = _imageBucketDataProvider.Download(siteId, imageId);
        if (!downloadResult.IsSuccess || file == null)
          return IDomainResult.Failed<FileResponseModel?> ();

        var (content, getContentResult) = _contentDataProvider.Get(siteId);
        if (!getContentResult.IsSuccess || content == null)
          return IDomainResult.Failed<FileResponseModel?>();

        var (image, transformResult) = _imageProvider.ResizeAndWatermark(file.Bytes, width, height, FontsEnum.Montserrat, FontStylesEnum.Regular, content.First().SiteName);
        if (!transformResult.IsSuccess || image == null)
          return IDomainResult.Failed<FileResponseModel?>();

        return IDomainResult.Success(new FileResponseModel {
          Name = file.Name,
          Bytes = image,
          ContentType = "image/jpeg" });
      }
      catch (Exception ex) {
        _logger.LogError(ex, "Unhandled exception");
        return IDomainResult.Failed<FileResponseModel?> (ex.Message);
      }

    }


  }
}
