using BotPages.Core.Abstractions;
namespace BotPages.Core.Messaging;
///
/// Fluent‑билдер для отправки сообщений (текст, кнопки, файлы, альбомы, прогресс).
///
public sealed class MessageBuilder
{
private readonly PageContext _ctx;
private string? _text = null;
private MessageFormat _format = MessageFormat.Plain;
private readonly List> _inline = new();
private readonly List> _reply = new();
private readonly List<(FileDescriptor file, string? caption, MessageFormat? captionFormat)> _files = new();
private readonly List<(FileDescriptor file, string? caption, MessageFormat? captionFormat)> _album = new();
private string? _progressTitle = null;
private int? _progressPercent = null;
private string? _progressMessageId = null;
private bool _disableReplyKeyboard;
/// Создать билдер сообщений.
public MessageBuilder(PageContext ctx) => _ctx = ctx;
/// Текст сообщения.
public MessageBuilder Text(string text, MessageFormat format = MessageFormat.Plain)
{
_text = text;
_format = format;
return this;
}
/// Добавить inline‑кнопку.
public MessageBuilder Inline(string label, string value)
{
_inline.Add(new() { new(label, value) });
return this;
}
/// Добавить inline‑кнопку.
public MessageBuilder Inline(InlineButton button)
{
_inline.Add(new() { button });
return this;
}
/// Добавить inline‑кнопку.
public MessageBuilder Inline(params InlineButton[] buttons)
{
_inline.Add(buttons.ToList());
return this;
}
/// Добавить строку inline‑кнопок.
public MessageBuilder Inline(IEnumerable row)
{
_inline.Add(row.ToList());
return this;
}
/// Добавить строку inline‑кнопок.
public MessageBuilder Inline(IEnumerable> row)
{
_inline.AddRange(row.Select(t => t.ToList()).ToList());
return this;
}
///
/// Отключение Reply клавиатуры.
///
///
public MessageBuilder DisableReply()
{
_disableReplyKeyboard = true;
return this;
}
/// Добавить reply‑кнопку.
public MessageBuilder Reply(params ReplyButton[] label)
{
_disableReplyKeyboard = false;
_reply.Add(label.ToList());
return this;
}
/// Добавить строку reply‑кнопок.
public MessageBuilder Reply(IEnumerable row)
{
_disableReplyKeyboard = false;
_reply.Add(row.ToList());
return this;
}
/// Добавить строку reply‑кнопок.
public MessageBuilder Reply(IEnumerable> row)
{
_disableReplyKeyboard = false;
_reply.AddRange(row.Select(t => t.ToList()).ToList());
return this;
}
/// Добавить файл для отправки.
public MessageBuilder File(FileDescriptor file, string? caption = null, MessageFormat? captionFormat = null)
{
_files.Add((file, caption, captionFormat));
return this;
}
/// Добавить файл в альбом.
public MessageBuilder Album(FileDescriptor file, string? caption = null, MessageFormat? captionFormat = null)
{
_album.Add((file, caption, captionFormat));
return this;
}
/// Установить прогресс операции.
public MessageBuilder Progress(string title, int percent = 0)
{
_progressTitle = title;
_progressPercent = percent;
return this;
}
/// Отправить собранное сообщение.
public async Task SendAsync(CancellationToken ct = default)
{
// Текст
if (!string.IsNullOrWhiteSpace(_text))
{
List>? reply = null;
if (_disableReplyKeyboard) reply = new();
else if (_reply.Any()) reply = _reply;
await _ctx.SendTextAsync(_text, _format, _inline, reply, ct);
}
// Файлы
foreach (var (file, caption, captionFormat) in _files)
await _ctx.SendFileAsync(file, caption, captionFormat, ct);
// Альбом
if (_album.Count > 0)
{
var builder = _ctx.Albums;
foreach (var (file, caption, captionFormat) in _album)
builder.Add(file, caption, captionFormat);
await builder.SendAsync(ct);
}
// Прогресс
if (_progressTitle is not null)
{
if (_progressMessageId is null)
_progressMessageId = await _ctx.StartProgressAsync(_progressTitle, ct);
if (_progressPercent > 0 && !string.IsNullOrEmpty(_progressMessageId))
await _ctx.UpdateProgressAsync(_progressMessageId, _progressPercent.Value, ct);
}
_text = null;
_files.Clear();
_album.Clear();
if (_progressPercent >= 100)
{
_progressTitle = null;
_progressMessageId = null;
_progressPercent = null;
}
}
}