using Knot.Shared.Kernel;
using Knot.Contracts.Settings.Application.Abstractions;
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 GetRecentGifsQuery(int Page = 1) : IQuery<JsonElement?>;

internal sealed class GetRecentGifsQueryHandler : IQueryHandler<GetRecentGifsQuery, JsonElement?>
{
    private readonly IKlipySettings _settings;
    private readonly IMemoryCache _cache;
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly IUserContext _userContext;

    public GetRecentGifsQueryHandler(IKlipySettings settings, IMemoryCache cache, IHttpClientFactory httpClientFactory, IUserContext userContext)
    {
        _settings = settings;
        _cache = cache;
        _httpClientFactory = httpClientFactory;
        _userContext = userContext;
    }

    public async Task<Result<JsonElement?>> Handle(GetRecentGifsQuery 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"));

        if (!_userContext.IsAuthenticated)
            return Result.Failure<JsonElement?>(new Error("AuthError", "User not authenticated"));

        var customerId = _userContext.UserId.ToString().ToLowerInvariant();
        
        // Disable cache for history to ensure it updates immediately
        var client = _httpClientFactory.CreateClient();
        
        // Correct URL according to docs: GET https://api.klipy.com/api/v1/{app_key}/gifs/recent/{customer_id}?page={page}&per_page={per_page}
        var baseUrl = "https://api.klipy.com/api/v1"; 
        var url = $"{baseUrl}/{conf.ApiKey}/gifs/recent/{customerId}?page={request.Page}&per_page=24";

        var response = await client.GetAsync(url, cancellationToken);
        if (!response.IsSuccessStatusCode)
        {
            if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
            {
                var urlCo = url.Replace("api.klipy.com", "api.klipy.co");
                response = await client.GetAsync(urlCo, cancellationToken);
            }

            if (!response.IsSuccessStatusCode)
            {
                var errorBody = await response.Content.ReadAsStringAsync(cancellationToken);
                return Result.Failure<JsonElement?>(new Error(Errors.KlipyApiError, $"Klipy Recent API Error: {response.StatusCode} {errorBody}"));
            }
        }

        var result = await response.Content.ReadFromJsonAsync<JsonElement>(cancellationToken: cancellationToken);
        
        return Result.Success<JsonElement?>(result);
    }
}
