from . import command
from .inline_keyboard_utils import generate_keyboard
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
import traceback
import math
import logging

logger = logging.getLogger('help')

def get_help_overview(bea):
    text = "Welcome to the Bea help overview. To find help for a command, please click the section you're interested in."
    try:
        modules = {cmd.__module__.split('.')[1] for cmd in bea.commands if 'lambda' not in cmd.__name__}
    except:
        traceback.print_exc()
        return ("Unable to generate Bea's help overview right now.", None)

    modules = sorted(modules)
    callback_datas = [f"h;m:{module}" for module in modules]
    modules = [m.title() for m in modules]
    return (text, InlineKeyboardMarkup(generate_keyboard(modules, callback_datas)))

def get_module_help(bea, data):
    module_name, *rest = data[2:].split(',')
    cmds = {cmd.__name__ for cmd in bea.commands if 'lambda' not in cmd.__name__ and cmd.__module__ == f'modules.{module_name}'}
    cmds = sorted(cmds, reverse=True)

    callback_datas = [f"h;c:{cname},m:{module_name}" for cname in cmds]

    markup = generate_keyboard(cmds, callback_datas)
    cb_data = ','.join(rest)
    logger.info(f"Callback data: {cb_data!r}")
    markup.insert(0, [InlineKeyboardButton("« Go back", callback_data='h;overview')])

    text = f"Here are the commands in section {module_name}."
    return (text, InlineKeyboardMarkup(markup))

def get_cmd_help(bea, data):
    name, *rest = data[2:].split(',')

    cmd = [c for c in bea.commands if c.__name__ == name]
    if not cmd:
        return update.message.reply_text(f"Command {name!r} not found.")
    cmd = cmd[0]

    output = []

    if hasattr(cmd, '_regex'):
        output.append(f"It has match regex `{cmd._regex}`.")

    if getattr(cmd, '_requiresauth', False):
        output.append("This command requires authorization (see also: showtags).")

    if cmd.__doc__ is not None:
        doc = '\n'.join([l.strip() for l in cmd.__doc__.split('\n')])
        output.append(f"It has the following documentation:\n\n{doc.strip()}")

    if not output:
        text = "That command doesn't have any help information."

    text = '\n'.join(output)
    markup = [[InlineKeyboardButton("« Go back", callback_data='h;'+','.join(rest))]]

    return (text, InlineKeyboardMarkup(markup))

def update_help(bea, bot, update):
    query = update.callback_query

    assert query.data.startswith('h;')
    data = query.data[2:]
    if data.startswith('m'):
        # the user selected a module.
        (text, markup) = get_module_help(bea, data)
        query.edit_message_text(text=text, reply_markup=markup)
    elif data.startswith('c'):
        # the user selected a command.
        (text, markup) = get_cmd_help(bea, data)
        query.edit_message_text(text=text, reply_markup=markup, parse_mode='Markdown')
    elif data == 'overview':
        (text, markup) = get_help_overview(bea)
        query.edit_message_text(text=text, reply_markup=markup)


@command('help')
def help(bea, bot, update):
    """
    Get help on Bea's commands. But you probably already knew that.
    """
    (text, markup) = get_help_overview(bea)
    msg = bea.reply(text, reply_markup=markup, quote=False)

def init(bea, config):
    bea.callback_handler['h'] = update_help
    return [help]
