using System.Net.Http.Json;
using System.Text.Json.Serialization;
using Meezi.Core.Interfaces;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace Meezi.Infrastructure.ExternalServices;

public class KavenegarSmsService : ISmsService
{
    private readonly HttpClient _httpClient;
    private readonly IConfiguration _configuration;
    private readonly IPlatformRuntimeConfig _platform;
    private readonly ILogger<KavenegarSmsService> _logger;

    public KavenegarSmsService(
        HttpClient httpClient,
        IConfiguration configuration,
        IPlatformRuntimeConfig platform,
        ILogger<KavenegarSmsService> logger)
    {
        _httpClient = httpClient;
        _configuration = configuration;
        _platform = platform;
        _logger = logger;
    }

    public async Task SendMessageAsync(string phone, string message, CancellationToken cancellationToken = default)
    {
        var apiKey = await GetApiKeyAsync(cancellationToken);
        if (string.IsNullOrWhiteSpace(apiKey))
        {
            _logger.LogInformation(
                "Kavenegar API key not configured — SMS to {Phone}: {Message}",
                phone,
                message);
            return;
        }

        var url =
            $"https://api.kavenegar.com/v1/{apiKey}/sms/send.json" +
            $"?receptor={Uri.EscapeDataString(phone)}&message={Uri.EscapeDataString(message)}";

        var response = await _httpClient.GetAsync(url, cancellationToken);
        if (!response.IsSuccessStatusCode)
        {
            _logger.LogWarning("Kavenegar SMS send failed with status {StatusCode}", response.StatusCode);
            throw new InvalidOperationException("SMS delivery failed.");
        }

        var body = await response.Content.ReadFromJsonAsync<KavenegarResponse>(cancellationToken: cancellationToken);
        if (body?.Return?.Status is not 200)
            throw new InvalidOperationException("SMS delivery failed.");
    }

    public async Task SendOtpAsync(string phone, string otp, CancellationToken cancellationToken = default)
    {
        var apiKey = await GetApiKeyAsync(cancellationToken);
        var template = await GetOtpTemplateAsync(cancellationToken);

        if (string.IsNullOrWhiteSpace(apiKey))
        {
            _logger.LogInformation("Kavenegar API key not configured — OTP for {Phone} (dev only, not sent via SMS)", phone);
            return;
        }

        var url = $"https://api.kavenegar.com/v1/{apiKey}/verify/lookup.json" +
                  $"?receptor={Uri.EscapeDataString(phone)}&token={otp}&template={Uri.EscapeDataString(template)}";

        var response = await _httpClient.GetAsync(url, cancellationToken);
        if (!response.IsSuccessStatusCode)
        {
            _logger.LogWarning("Kavenegar OTP send failed with status {StatusCode}", response.StatusCode);
            throw new InvalidOperationException("SMS delivery failed.");
        }

        var body = await response.Content.ReadFromJsonAsync<KavenegarResponse>(cancellationToken: cancellationToken);
        if (body?.Return?.Status is not 200)
        {
            _logger.LogWarning("Kavenegar returned status {Status}", body?.Return?.Status);
            throw new InvalidOperationException("SMS delivery failed.");
        }
    }

    private sealed class KavenegarResponse
    {
        [JsonPropertyName("return")]
        public KavenegarReturn? Return { get; set; }
    }

    private sealed class KavenegarReturn
    {
        [JsonPropertyName("status")]
        public int Status { get; set; }
    }

    private async Task<string?> GetApiKeyAsync(CancellationToken cancellationToken)
    {
        var fromDb = await _platform.GetAsync("integrations.kavenegar.apiKey", cancellationToken);
        if (!string.IsNullOrWhiteSpace(fromDb))
            return fromDb;
        return _configuration["Kavenegar:ApiKey"];
    }

    private async Task<string> GetOtpTemplateAsync(CancellationToken cancellationToken)
    {
        var fromDb = await _platform.GetAsync("integrations.kavenegar.otpTemplate", cancellationToken);
        if (!string.IsNullOrWhiteSpace(fromDb))
            return fromDb;
        return _configuration["Kavenegar:OtpTemplate"] ?? "verify";
    }
}
