using System;

namespace AiLogia.Web.Services;

public interface IAuthLinksClient
{
    Task<(bool valid, string? reason, long userId, long tgId, string? username, string? fullName, DateTime? expiresUtc)>
           ValidateAsync(string token, CancellationToken ct = default);

    Task<bool> ConsumeAsync(string token, CancellationToken ct = default);
    Task<(string token, DateTime expiresAtUtc)?> CreateAsync(
       long tgId, string? username, string? fullName, int? ttlMinutes = null, CancellationToken ct = default);
}

public sealed class AuthLinksClient : IAuthLinksClient
{
    private readonly HttpClient _http;
    private readonly string? _apiKey;
    public AuthLinksClient(IHttpClientFactory factory, IConfiguration cfg)
    {
        _http = factory.CreateClient("AuthMs");
        _http.BaseAddress = new Uri(cfg["AuthService:BaseUrl"]!);
        _apiKey = cfg["AuthService:ApiKey"];
    }

    // === DTO под ответы AiLogia.Auth ===
    private sealed record MagicUser(long id, long telegram_user_id, string? username, string? full_name);

    private sealed record ValidateResponse(
        bool valid,
        string? reason,
        MagicUser? user,
        DateTime? expires_at_utc
    );

    private sealed record ConsumeRequest(string token);
    private sealed record ConsumeResponse(bool consumed);

    public async Task<(bool valid, string? reason, long userId, long tgId, string? username, string? fullName, DateTime? expiresUtc)>
        ValidateAsync(string token, CancellationToken ct = default)
    {
        var url = $"/magic-links/validate?token={Uri.EscapeDataString(token)}";
        var dto = await _http.GetFromJsonAsync<ValidateResponse>(url, cancellationToken: ct);

        if (dto is null)
            return (false, "invalid", 0, 0, null, null, null);

        if (!dto.valid || dto.user is null)
            return (false, dto.reason, 0, 0, null, null, dto.expires_at_utc);

        return (true, null,
            dto.user.id,
            dto.user.telegram_user_id,
            dto.user.username,
            dto.user.full_name,
            dto.expires_at_utc);
    }

    private sealed record CreateRequest(long telegram_user_id, string? username, string? full_name, int? ttl_minutes);
    private sealed record CreateResponse(string token, DateTime expires_at_utc);


    public async Task<bool> ConsumeAsync(string token, CancellationToken ct = default)
    {
        using var resp = await _http.PostAsJsonAsync("/magic-links/consume", new ConsumeRequest(token), ct);
        if (!resp.IsSuccessStatusCode) return false;

        var dto = await resp.Content.ReadFromJsonAsync<ConsumeResponse>(cancellationToken: ct);
        return dto?.consumed == true;
    }

    public async Task<(string token, DateTime expiresAtUtc)?> CreateAsync(
        long tgId, string? username, string? fullName, int? ttlMinutes = null, CancellationToken ct = default)
    {
        using var req = new HttpRequestMessage(HttpMethod.Post, "/magic-links");
        if (!string.IsNullOrEmpty(_apiKey))
            req.Headers.Add("X-Api-Key", _apiKey);

        req.Content = JsonContent.Create(new CreateRequest(tgId, username, fullName, ttlMinutes));
        using var resp = await _http.SendAsync(req, ct);
        if (!resp.IsSuccessStatusCode) return null;

        var dto = await resp.Content.ReadFromJsonAsync<CreateResponse>(cancellationToken: ct);
        return dto is null ? null : (dto.token, dto.expires_at_utc);
    }
}