import os
import logging
import logging.config
from functools import partial
from dotenv import load_dotenv
from telegram import Bot, ReplyKeyboardMarkup, ReplyKeyboardRemove
from telegram.ext import (Updater, CommandHandler, MessageHandler,
                          RegexHandler, ConversationHandler, Filters)
from redis import Redis

from tg_logging import create_logger
from quiz_tools import get_question_and_answer, format_answer, format_question


QUESTION, ATTEMPT = range(2)


def main():
    class LoggerTelegramBot(logging.Handler):
        def emit(self, record):
            log_entry = self.format(record)
            bot.send_message(chat_id=chat_id_tg_admin, text=log_entry)

    dictLogConfig = {
        'version': 1,
        'handlers': {
            'handler': {
                '()': LoggerTelegramBot,
                'formatter': 'formatter'
                }
        },
        'loggers': {
            'tg_logger': {
                'handlers': ['handler'],
                'level': 'INFO'
            }
        },
        'formatters': {
            'formatter': {
                'format': '%(asctime)s - %(levelname)s - %(message)s'
            }
        }
    }

    load_dotenv()
    chat_id_tg_admin = os.getenv('CHAT_ID_TG_ADMIN')
    bot = Bot(token=os.getenv('TOKEN_TG'))
    logging.config.dictConfig(dictLogConfig)
    logger = logging.getLogger('tg_logger')
    handler = LoggerTelegramBot()
    logger.addHandler(handler)
    rediser = Redis(
                host=os.getenv('REDIS_HOST'),
                port=os.getenv('REDIS_PORT'),
                db=0,
                password=os.getenv('REDIS_PWD'))
    updater = Updater(token_tg)
    dp = updater.dispatcher
    logger.info(dp)
    conv_handler = ConversationHandler(
        entry_points=[CommandHandler('start', start)],
        states={
            QUESTION: [
                RegexHandler('^Выход$', do_exit),
                MessageHandler(Filters.text, partial(handle_new_question, rediser))],
            ATTEMPT: [
                RegexHandler('^Выход$', do_exit),
                RegexHandler('^(Новый вопрос|Другой вопрос)$', partial(handle_new_question, rediser)),
                RegexHandler('^Показать ответ$', partial(display_answer, rediser)),
                MessageHandler(Filters.text, partial(handle_attempt, rediser))],
        },
        fallbacks=[CommandHandler('cancel', do_exit)]
    )
    dp.add_handler(conv_handler)
    updater.start_polling()
    updater.idle()


def do_reply(update, text, keyboard=None):
    if keyboard is None:
        markup = ReplyKeyboardRemove()
        return update.message.reply_text(text, reply_markup=markup)
    markup = ReplyKeyboardMarkup(keyboard, resize_keyboard=True)
    return update.message.reply_text(text, reply_markup=markup)


def start(bot, update):
    do_reply(update, 'Привет знатоку в чате-викторине! Начинаем?', [['Да!']])
    return QUESTION


def handle_new_question(rediser, bot, update):
    new_question, new_answer = get_question_and_answer()
    chat_id = update.message.chat_id
    rediser.set(chat_id, new_answer)
    do_reply(update, format_question(new_question))
    return ATTEMPT


def display_answer(rediser, bot, update):
    chat_id = update.message.chat_id
    answer = rediser.get(chat_id).decode()
    do_reply(update, answer, [['Новый вопрос', 'Выход']])
    return QUESTION


def handle_attempt(rediser, bot, update):
    chat_id = update.message.chat_id
    attempt = update.message.text.strip().lower()
    answer = rediser.get(chat_id).decode()
    if attempt == format_answer(answer):
        text = 'Правильно! \n\n {}'.format(answer)
        reply_keyboard = [['Новый вопрос', 'Выход']]
    else:
        text = 'Неверно! Попробуйте еще раз.'
        reply_keyboard = [['Показать ответ', 'Другой вопрос', 'Выход']]
    do_reply(update, text, reply_keyboard)
    return ATTEMPT


def do_exit(bot, update):
    text = 'До скорой встречи! Желаете начать заново? Жмите /start'
    do_reply(update, text)
    return ConversationHandler.END


if __name__ == '__main__':
    main()

[((1196, 1209), 'dotenv.load_dotenv', 'load_dotenv', ([], {}), '()\n', (1207, 1209), False, 'from dotenv import load_dotenv\n'), ((1233, 1262), 'os.getenv', 'os.getenv', (['"""CHAT_ID_TG_ADMIN"""'], {}), "('CHAT_ID_TG_ADMIN')\n", (1242, 1262), False, 'import os\n'), ((1310, 1350), 'logging.config.dictConfig', 'logging.config.dictConfig', (['dictLogConfig'], {}), '(dictLogConfig)\n', (1335, 1350), False, 'import logging\n'), ((1364, 1394), 'logging.getLogger', 'logging.getLogger', (['"""tg_logger"""'], {}), "('tg_logger')\n", (1381, 1394), False, 'import logging\n'), ((1658, 1675), 'telegram.ext.Updater', 'Updater', (['token_tg'], {}), '(token_tg)\n', (1665, 1675), False, 'from telegram.ext import Updater, CommandHandler, MessageHandler, RegexHandler, ConversationHandler, Filters\n'), ((2678, 2729), 'telegram.ReplyKeyboardMarkup', 'ReplyKeyboardMarkup', (['keyboard'], {'resize_keyboard': '(True)'}), '(keyboard, resize_keyboard=True)\n', (2697, 2729), False, 'from telegram import Bot, ReplyKeyboardMarkup, ReplyKeyboardRemove\n'), ((2998, 3023), 'quiz_tools.get_question_and_answer', 'get_question_and_answer', ([], {}), '()\n', (3021, 3023), False, 'from quiz_tools import get_question_and_answer, format_answer, format_question\n'), ((2575, 2596), 'telegram.ReplyKeyboardRemove', 'ReplyKeyboardRemove', ([], {}), '()\n', (2594, 2596), False, 'from telegram import Bot, ReplyKeyboardMarkup, ReplyKeyboardRemove\n'), ((3119, 3148), 'quiz_tools.format_question', 'format_question', (['new_question'], {}), '(new_question)\n', (3134, 3148), False, 'from quiz_tools import get_question_and_answer, format_answer, format_question\n'), ((3563, 3584), 'quiz_tools.format_answer', 'format_answer', (['answer'], {}), '(answer)\n', (3576, 3584), False, 'from quiz_tools import get_question_and_answer, format_answer, format_question\n'), ((1283, 1304), 'os.getenv', 'os.getenv', (['"""TOKEN_TG"""'], {}), "('TOKEN_TG')\n", (1292, 1304), False, 'import os\n'), ((1502, 1525), 'os.getenv', 'os.getenv', (['"""REDIS_HOST"""'], {}), "('REDIS_HOST')\n", (1511, 1525), False, 'import os\n'), ((1548, 1571), 'os.getenv', 'os.getenv', (['"""REDIS_PORT"""'], {}), "('REDIS_PORT')\n", (1557, 1571), False, 'import os\n'), ((1620, 1642), 'os.getenv', 'os.getenv', (['"""REDIS_PWD"""'], {}), "('REDIS_PWD')\n", (1629, 1642), False, 'import os\n'), ((1786, 1816), 'telegram.ext.CommandHandler', 'CommandHandler', (['"""start"""', 'start'], {}), "('start', start)\n", (1800, 1816), False, 'from telegram.ext import Updater, CommandHandler, MessageHandler, RegexHandler, ConversationHandler, Filters\n'), ((2367, 2400), 'telegram.ext.CommandHandler', 'CommandHandler', (['"""cancel"""', 'do_exit'], {}), "('cancel', do_exit)\n", (2381, 2400), False, 'from telegram.ext import Updater, CommandHandler, MessageHandler, RegexHandler, ConversationHandler, Filters\n'), ((1876, 1908), 'telegram.ext.RegexHandler', 'RegexHandler', (['"""^Выход$"""', 'do_exit'], {}), "('^Выход$', do_exit)\n", (1888, 1908), False, 'from telegram.ext import Updater, CommandHandler, MessageHandler, RegexHandler, ConversationHandler, Filters\n'), ((2035, 2067), 'telegram.ext.RegexHandler', 'RegexHandler', (['"""^Выход$"""', 'do_exit'], {}), "('^Выход$', do_exit)\n", (2047, 2067), False, 'from telegram.ext import Updater, CommandHandler, MessageHandler, RegexHandler, ConversationHandler, Filters\n'), ((1955, 1992), 'functools.partial', 'partial', (['handle_new_question', 'rediser'], {}), '(handle_new_question, rediser)\n', (1962, 1992), False, 'from functools import partial\n'), ((2155, 2192), 'functools.partial', 'partial', (['handle_new_question', 'rediser'], {}), '(handle_new_question, rediser)\n', (2162, 2192), False, 'from functools import partial\n'), ((2234, 2266), 'functools.partial', 'partial', (['display_answer', 'rediser'], {}), '(display_answer, rediser)\n', (2241, 2266), False, 'from functools import partial\n'), ((2301, 2333), 'functools.partial', 'partial', (['handle_attempt', 'rediser'], {}), '(handle_attempt, rediser)\n', (2308, 2333), False, 'from functools import partial\n')]