using MediatR;
using Netina.Domain.Dtos.ResponseDtos.Torob;
using Netina.Domain.Dtos.ResponseDtos.Zarehbin;
using Netina.Domain.Entities.ProductCategories;

namespace Netina.Core.CoreServices;

public class SearchService : ISearchService
{
    private readonly IRepositoryWrapper _repositoryWrapper;

    public SearchService(IRepositoryWrapper repositoryWrapper)
    {
        _repositoryWrapper = repositoryWrapper;
    }
    public async Task<SearchResponseDto> SearchAsync(string name, CancellationToken cancellationToken = default)
    {
        var searchQuery = name.ToLowerInvariant().Trim();
        int minSimilarityThreshold = 20;
        var products = await _repositoryWrapper.SetRepository<Product>()
            .TableNoTracking
            .Where(p => FuzzySharp.Fuzz.PartialRatio(p.PersianName.ToLowerInvariant().Trim(), searchQuery) >= minSimilarityThreshold)
            .Select(ProductMapper.ProjectToSDto)
            .ToListAsync(cancellationToken);

        var categories = await _repositoryWrapper.SetRepository<ProductCategory>()
            .TableNoTracking
            .Where(p => FuzzySharp.Fuzz.PartialRatio(p.Name.ToLowerInvariant().Trim(), searchQuery) >= minSimilarityThreshold)
            .Select(ProductCategoryMapper.ProjectToSDto)
            .ToListAsync(cancellationToken);

        return new SearchResponseDto
        {
            Products = products.Select(p => p.Adapt<SearchedProductResponseDto>()).ToList(),
            Categories = categories.Select(c => c.Adapt<SearchedProductCategoryResponseDto>()).ToList()
        };
    }

    public async Task<SearchResponseDto> ThumbSearchAsync(string name, CancellationToken cancellationToken = default)
    {
        var searchQuery = name.ToLowerInvariant().Trim();
        int minSimilarityThreshold = 20;
        var products = await _repositoryWrapper.SetRepository<Product>()
            .TableNoTracking
            .Where(p => FuzzySharp.Fuzz.PartialRatio(p.PersianName.ToLowerInvariant().Trim(), searchQuery) >= minSimilarityThreshold)
            .Take(8)
            .Select(ProductMapper.ProjectToSDto)
            .ToListAsync(cancellationToken);

        var categories = await _repositoryWrapper.SetRepository<ProductCategory>()
            .TableNoTracking
            .Where(p => FuzzySharp.Fuzz.PartialRatio(p.Name.ToLowerInvariant().Trim(), searchQuery) >= minSimilarityThreshold)
            .Select(ProductCategoryMapper.ProjectToSDto)
            .ToListAsync(cancellationToken);

        return new SearchResponseDto
        {
            Products = products.Select(p => p.Adapt<SearchedProductResponseDto>()).ToList(),
            Categories = categories.Select(c => c.Adapt<SearchedProductCategoryResponseDto>()).ToList()
        };
    }

    public Task<ZarehbinPagedResponseDto> ZarehbinAsync(int page, CancellationToken cancellationToken = default)
    {
        throw new NotImplementedException();
    }

    public Task<ZarehbinProductResponseDto> ZarehbinAsync(Guid productId, CancellationToken cancellationToken = default)
    {
        throw new NotImplementedException();
    }

}