# раскомментировать, когда перейдем на разные пароли
import hashlib
import threading
import time
from datetime import datetime

import requests

import config
# test
import jsonAndRequest as jsreq
from BotClass import JabberBot

global tasklist


def log_handler():
    while True:
        with open('log.txt', 'a') as log_file:
            log_file.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - Function is still running...\n")
        time.sleep(3600)


botname = "open_service_request_booked"

operating_status = '211'
JID = botname + "@" + config.JSERVER
PORT = config.PORT

PASSWORD = hashlib.md5((botname + config.PASSWORD).encode('utf-8')).hexdigest()

print(JID, PASSWORD)

# таким образом хранится список jid, от которых можно получать сообщения этому боту
listen_to = ["799999999990@ej.sharix-app.org"]

# тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
proceed_to = ["open_service_request_assigned@ej.sharix-app.org", "open_service_request_pending@ej.sharix-app.org",
              "open_service_request_forcemajeure@ej.sharix-app.org"]

# максимальное значение попыток обработать заказ
idle_value = 10


def log_handler():
    while True:
        with open(f'{botname}.txt', 'a') as log_file:
            log_file.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - {botname} is still running...\n")
        time.sleep(3600)


# обработчик входящих сообщений
def message_handler(conn, mess):
    text = mess.getBody()  # текст сообщения боту
    user = mess.getFrom()  # отправитель сообщения
    if (str(user).split("/")[0]) in listen_to:
        # print (str(user).split("/")[0])
        if text is not None:
            try:
                orderObj = jsreq.jsonToOrder(text)
                tasklist.append(orderObj)
                bot.bot_log(str(datetime.now()) + " Поступивший заказ успешно добавлен в очередь обработки\n")
            except:
                bot.proceed_status(proceed_to[-1], text)
                bot.bot_log(
                    botname + " " + str(datetime.now()) + " " + "Заказ успешно обработан и отправлен на assigned\n")


def open_service_request_booked_wait(period, localtask):
    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ ожидает\n")
    time.sleep(period)
    # ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
    localtask.title = localtask.title + "1"

    # обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
    bot.proceed_status(proceed_to[0], localtask)
    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ подождал и возвращен в очередь\n")


def open_service_request_booked_process(localtask):
    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")

    if not localtask.provider:
        answer, provider, service = set_provider(localtask.id)
        # localtask.service =service.id
        localtask.service = service['id']
        if set_provider(localtask.id):
            bot.bot_log(botname + " " + str(datetime.now()) + " " + "Водитель успешно установлен\n")
        else:
            bot.bot_log(botname + " " + str(datetime.now()) + " " + "'Ошибка водитель не был установлен'\n")
        localtask.provider = provider
    current_time = datetime.now()

    # if localtask.asap or (current_time - datetime.fromisoformat(localtask.time_start_predicted) < timedelta(hours=3)):
    if localtask.asap:
        localtask.status = '212'
        print(jsreq.change_to_task(localtask, token))
        bot.proceed_status(proceed_to[0], localtask)
        bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ успешно обработан и отправлен на assigned\n")
    else:
        localtask.status = '220'
        print(jsreq.change_to_task(localtask, token))
        bot.proceed_status(proceed_to[1], localtask)
        bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ успешно обработан и отправлен на pending\n")

        # Проверка срочности заказа
        # if order.asap:
        #     #Заглушка назначение исполнителя системой
        #     if set_provider(order.ticket, order.provider) == "success":
        #         bot.proceed_status(proceed_to[0], localtask)
        #     else:
        #         bot.bot_log(botname+" "+str(datetime.now())+" "+"Ошибка назначения исполнителя\n")
        # else:
        #         localtask.status = 220
        #         bot.proceed_status(proceed_to[0], localtask)
        #         print(localtask)
        # bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ успешно обработан и отправлен на assigned\n")
        # Проверка срочности заказа


def get_balance(client):
    headers = {'Authorization': f'Token {token}'}
    # Передаем id пользователя и получаем его баланс
    response = requests.get(config.API_URL + f"/api/example/{client}", headers=headers)
    print(response.json())
    ordertext = response.json()

    if not ordertext:
        print("Empty array")
    else:
        print(ordertext[0], "PROCESSING")
        try:
            balance = ordertext[0].get('balance')
            return balance
        except Exception as ex:
            print(ex)


# set provider?
def choose_provider(auth_token, geo):
    providers = requests.get(config.API_URL + "/dbsynce/api/provider/", headers=auth_token)
    provider = providers.json()[0]['id']
    return provider


def set_provider(localtask_id):
    token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL + "my/api/v1/auth/token/login/")
    headers = {'Authorization': f'Token {token}'}
    provider = choose_provider(headers, 'geoposition')
    # NOTE:BUG:ERROR:FIXME: модель сервис не должна была содержать поле id_provider
    # service = requests.get(config.API_URL+f"/dbsynce/api/service/?id_provider={provider}", headers=headers)
    service = service.json()[0]
    data = {'provider': int(provider)}
    # print(data)
    # print(str(config.API_URL+f"/dbsynce/api/orders/{localtask_id}/"))
    response = requests.patch(config.API_URL + f"/dbsynce/api/orders/{localtask_id}/", headers=headers, json=data)
    return response, provider, service

    # if not ordertext:
    #     print("Empty array")
    # else:
    #     print(ordertext[0], "PROCESSING")
    #     try:
    #         message = ordertext[0].get('message')
    #         return message
    #     except Exception as ex:
    #         print(ex)


def open_service_request_booked():
    log_thread = threading.Thread(target=log_handler)
    log_thread.daemon = True
    log_thread.start()

    while (len(tasklist)):
        localtask = tasklist.pop(0)
        if (str(localtask.status) != str(operating_status)):
            # bot.proceed_status(proceed_to[-1],localtask) #временная проверка отправки
            print(localtask)
            localtask.status = '239'
            jsreq.change_to_task(localtask, token)
            bot.proceed_status(proceed_to[-1], localtask)
            bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ не по адресу, перенаправляем на форсмажор\n")
            continue
        else:
            bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " " + "Заказ в очереди на обработке\n")
            t1 = threading.Thread(target=open_service_request_booked_process, args=([localtask]))
            t1.start()
        # elif (localtask.provider==T):
        #     t1=threading.Thread(target=open_service_request_booked_wait, args=(5,localtask))
        #     t1.start()

        # if (localtask.title=="101"):
        #     t1=threading.Thread(target=open_service_request_booked_process, args=(10,localtask))
        #     t1.start()

        # если никакие обработчики не подошли - отправляем обратно в очередь
        # bot.proceed_status(proceed_to[0],localtask)
        # print("Заказ возвращен в очередь\n")
        # print(tasklist)


# Авторизация и запуск бота

# пустой список заказов
tasklist = []

# #надо инициализировать tasklist при запуске из API
token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL + "my/api/v1/auth/token/login/")
# #ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
tasklist_dbsynce = jsreq.requestGetList(token,
                                        config.API_URL + "/dbsynce/api/orders/")  ###Должна быть проверка между двумя

# # print (len(tasklist))

bot = JabberBot(JID, PASSWORD, PORT)

bot.register_handler('message', message_handler)
bot.start(open_service_request_booked)

# print(set_provider('localtask'))
