using Knot.Shared.Kernel;
using Knot.Contracts.Settings.Application.Abstractions;
using Knot.Shared.Kernel.Constants;
using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading;
using System.Threading.Tasks;
using MediatR;

namespace Knot.Modules.Klipy.Application.Klipy.Commands;

public record MarkGifSharedCommand(string GifId, string Query = "") : ICommand;

internal sealed class MarkGifSharedCommandHandler : ICommandHandler<MarkGifSharedCommand>
{
    private readonly IKlipySettings _settings;
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly IUserContext _userContext;

    public MarkGifSharedCommandHandler(IKlipySettings settings, IHttpClientFactory httpClientFactory, IUserContext userContext)
    {
        _settings = settings;
        _httpClientFactory = httpClientFactory;
        _userContext = userContext;
    }

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

        var customerId = _userContext.IsAuthenticated ? _userContext.UserId.ToString().ToLowerInvariant() : Knot.Shared.Kernel.Constants.Klipy.DefaultCustomerId;
        
        var client = _httpClientFactory.CreateClient();
        client.DefaultRequestHeaders.Add("Accept", "application/json");
        
        // Correct URL according to docs: POST https://api.klipy.com/api/v1/{app_key}/gifs/share/{gif_id}
        var baseUrl = "https://api.klipy.com/api/v1"; 
        var url = $"{baseUrl}/{conf.ApiKey}/gifs/share/{request.GifId}";

        // According to docs, q and customer_id must be in the JSON body
        var body = new
        {
            customer_id = customerId,
            q = request.Query ?? "" // Must be empty string if not from search
        };

        using var content = JsonContent.Create(body);
        var response = await client.PostAsync(url, content, cancellationToken);
        
        if (!response.IsSuccessStatusCode)
        {
            if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
            {
                var urlCo = url.Replace("api.klipy.com", "api.klipy.co");
                using var contentCo = JsonContent.Create(body);
                response = await client.PostAsync(urlCo, contentCo, cancellationToken);
            }

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

        return Result.Success();
    }
}
