# pylint: disable=undefined-variable
import logging


from telegram import Update
from telegram.ext import CallbackContext
from telegram.chataction import ChatAction
from telegram.message import ParseMode
from telegram.inline.inlinequeryresultarticle import InlineQueryResultArticle
from telegram.inline.inputtextmessagecontent import InputTextMessageContent

from telegram.ext.dispatcher import run_async

from utils import validUrl, name_and_id, update_object_type, players
from replies import error, info, reply_markup
from db import data
logging.basicConfig(
                    handlers=(
                              logging.FileHandler('command_logs.log'),
                              logging.StreamHandler()),
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    level=logging.INFO)

welcome_text = ("Minecraft Server Status Bot\n"
"\n"
"To check players online on the server use @msmpbot in the text input line in any Telegram chat.\n"
"\n"
"Commands:\n"
"/status - Server info\n"
"/players - Online players on the server\n"
"\n"
"To change the monitored server send me its address.")

# ==========================
# Inline Query Handler
# ==========================

def inline_status(update: Update, context: CallbackContext):
    address = context.user_data['url']

    q = list()

    q.append(InlineQueryResultArticle(
        id='1', title=_('Address: ') + address,
        input_message_content=InputTextMessageContent(
        message_text=_('Address: ') + address))
        )

    online, str_players = players(address, True)

    text = ngettext('{0} player online', '{0} players online', online).format(online)

    q.append(InlineQueryResultArticle(
        id='2', title=text,
        description=str_players,
        input_message_content=InputTextMessageContent(
        message_text=text if online == 0 else text + ': ' + str_players)))

    update.inline_query.answer(q, cache_time=60)
    logging.info("inline answer sent")
    


# ==========================
# Message Handler
# ==========================

def message(update: Update, context: CallbackContext):
    """Usage: <IP-address> """
    user_data = context.user_data
    
    if not update.message.text: return
        
    text = update.message.text.lower()
    if text == ("ru" or "en"):
        user_data['lang'] = text
        return

    if text != 'default':
        if not validUrl(text):
            logging.info("Invalid URL, too long")
            return

    data(update.effective_user.id, text)

    user_data['url'] = data(update.effective_user.id)

    update.message.reply_chat_action(ChatAction.TYPING)
    update.message.reply_text(_('Server addess changed to ') + user_data['url'], ParseMode.MARKDOWN)


# ==========================
# Commands
# ==========================

def cmd_start(update: Update, context: CallbackContext):
    """Usage: /start"""
    message = update.message
    message.reply_chat_action(ChatAction.TYPING)
    message.reply_text(_(welcome_text), ParseMode.MARKDOWN)


def cmd_status(update: Update, context: CallbackContext):
    """Usage: /status url"""
    update.message.reply_chat_action(ChatAction.TYPING)

    url = context.user_data['url']

    update.message.reply_text(
        text=info.status(url),
        reply_markup=reply_markup(),
        parse_mode=ParseMode.MARKDOWN)

    logging.info("/status %s online" % url)


def cmd_players(update: Update, context: CallbackContext):
    """Usage: /players url"""
    update.message.reply_chat_action(ChatAction.TYPING)

    url = context.user_data['url']

    update.message.reply_text(
        text=info.players(url),
        reply_markup=reply_markup(),
        parse_mode=ParseMode.MARKDOWN)

    logging.info("/players %s online" % url)


# ==========================
# CallBacks
# ==========================

def cb_status(update: Update, context: CallbackContext):
    update.callback_query.message.edit_text(
        text=info.status(context.user_data['url']),
        reply_markup=reply_markup(),
        parse_mode=ParseMode.MARKDOWN
    )


def cb_players(update: Update, context: CallbackContext):
    update.callback_query.message.edit_text(
        text=info.players(context.user_data['url']),
        reply_markup=reply_markup(),
        parse_mode=ParseMode.MARKDOWN
    )
    update.callback_query.edit_message_text

    
def cb_about(update: Update, context: CallbackContext):
    update.callback_query.message.edit_text(
        text=_(welcome_text),
        reply_markup=reply_markup(),
        parse_mode=ParseMode.MARKDOWN
    )

# ==========================
# Before all handlers
# ==========================

from os import getenv
import gettext
domain = getenv("HEROKU_APP_NAME")
lang_code = None

def check_database(update : Update, context: CallbackContext):
    user_data = context.user_data

    try:
        user_data['url']

    except KeyError:
        user_data['url'] = data(update.effective_user.id)
        
        global lang_code
        lc = update.effective_user.language_code
        
        user_data['lang'] = (
            lc 
            if lc and gettext.find(domain, "locale", [lc])
            else 'en'
        )
    
    if lang_code != user_data['lang']:
        lang_code = user_data['lang']
        
        lang = gettext.translation(domain, "locale", [lang_code])
        lang.install(['ngettext'])

    logging.info(update_object_type(update).__class__.__name__ + " recieved from " + name_and_id(update.effective_user))
    
# ==========================
# Error handler
# ==========================

from socket import timeout as TimeoutError
from telegram.error import BadRequest

def error_handler(update : Update, context : CallbackContext):
    if type(context.error) is TimeoutError:
        logging.error("Timeout error")
    else:
        logging.exception(context.error)

        if type(context.error) is BadRequest: return

    if update.inline_query:
        error.inline(context.bot, update.inline_query.id)
    elif update.message:
        error.message(context.bot, update.message.chat_id, context.user_data['url'])
    elif update.callback_query:
        error.callback(context.bot, update.callback_query.message, context.user_data['url'])
