using JSMR.Application.Common.Search;
using JSMR.Application.Logging;
using Microsoft.Extensions.Logging;
using System.Diagnostics;

namespace JSMR.Application.VoiceWorks.Queries.Search;

// TODO: Caching?
public sealed class SearchVoiceWorksHandler(IVoiceWorkSearchProvider provider, ILogger<SearchVoiceWorksHandler> logger)
{
    public async Task<SearchVoiceWorksResponse> HandleAsync(SearchVoiceWorksRequest request, CancellationToken cancellationToken)
    {
        var searchOptions = request.Options;

        Stopwatch stopWatch = Stopwatch.StartNew();
        SearchResult<VoiceWorkSearchResult> results = await provider.SearchAsync(searchOptions, cancellationToken);
        long elapsedMilliseconds = stopWatch.ElapsedMilliseconds;

        LogEvents.SearchCompleted(
            logger,
            Elapsed: elapsedMilliseconds,
            Items: results.Items.Length,
            Total: results.TotalItems,
            Page: searchOptions.PageNumber,
            Size: searchOptions.PageSize,
            Sort: searchOptions.SortOptions.ToLogObject(),
            Criteria: searchOptions.Criteria.ToLogObject()
        );

        return new SearchVoiceWorksResponse(results);
    }
}

//public record SearchProviderContext(

//);

//public class SearchHandler<TSearchResult, TCriteria, TSortField>(ISearchProvider<TSearchResult, TCriteria, TSortField> searchProvider, ILogger logger)
//    where TCriteria : notnull, new()
//    where TSortField : struct, Enum
//{
//    public async Task<SearchVoiceWorksResponse> HandleAsync(SearchOptions<TCriteria, TSortField> options, CancellationToken cancellationToken)
//    {
//        Stopwatch stopWatch = Stopwatch.StartNew();

//        SearchResult<TSearchResult> results = await searchProvider.SearchAsync(options, cancellationToken);

//        long elapsedMilliseconds = stopWatch.ElapsedMilliseconds;

//        LogEvents.SearchCompleted(
//            logger,
//            Elapsed: elapsedMilliseconds,
//            Items: results.Items.Length,
//            Total: results.TotalItems,
//            Page: options.PageNumber,
//            Size: options.PageSize,
//            Sort: options.SortOptions.ToLogObject(),
//            Criteria: options.Criteria.ToLogObject()
//        );

//        return new SearchVoiceWorksResponse(results);
//    }
//}