using System.Collections.Concurrent;
using System.Security.Cryptography;

namespace ApiDenuncias.Services;

public sealed record PendingGlobalLeaksLogin(
    string Id,
    string Username,
    string Password,
    string FinalPassword,
    string TokenAnswer,
    DateTimeOffset ExpiresAtUtc);

public sealed class PendingGlobalLeaksLoginStore
{
    private static readonly TimeSpan Lifetime = TimeSpan.FromMinutes(5);
    private readonly ConcurrentDictionary<string, PendingGlobalLeaksLogin> _items = new(StringComparer.Ordinal);

    public PendingGlobalLeaksLogin Create(string username, string password, string finalPassword, string tokenAnswer)
    {
        CleanupExpired();

        var id = Convert.ToHexString(RandomNumberGenerator.GetBytes(32)).ToLowerInvariant();
        var pending = new PendingGlobalLeaksLogin(
            id,
            username,
            password,
            finalPassword,
            tokenAnswer,
            DateTimeOffset.UtcNow.Add(Lifetime));

        _items[id] = pending;
        return pending;
    }

    public PendingGlobalLeaksLogin Get(string id)
    {
        CleanupExpired();

        if (string.IsNullOrWhiteSpace(id) || !_items.TryGetValue(id, out var pending))
        {
            throw new InvalidOperationException("La preparacion del login ha caducado. Vuelve a introducir usuario y contrasena.");
        }

        if (pending.ExpiresAtUtc <= DateTimeOffset.UtcNow)
        {
            _items.TryRemove(id, out _);
            throw new InvalidOperationException("La preparacion del login ha caducado. Vuelve a introducir usuario y contrasena.");
        }

        return pending;
    }

    public void Remove(string id)
    {
        if (!string.IsNullOrWhiteSpace(id))
        {
            _items.TryRemove(id, out _);
        }
    }

    private void CleanupExpired()
    {
        var now = DateTimeOffset.UtcNow;
        foreach (var item in _items)
        {
            if (item.Value.ExpiresAtUtc <= now)
            {
                _items.TryRemove(item.Key, out _);
            }
        }
    }
}
