using Knot.Shared.Kernel;
using Knot.Contracts.Settings.Application.Abstractions;
using Knot.Contracts.Settings.Application.DTOs;
using Knot.Shared.Kernel.Constants;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using MediatR;

namespace Knot.Modules.Klipy.Application.Klipy.Queries;

public record GetTrendingGifsQuery(int Page = 1) : IQuery<JsonElement?>;

internal sealed class GetTrendingGifsQueryHandler : IQueryHandler<GetTrendingGifsQuery, JsonElement?>
{
    private readonly IKlipySettings _settings;
    private readonly IMemoryCache _cache;
    private readonly IHttpClientFactory _httpClientFactory;

    public GetTrendingGifsQueryHandler(IKlipySettings settings, IMemoryCache cache, IHttpClientFactory httpClientFactory)
    {
        _settings = settings;
        _cache = cache;
        _httpClientFactory = httpClientFactory;
    }

    public async Task<Result<JsonElement?>> Handle(GetTrendingGifsQuery request, CancellationToken cancellationToken)
    {
        var conf = _settings.Current;
        if (!conf.Enabled || string.IsNullOrEmpty(conf.ApiKey))
            return Result.Failure<JsonElement?>(new Error(Errors.KlipyNotConfigured, "Klipy is not configured"));

        var cacheKeyTrending = $"klipy_trending_{conf.ApiKey}_{request.Page}";
        if (_cache.TryGetValue(cacheKeyTrending, out JsonElement cachedResult))
            return Result.Success<JsonElement?>(cachedResult);

        var customerId = Knot.Shared.Kernel.Constants.Klipy.DefaultCustomerId;
        var client = _httpClientFactory.CreateClient();
        
        var urlCo = string.Format(Knot.Shared.Kernel.Constants.Klipy.ApiUrlCo, conf.ApiKey, Knot.Shared.Kernel.Constants.Klipy.ResourceTrending, request.Page, 30, "", customerId);

        var response = await client.GetAsync(urlCo, cancellationToken);
        if (!response.IsSuccessStatusCode)
        {
            if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
            {
                var urlCom = string.Format(Knot.Shared.Kernel.Constants.Klipy.ApiUrlCom, conf.ApiKey, Knot.Shared.Kernel.Constants.Klipy.ResourceTrending, request.Page, 30, "", customerId);
                response = await client.GetAsync(urlCom, cancellationToken);
            }

            if (!response.IsSuccessStatusCode)
                return Result.Failure<JsonElement?>(new Error(Errors.KlipyApiError, "Klipy API Error"));
        }

        var result = await response.Content.ReadFromJsonAsync<JsonElement>(cancellationToken: cancellationToken);
        _cache.Set(cacheKeyTrending, result, TimeSpan.FromMinutes(Knot.Shared.Kernel.Constants.Klipy.TrendingCacheMinutes));
        
        return Result.Success<JsonElement?>(result);
    }
}

