using LensUp.Common.Types.BlobStorage.Constants;
using LensUp.Common.Types.BlobStorage.Exceptions;
using LensUp.PhotoCollectorService.API.DataAccess.ActiveGallery;
using LensUp.PhotoCollectorService.API.Exceptions;

namespace LensUp.PhotoCollectorService.API.Validators;

public interface IUploadPhotoToGalleryRequestValidator
{
    void EnsureThatAuthorNameIsValid(string authorName);
    void EnsureThatWishesTextIsValid(string wishesText);
    string EnsureThatPhotoFileIsValid(IFormFile photoFile);
    Task<string> EnsureThatGalleryIsActivated(int enterCode, CancellationToken cancellationToken);
}

public sealed class UploadPhotoToGalleryRequestValidator : IUploadPhotoToGalleryRequestValidator
{
    private readonly IActiveGalleryRepository activeGalleryRepository;
    public UploadPhotoToGalleryRequestValidator(IActiveGalleryRepository activeGalleryRepository)
    {
        this.activeGalleryRepository = activeGalleryRepository;
    }

    public string EnsureThatPhotoFileIsValid(IFormFile photoFile)
    {
        if (photoFile == null || photoFile.Length == 0)
        {
            throw new PhotoFileIsEmptyException();
        }

        var extension = Path.GetExtension(photoFile.FileName).ToLower();
        if (!PhotoFileExtensions.AllowedToUpload.Contains(extension))
        {
            throw new PhotoExtensionIsNotAllowedException(extension);
        }

        return extension;
    }

    public async Task<string> EnsureThatGalleryIsActivated(int enterCode, CancellationToken cancellationToken)
    {
        var activeGalleryEntity = await this.activeGalleryRepository.GetAsync(enterCode.ToString(), cancellationToken);

        if (activeGalleryEntity == null) 
        {
            throw new ActiveGalleryNotFoundException(enterCode);
        }

        bool isExpired = activeGalleryEntity.EndDate < DateTimeOffset.UtcNow;
        if (isExpired)
        {
            throw new ActiveGalleryIsExpiredException(activeGalleryEntity.GalleryId);
        }

        return activeGalleryEntity.GalleryId;
    }

    public void EnsureThatAuthorNameIsValid(string authorName)
    {
        if (string.IsNullOrWhiteSpace(authorName))
        {
            throw new ArgumentException(nameof(authorName));
        }
    }

    public void EnsureThatWishesTextIsValid(string wishesText)
    {
        if (string.IsNullOrWhiteSpace(wishesText))
        {
            throw new ArgumentException(nameof(wishesText));
        }
    }
}
