using System.Text.Json;
using JobsMedical.Web.Models;

namespace JobsMedical.Web.Services.Scraping;

/// <summary>
/// Bale (Iranian messenger) source via its Telegram-compatible Bot API getUpdates. Enabled +
/// bot token come from admin settings (DB). The bot must be a member of the channels it reads.
/// </summary>
public class BaleListingSource : IListingSource
{
    private const string BaseUrl = "https://tapi.bale.ai";
    private readonly ScrapeHttpClients _clients;
    private readonly ILogger<BaleListingSource> _log;

    public BaleListingSource(ScrapeHttpClients clients, ILogger<BaleListingSource> log)
    {
        _clients = clients;
        _log = log;
    }

    public string Name => "بله";

    public async Task<IReadOnlyList<ScrapedItem>> FetchAsync(AppSetting s, CancellationToken ct = default)
    {
        if (!s.BaleEnabled || string.IsNullOrWhiteSpace(s.BaleBotToken)) return Array.Empty<ScrapedItem>();

        try
        {
            var client = _clients.For(s, s.BaleUseProxy);
            var body = await client.GetStringAsync($"{BaseUrl}/bot{s.BaleBotToken}/getUpdates", ct);
            using var doc = JsonDocument.Parse(body);
            if (!doc.RootElement.TryGetProperty("result", out var result) || result.ValueKind != JsonValueKind.Array)
                return Array.Empty<ScrapedItem>();

            var items = new List<ScrapedItem>();
            foreach (var update in result.EnumerateArray())
            {
                var post = Msg(update, "channel_post") ?? Msg(update, "message");
                if (post is not { } p) continue;
                var text = p.TryGetProperty("text", out var t) && t.ValueKind == JsonValueKind.String ? t.GetString() : null;
                if (string.IsNullOrWhiteSpace(text) || text!.Trim().Length < 15) continue;
                // Bot API messages carry a unix `date` — keep it so stale posts can be aged out.
                DateTime? postedAt = p.TryGetProperty("date", out var d) && d.ValueKind == JsonValueKind.Number && d.TryGetInt64(out var epoch)
                    ? DateTimeOffset.FromUnixTimeSeconds(epoch).UtcDateTime : null;
                items.Add(new ScrapedItem("بله", text.Trim(), PostedAt: postedAt));
            }
            return items;
        }
        catch (Exception ex) { _log.LogWarning(ex, "Bale fetch failed."); return Array.Empty<ScrapedItem>(); }
    }

    private static JsonElement? Msg(JsonElement update, string key)
        => update.TryGetProperty(key, out var m) && m.ValueKind == JsonValueKind.Object ? m : null;
}
