#-*- coding: utf-8 -*-

import traceback
from pyrogram import Client, filters, idle
from pyrogram.types import ForceReply, BotCommand, BotCommandScopeChat
from pyrogram.enums.chat_action import ChatAction
from functions import *
from modules.colors import *
from modules.bwt import *
import subprocess
import os

config = jsonLoad("config.json")

owner_id = config["owner_id"]

app = Client(config["bot_name"], api_id=config["api_id"], api_hash=config["api_hash"], bot_token=config["bot_token"])


@app.on_message(~ filters.scheduled & filters.command(["setcard", "задать карту"], prefixes=["/", ""]))
async def setcard(_, msg):
    if userGet(msg.from_user.id, "context") is None:
        userSet(msg.from_user.id, "context", "set")
        await msg.reply_text(string("send_number"), reply_markup=ForceReply(placeholder=string("enter_number")))
    else:
        await msg.reply_text(string("cancel_first"))


@app.on_message(~ filters.scheduled & filters.command(["cancel", "відміна"], prefixes=["/", ""]))
async def cancel(_, msg):
    if userGet(msg.from_user.id, "context") is not None:
        userReset(msg.from_user.id, "context")
        await msg.reply_text(string("cancel"))
    else:
        await msg.reply_text(string("cancel_none"))


@app.on_message(~ filters.scheduled & filters.command(["resetcard", "забути картку"], prefixes=["/", ""]))
async def resetcard(_, msg):
    if userGet(msg.from_user.id, "context") is None:
        if "card" in jsonLoad("data/database.json")[str(msg.from_user.id)]:
            userReset(msg.from_user.id, "card")
            await msg.reply_text(string("card_unlinked"))
            appendLog(f"User {str(msg.from_user.id)} reseted his card")
        else:
            await msg.reply_text(string("card_not_linked").format(string("get_number")))
            appendLog(f"User {str(msg.from_user.id)} tried to reset non-existent card")
    else:
        await msg.reply_text(string("cancel_first"))


@app.on_message(~ filters.scheduled & filters.command(["balance", "баланс"], prefixes=["/", ""]))
async def balance(_, msg):
    if userGet(msg.from_user.id, "context") is None:
        try:
            if "card" in jsonLoad("data/database.json")[str(msg.from_user.id)]:
                await app.send_chat_action(chat_id=msg.chat.id, action=ChatAction.TYPING)
                water_left = await getWaterLeft(userGet(msg.from_user.id, "card"), msg.from_user.id, app)
                if water_left == "":
                    raise EmptyCardException("Card information is empty")
                elif water_left == "Failure":
                    await msg.reply_text(string("error_occured").format(string("get_number")))
                    appendLog(f"User {str(msg.from_user.id)} could not get left water amount")
                else:
                    await msg.reply_text(string("card_balance").format(water_left))
                    appendLog(f"User {str(msg.from_user.id)} has {water_left} liters remaining")
            else:
                await msg.reply_text(string("card_not_linked").format(string("get_number")))
                appendLog(f"User {str(msg.from_user.id)} tried to get balance without card set")
        except Exception as exp:
            await msg.reply_text(string("error_occured").format(string("get_number")))
            await app.send_message(owner_id, f"Error occured by {str(msg.from_user.id)}:\nException: `{exp}`\nTraceback: `{traceback.format_exc()}`")
            appendLog(f"User {str(msg.from_user.id)} could not get left water amount")
    else:
        await msg.reply_text(string("cancel_first"))


@app.on_message(~ filters.scheduled & filters.command(["topup", "refill", "поповнити"], prefixes=["/", ""]))
async def topup_cmd(_, msg):
    if userGet(msg.from_user.id, "context") is None:
        try:
            if "card" in jsonLoad("data/database.json")[str(msg.from_user.id)]:
                await app.send_chat_action(chat_id=msg.chat.id, action=ChatAction.TYPING)
                await msg.reply_text(string("top_up").format(str(userGet(msg.from_user.id, "card"))))
                appendLog(f"User {str(msg.from_user.id)} requested top up")
            else:
                await msg.reply_text(string("card_not_linked").format(string("get_number")))
                appendLog(f"User {str(msg.from_user.id)} tried to request top up without card set")
        except Exception as exp:
            await msg.reply_text(exp)
    else:
        await msg.reply_text(string("cancel_first"))


@app.on_message(~ filters.scheduled & filters.command(["start", "help", "допомога"], prefixes=["/", ""]))
async def help(_, msg):
    if userGet(msg.from_user.id, "context") is None:
        await msg.reply_text(string("welcome").format(string("get_number")))
        if msg.from_user.language_code in jsonLoad("strings.json"):
            userSet(msg.from_user.id, "locale", msg.from_user.language_code)
        else:
            userSet(msg.from_user.id, "locale", "en")
    else:
        await msg.reply_text(string("cancel_first"))

pid = os.getpid()

@app.on_message(~ filters.scheduled & filters.command(["kill", "die", "shutdown"], prefixes="/"))
async def kill(_, msg):
    if msg.from_user.id == owner_id:
        await msg.reply_text(f"Shutting down bot with pid **{pid}**")
        os.system(f"kill -9 {pid}")


@app.on_message(~ filters.scheduled)
async def any_message_handler(app, msg):
    if userGet(msg.from_user.id, "context") == "set":
        userSet(msg.from_user.id, "card", msg.text)
        userReset(msg.from_user.id, "context")
        appendLog(f"User {str(msg.from_user.id)} set card id to {msg.text}")
        await msg.reply_text(string("card_linked").format(msg.text))

print(f'{nowtime()} {WHITE}Starting with PID {YELLOW}{pid}{RESET}')

app.start()
app.send_message(owner_id, f"Starting bot with pid **{pid}**")

app.set_bot_commands([
    BotCommand("help", "Меню допомоги"),
    BotCommand("balance", "Баланс картки"),
    BotCommand("topup", "Поповнити картку"),
    BotCommand("setcard", "Прив'язати картку"),
    BotCommand("resetcard", "Відв'язати картку"),
    BotCommand("cancel", "Відмінити операцію"),
    ],
    language_code="uk")

app.set_bot_commands([
    BotCommand("help", "Меню допомоги"),
    BotCommand("balance", "Баланс картки"),
    BotCommand("topup", "Поповнити картку"),
    BotCommand("setcard", "Прив'язати картку"),
    BotCommand("resetcard", "Відв'язати картку"),
    BotCommand("cancel", "Відмінити операцію"),
    ],
    language_code="ru")

app.set_bot_commands([
    BotCommand("help", "Help menu"),
    BotCommand("balance", "Card's balance"),
    BotCommand("topup", "Refill card"),
    BotCommand("setcard", "Link card"),
    BotCommand("resetcard", "Unlink card"),
    BotCommand("cancel", "Cancel operation"),
    ])

app.set_bot_commands([
    BotCommand("help", "Help menu"),
    BotCommand("balance", "Card's balance"),
    BotCommand("topup", "Refill card"),
    BotCommand("setcard", "Link card"),
    BotCommand("resetcard", "Unlink card"),
    BotCommand("shutdown", "Turn off the bot"),
    BotCommand("cancel", "Cancel operation"),
    ],
    scope=BotCommandScopeChat(chat_id=owner_id))

idle()

app.send_message(owner_id, f"Shutting down bot with pid **{pid}**")
print(f'\n{nowtime()} {WHITE}Shutting down with PID {YELLOW}{pid}{RESET}')

subprocess.call(f'kill -9 {pid}', shell=True)
