using Application.Aggregates.Products.ViewModels;
using Application.Aggregates.Stores.ViewModels;
using Domain.Aggregates.Products;
using Domain.Aggregates.Products.Data;
using Domain.Aggregates.Stores;
using Mapster;
using Persistence.Repositories.Aggregates.Stores;
using Resources.Messages;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Application.Aggregates.Products;

public class ProductsApplication(IProductRepository productRepository)
{
    public async Task<ProductViewModel> CreateAsync(CreateProductViewModel productViewModel)
    {
        var product =  Product.Create(
            name: productViewModel.Name,
            description: productViewModel.Description,
            price: productViewModel.Price,
            quantity: productViewModel.Quantity);

        if (productViewModel.IsActive == true)
        {
            product.Activate();
        }

        await productRepository.AddAsync(product);
        await productRepository.SaveChangesAsync();

        return product.Adapt<ProductViewModel>();
    }

    public async Task<List<ProductViewModel>> GetStors()
    {
        var products =
            await productRepository.GetAllAsync();

        return products.Adapt<List<ProductViewModel>>();
    }

    public async Task<ProductViewModel> GetAsync(Guid productId)
    {
        var product =
            await productRepository.GetAsync(productId);

        return product.Adapt<ProductViewModel>();
    }

    public async Task<ProductViewModel> UpdateAsync(UpdateProductViewModel updateProductView)
    {
        var update =
            await productRepository.GetAsync(updateProductView.Id);

        if (update == null || updateProductView.Id == Guid.Empty)
        {
            var error =
                string.Format(Errors.NotFound, Resources.DataDictionary.Store);

            throw new Exception(error);
        }

        update.Update(
            name: updateProductView.Name,
            description: updateProductView.Description,
            price: updateProductView.Price,
            quantity: updateProductView.Quantity);

        if (updateProductView.IsActive == true)
        {
            update.Activate();
        }
        else
        {
            update.Deactivate();
        }

        await productRepository.SaveChangesAsync();

        return update.Adapt<ProductViewModel>();
    }

    public async Task DeleteAsync(Guid productId)
    {
        var delete =
            await productRepository.GetAsync(productId);

        if (delete == null || delete.Id == Guid.Empty)
        {
            var error =
                string.Format(Errors.NotFound, Resources.DataDictionary.Store);

            throw new Exception(error);
        }

        productRepository.Remove(delete);

        await productRepository.SaveChangesAsync();
    }
}
