using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Dapper;
using Npgsql;
using Telegram.Bot;
using Telegram.Bot.Types.ReplyMarkups;

namespace GmRelay.Bot.Features.Sessions.CreateSession.Wizard;

public sealed class TelegramWizardMessenger(
    ITelegramBotClient bot,
    NpgsqlDataSource dataSource) : ITelegramWizardMessenger
{
    public async Task<long> EditMessageTextAsync(
        long chatId, int? messageThreadId, long messageId, string text,
        InlineKeyboardMarkup keyboard, CancellationToken ct)
    {
        var msg = await bot.EditMessageText(
            chatId: chatId,
            messageId: (int)messageId,
            text: text,
            replyMarkup: keyboard,
            cancellationToken: ct);
        return msg.MessageId;
    }

    public async Task<long> SendGroupMessageAsync(
        long chatId, int? messageThreadId, string text,
        InlineKeyboardMarkup keyboard, CancellationToken ct)
    {
        var msg = await bot.SendMessage(
            chatId: chatId,
            text: text,
            messageThreadId: messageThreadId,
            replyMarkup: keyboard,
            cancellationToken: ct);
        return msg.MessageId;
    }

    public async Task AnswerCallbackAsync(string callbackId, string? text, CancellationToken ct)
    {
        await bot.AnswerCallbackQuery(callbackId, text: text, cancellationToken: ct);
    }

    public async Task<IReadOnlyList<WizardClubOption>> GetGmClubsAsync(long ownerTelegramId, CancellationToken ct)
    {
        // Adjusted from the plan: this codebase models "clubs" as game_groups
        // (V001 created game_groups; V026 added public_slug; no `clubs` table exists,
        // and game_groups has no `club_id` FK). The picker therefore returns the
        // game_groups the owner manages as a GM (via group_managers), matching
        // the WizardClubOption contract (UUID id, name) used downstream.
        const string sql = """
            SELECT g.id   AS ClubId,
                   g.name AS Name
            FROM game_groups g
            JOIN group_managers gm ON gm.group_id = g.id
            JOIN players p ON p.id = gm.player_id
            WHERE p.platform = 'Telegram'
              AND p.external_user_id = @ExternalId
            GROUP BY g.id, g.name
            ORDER BY g.name
            """;
        await using var connection = await dataSource.OpenConnectionAsync(ct);
        var rows = await connection.QueryAsync<WizardClubOption>(
            new CommandDefinition(sql, new { ExternalId = ownerTelegramId.ToString() }, cancellationToken: ct));
        return rows.AsList();
    }
}
