using AiLogia.Bot.Handlers;
using AiLogia.Bot.Services;
using Microsoft.Extensions.Configuration;
using Telegram.Bot;
using Telegram.Bot.Types;

namespace AiLogia.Bot.Core;

public interface ICommandsRouter
{
    Task RouteMessageAsync(Message message);
    Task RouteCommandAsync(Message message);
    Task RouteCallbackAsync(CallbackQuery callbackQuery);
}

public class CommandsRouter(
    IConfiguration config,
    ITelegramBotClient bot,
    ISystemLogService log,
    IEnumerable<ICommandHandler> commandHandlers, IEnumerable<ICallbackHandler> callbackHandlers, IEnumerable<IMessageHandler> messageHandlers) : ICommandsRouter
{
    private readonly ITelegramBotClient _bot = bot;
    private readonly ISystemLogService _log = log;
    private readonly IEnumerable<ICommandHandler> _commandHandlers = commandHandlers;
    private readonly IEnumerable<ICallbackHandler> _callbackHandlers = callbackHandlers;
    private readonly IEnumerable<IMessageHandler> _messageHandlers = messageHandlers;

    public async Task RouteMessageAsync(Message message)
    {
        //   if (string.IsNullOrWhiteSpace(message.Text))
        //       return;

        //   foreach (var handler in _messageHandlers)
        //   {
        //       await handler.HandleAsync(message);
        //   }

        // Не фильтруем по Text — нам нужны и медиа без подписи
        foreach (var handler in _messageHandlers)
        {
            try
            {
                if (handler is ICanHandle can && !can.CanHandle(message))
                    continue;

                await handler.HandleAsync(message);
                return; // первый, кто взял — обработал
            }
            catch (Exception ex)
            {
                await _log.ExceptionAsync(ex, $"Handler {handler} failed" );
            }
        }
    }

    private static string ExplainCommand(Message message)
    {
        var arr = message.Text?.Split(' ', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);

        if (arr == null || arr.Length < 1) return String.Empty;

        var command = arr[0];

        if (command == "/start")
        {
            if (arr.Length == 2)
            {
                var secondary = arr[1].ToLowerInvariant();

                switch (secondary)
                {
                    case "auth": return "/" + secondary;
                    default: break;
                }
           }
        }

        return command;
    }

    public async Task RouteCommandAsync(Message message)
    {
        var command = ExplainCommand(message);
        var chatId = message.Chat.Id;
        var user = message.From;

        await _log.InfoAsync($"Command received: {command}", new
        {
            chatId,
            userId = user?.Id,
            username = user?.Username,
            fullName = $"{user?.FirstName} {user?.LastName}"
        });

        var handler = _commandHandlers.FirstOrDefault(h => h.Command == command);

        if (handler != null)
        {
            await handler.HandleAsync(message);
        }
        else
        {
            await _bot.SendMessage(
                chatId: chatId,
                text: "🤷 Неизвестная команда."
            );
        }
    }

    public async Task RouteCallbackAsync(CallbackQuery callbackQuery)
    {
        var chatId = callbackQuery.Message?.Chat.Id ?? callbackQuery.From.Id;

        await _log.InfoAsync("Received callback", new
        {
            callbackQuery.Id,
            callbackQuery.Data,
            user = callbackQuery.From?.Username
        });

        var handler = _callbackHandlers.FirstOrDefault(h => h.CanHandle(callbackQuery.Data ?? ""));
        if (handler != null)
        {
            await handler.HandleAsync(callbackQuery);
        }
        else
        {
            await _bot.AnswerCallbackQuery(
                callbackQueryId: callbackQuery.Id,
                text: "🔧 Нераспознанное действие.",
                showAlert: false
            );
        }
    }
}
