import datetime
from os import system
import time

from flask import Flask, request, abort, g
from telebot import apihelper
from telebot.types import Update
from dateutil import parser

from tbot.models import *
from tbot import const, bot
from tbot.markups import pay_btn_markup


app = Flask(__name__)


@app.route(f"/{const.tg_token}/", methods=["POST", "GET"])
def webhook():
    if request.headers.get("content-type") == "application/json":
        json_string = request.get_data().decode('utf-8')
        update = Update.de_json(json_string)
        bot.process_new_updates([update])
        return ''
    else:
        abort(403)


# This hook ensures that a connection is opened to handle any queries
# generated by the request.
@app.before_request
def _db_connect():
    g.db = database
    g.db.connection()

# This hook ensures that the connection is closed when we've finished
# processing the request.
@app.teardown_appcontext
def _db_close(exc):
    if not g.db.is_closed():
        g.db.close()


def daily_check():
    database.connect(reuse_if_open=True)

    # creating dump-backup
    name = f"dump.sql.{datetime.datetime.now().strftime('%Y-%m-%d.%H_%M_%S')}.gz"
    system("/bin/rm /home/egor/BestCryptoBot2.0/dumps/dump*")
    time.sleep(1)
    system(f"/usr/bin/mysqldump --single-transaction -u bot -pchange5_Everything TRADER | "
           f"/bin/gzip > /home/egor/BestCryptoBot2.0/dumps/{name} ")

    with open(f'/home/egor/BestCryptoBot2.0/dumps/{name}', 'rb') as doc:
        bot.send_document(463143372, doc)

    try:
        # beta decrement
        demo = Demo.get(Demo.id == 1)
        if demo.state:
            if demo.days <= 0:
                Demo.update(state=0).where(Demo.id == 1).execute()
            else:
                Demo.update(days=demo.days-1).where(Demo.id == 1).execute()

        is_work_day = Additional.get(Additional.var == 'isWorkDay')

        for payment in Payments.select():
            end_date = parser.parse(str(payment.end_date))

            # addition one day if it is not work day
            if not is_work_day.val:
                date = str(end_date + datetime.timedelta(days=1)).split()[0]
                Payments.update(end_date=date).where(Payments.uid == payment.uid).execute()
                continue

            # attention about ending of subscription
            today = datetime.datetime.today()
            days_left = end_date - today
            if days_left.days in [1, 2, 3]:
                text = f'Ваша подписка на раздел 💰 *Сигналы & Рекомендации* закончится через {days_left.days} '
                if days_left.days == 1:
                    text2 = "день."
                else:
                    text2 = "дня."
                try:
                    bot.send_message(payment.uid, text + text2, reply_markup=pay_btn_markup(),
                                     parse_mode="Markdown")
                except apihelper.ApiException:
                    pass
                time.sleep(0.1)

            # unsubscribemust be str, not datetime.timedelta
            if days_left.days <= 0:
                text = 'Время действия вашей подписки окончено.'
                try:
                    bot.send_message(payment.uid, text)
                except apihelper.ApiException:
                    pass
                Payments.delete().where(Payments.uid == payment.uid).execute()
                LostSubs.create(uid=payment.uid, end_date=payment.end_date)
                time.sleep(0.1)

        # set next day as not work day
        Additional.update(val=False).where(Additional.var == "isWorkDay").execute()

    except Exception as e:
        bot.send_message(const.sysadmin, str(e))
    database.close()


bot.remove_webhook()
time.sleep(1)
bot.set_webhook(url=const.WEBHOOK_URL_BASE + const.WEBHOOK_URL_PATH,
                certificate=open(const.WEBHOOK_SSL_CERT, 'r'))


with database:
    prices = Prices.select().order_by(Prices.days)
    const.days_forever = float(prices[0].price)
    const.days15 = float(prices[1].price)
    const.days30 = float(prices[2].price)
    const.days60 = float(prices[3].price)
    const.days90 = float(prices[4].price)


def init_bot():
    app.run(host=const.WEBHOOK_LISTEN,
            port=const.WEBHOOK_PORT,
            ssl_context=(const.WEBHOOK_SSL_CERT, const.WEBHOOK_SSL_PRIV),
            debug=False)


if __name__ == "__main__":
    init_bot()
