using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Nostr.Client.Json;
using Nostr.Client.Messages;
using NostrServices.Client;
using NostrServices.Services;

namespace NostrServices.Controllers;

[Route("/api/v1/import")]
public class ImportController : Controller
{
    private readonly ILogger<ImportController> _logger;
    private readonly RedisStore _redisStore;

    public ImportController(RedisStore redisStore, ILogger<ImportController> logger)
    {
        _redisStore = redisStore;
        _logger = logger;
    }

    /// <summary>
    /// Import events in ND-JSON format
    /// </summary>
    /// <remarks>
    /// POST events in ND-JSON format here to add them to the cache which is used in <see cref="OpenGraphController"/>
    /// 
    /// `nak req -k 1 -l 100 wss://nos.lol | curl -v -X POST --data-binary @- https://nostr.api.v0l.io/api/v1/import`
    ///
    /// You can also write events directly to this API as nostr websocket
    ///
    /// `nak req -k 1 -l 100 wss://nos.lol | nak event --envelope | websocat -tn wss://nostr.api.v0l.io/`
    /// </remarks>
    /// <returns></returns>
    [HttpPost]
    [DisableRequestSizeLimit]
    [Consumes("text/json", "application/json")]
    public async Task<IActionResult> ImportEvent()
    {
        var cts = HttpContext.RequestAborted;
        using var sr = new StreamReader(Request.Body);

        while (await sr.ReadLineAsync(cts) is { } line)
        {
            try
            {
                var ev = JsonConvert.DeserializeObject<NostrEvent>(line, NostrSerializer.Settings);
                if (ev != default && ev.IsSignatureValid())
                {
                    if (RelayListener.AcceptedKinds.Contains(ev.Kind))
                    {
                        if (ev.Kind is NostrKind.Metadata)
                        {
                            await _redisStore.StoreProfile(CompactProfile.FromNostrEvent(ev)!);
                        }
                        else
                        {
                            await _redisStore.StoreEvent(CompactEvent.FromNostrEvent(ev));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning("Failed to import {json} {msg}", line, ex.Message);
            }
        }

        return Ok();
    }
}
