using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Skcks.Study.AbpProject.Categories;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;

namespace Skcks.Study.AbpProject.Products;

public class ProductAppService:AbpProjectAppService, IProductAppService
{
    private readonly IRepository<Product, Guid> _productRepository;
    private readonly IRepository<Category, Guid> _categoryRepository;
    private readonly IUnitOfWorkManager _unitOfWorkManager;

    public ProductAppService(IRepository<Product, Guid> productRepository, IRepository<Category, Guid> categoryRepository, IUnitOfWorkManager unitOfWorkManager)
    {
        _productRepository = productRepository;
        _categoryRepository = categoryRepository;
        _unitOfWorkManager = unitOfWorkManager;
    }

    public async Task<PagedResultDto<ProductDto>> GetListAsync(PagedAndSortedResultRequestDto input)
    {
        var productsQuery = await _productRepository.WithDetailsAsync(x=>x.Category);

        productsQuery = productsQuery.Skip(input.SkipCount)
            .Take(input.MaxResultCount)
            .OrderBy(x => input.Sorting ?? x.Name);


        var products = await AsyncExecuter.ToListAsync(productsQuery);
        var count = await _productRepository.GetCountAsync();

        return new PagedResultDto<ProductDto>(
            count, ObjectMapper.Map<List<Product>, List<ProductDto>>(products));
    }

    public async Task CreateAsync(CreateUpdateProductDto input)
    {
        var product = ObjectMapper.Map<CreateUpdateProductDto, Product>(input);
        await _productRepository.InsertAsync(product);
    }

    public async Task<ListResultDto<CategoryLookupDto>> GetCategoriesAsync()
    {
        var categories = await _categoryRepository.GetListAsync();
        var categoryLookupDto = ObjectMapper.Map<List<Category>, List<CategoryLookupDto>>(categories);

        return new ListResultDto<CategoryLookupDto>(categoryLookupDto);
    }

    public async Task<ProductDto> GetAsync(Guid id)
    {
        var product = await _productRepository.GetAsync(id);
        return ObjectMapper.Map<Product, ProductDto>(product);
    }

    public async Task UpdateAsync(Guid id, CreateUpdateProductDto input)
    {
        var product = await _productRepository.GetAsync(id);
        ObjectMapper.Map(input, product);
    }

    public async Task DeleteAsync(Guid id)
    {
        await _productRepository.DeleteAsync(id);
    }
}