using CSharpFunctionalExtensions;
using Wishlist.Data.Entities;
using Wishlist.Data.Services.Interfaces;

namespace Wishlist.Data.Services;

public class WishlistService : IWishlistService
{
    private readonly AppDataContext _context;
    private readonly ILogger<WishlistService> _logger;

    public WishlistService(AppDataContext context, ILogger<WishlistService> logger)
    {
        _context = context;
        _logger = logger;
    }

    public async Task<Result<Entities.Wishlist>> Create(Entities.Wishlist entity)
    {
        try
        {
            _logger.LogInformation($"Creating Wishlist {entity.Id}");
            entity.Created = DateTime.UtcNow;
            entity.LastModified = entity.Created;
            var createdEntity = await _context.Wishlists.AddAsync(entity);
            await _context.SaveChangesAsync();
            return createdEntity.Entity;
        }
        catch (Exception e)
        {
            _logger.LogError("An error occurred while creating the Wishlist. {Entity} - {Error}", entity, e.Message);
            return Result.Failure<Entities.Wishlist>($"An error occurred while creating the Wishlist. {e}");
        }
    }

    public async Task<Maybe<Entities.Wishlist>> Read(Guid entityId)
    {
        var entity = await _context.Wishlists.FindAsync(entityId);
        return entity;
    }

    public async Task<Result<Entities.Wishlist>> Update(Entities.Wishlist entity)
    {
        var oldEntity = await Read(entity.Id);
        if (oldEntity.HasNoValue)
        {
            return Result.Failure<Entities.Wishlist>("The given entity was not found.");
        }
        entity.LastModified =  DateTime.UtcNow;
        _context.Wishlists.Update(entity);
        await _context.SaveChangesAsync();
        return Result.Success(entity);
    }

    public async Task<Result<Entities.Wishlist>> Delete(Guid entityId)
    {
        var entity = await Read(entityId);
        if (entity.HasNoValue)
        {
            return Result.Failure<Entities.Wishlist>("The given entity was not found.");
        }
        var deletedEntity = _context.Wishlists.Remove(entity.Value);
        await _context.SaveChangesAsync();
        return Result.Success(deletedEntity.Entity);
    }

    public async Task<Result<Wish>> AddWish(Guid id, Wish wish)
    {
        var listMaybe = await Read(id);
        if (listMaybe.HasNoValue)
        {
            return Result.Failure<Wish>($"Wishlist '{id}' was not found. Wish '{wish.Id}' not added");
        }
        var wishlist = listMaybe.Value;

        wish.WishlistId = wishlist.Id;
        wishlist.Wishes.Add(wish);
        var update = await Update(wishlist);
        if (update.IsFailure)
        {
            return Result.Failure<Wish>(update.Error);
        }
        await _context.SaveChangesAsync();
        return Result.Success(wish);
    }
}