import logging

import schedule

from school_ringer_modules.groups_dataclasses import AllGroupsOfCalls
from school_ringer_modules.schedules_dataclasses import AllSchedules
from school_ringer_modules.sound import ring_the_call
from school_ringer_modules.time_functions import time_before, time_string_to_minute


def update_all_calls() -> dict:
    """
    Обновляет список звонков для фоновой службы
    @return: словарь всех запланированных звонков с временами в качестве ключей
    """
    schedules = AllSchedules()
    all_groups_of_calls = AllGroupsOfCalls()
    all_calls = dict()
    print('updating all calls')
    number = 1
    for schedule_name in schedules.schedules:
        current_schedule_object = schedules.__getitem__(schedule_name)
        if current_schedule_object.active is True:
            for lesson in current_schedule_object.lessons:
                group = current_schedule_object.lessons[lesson]["group"]
                for lesson_event in ("start", "end"):
                    if current_schedule_object.lessons[lesson][lesson_event] != '-':
                        time = current_schedule_object.lessons[lesson][lesson_event]
                        all_calls[number] = {
                            "time": time,
                            "schedule_name": schedule_name,
                            "lesson_number": lesson,
                            "type": lesson_event,
                            "sound": all_groups_of_calls.groups[group][lesson_event]
                        }
                        number += 1
                if current_schedule_object.pre_call > 0:
                    time_of_pre_call = time_before(current_schedule_object.lessons[lesson]["start"],
                                                   current_schedule_object.pre_call)
                    all_calls[number] = {
                        "time": time_of_pre_call,
                        "schedule_name": schedule_name,
                        "lesson_number": lesson,
                        "type": "start",
                        "sound": all_groups_of_calls.groups[group]["pre"]
                    }
                    number += 1
    # print(all_calls)
    calls_with_minuses_numbers = []
    for number in all_calls:
        if all_calls[number]["time"] == '-':
            calls_with_minuses_numbers.append(number)

    for number in calls_with_minuses_numbers:
        all_calls.pop(number)
    return all_calls


def schedule_all_calls(all_calls_dict: dict, function=ring_the_call) -> list:
    """
    Планирует звонки по указанному расписанию
    @param all_calls_dict: словарь всех запланированных звонков
    @param function: функция, которая должна вызываться по расписанию (по умолчанию - вызов звонка)
    @return: список запланированных заданий в формате модуля schedule
    """
    schedules = AllSchedules()
    schedule.clear()
    allCalls = all_calls_dict
    allTimes = [allCalls[call]["time"] for call in allCalls.keys()]
    allTimes.sort(key=time_string_to_minute)
    for number in allCalls.keys():
        time = allCalls[number]["time"]
        current_schedule = allCalls[number]["schedule_name"]
        current_weekdays = schedules.schedules[current_schedule]["weekdays"]
        psble = True if allTimes.index(time) != len(allTimes) - 1 else False
        if current_weekdays["monday"] is True:
            schedule.every().monday.at(time).do(function, filename=all_calls_dict[number]["sound"],
                                                play_music=psble if all_calls_dict[number]["type"] == "end" else False)
        if current_weekdays["tuesday"] is True:
            schedule.every().tuesday.at(time).do(function, filename=all_calls_dict[number]["sound"],
                                                 play_music=psble if all_calls_dict[number]["type"] == "end" else False)
        if current_weekdays["wednesday"] is True:
            schedule.every().wednesday.at(time).do(function, filename=all_calls_dict[number]["sound"],
                                                   play_music=psble if all_calls_dict[number]["type"] == "end" else False)
        if current_weekdays["thursday"] is True:
            schedule.every().thursday.at(time).do(function, filename=all_calls_dict[number]["sound"],
                                                  play_music=psble if all_calls_dict[number]["type"] == "end" else False)
        if current_weekdays["friday"] is True:
            schedule.every().friday.at(time).do(function, filename=all_calls_dict[number]["sound"],
                                                play_music=psble if all_calls_dict[number]["type"] == "end" else False)
        if current_weekdays["saturday"] is True:
            schedule.every().saturday.at(time).do(function, filename=all_calls_dict[number]["sound"],
                                                  play_music=psble if all_calls_dict[number]["type"] == "end" else False)
        if current_weekdays["sunday"] is True:
            schedule.every().sunday.at(time).do(function, filename=all_calls_dict[number]["sound"],
                                                play_music=psble if all_calls_dict[number]["type"] == "end" else False)
    print(schedule.get_jobs())
    return schedule.get_jobs()


def get_time_of_next_call(all_jobs: list) -> schedule.next_run:
    """
    Возвращает время следующего звонка или None, если они не запланированы
    @param all_jobs: список запланированных заданий в формате модуля schedule
    @return: объект next_run в формате модуля schedule или None, если звонки не запланированы
    """
    all_jobs.sort(key=lambda x: x.next_run)
    try:
        return all_jobs[0].next_run
    except IndexError:
        logging.info("Звонки не запланированы.")
        return None

# def get_info_about_next_call(next_call: schedule.next_run) -> str:
#     """
#     Возвращает информацию о ближайшем звонке в текстовом виде
#     @param next_call: объект next_run в формате модуля schedule
#     @return: строка с назначением (на урок/с урока), номером урока и временем ближайшего звонка
#     """
#     allCalls = update_all_calls()
#     all_jobs = schedule_all_calls(allCalls)
#     schedule.run_pending()
#     next_time = str(next_call).split()[1].rsplit(':', 1)[0]
#     lesson = allCalls[next_time]['lesson_number']
#     type = allCalls[next_time]['type']
#     schedule_name = allCalls[next_time]['schedule_name']
#     if type == 'start':
#         purpose = 'на урок'
#     else:
#         purpose = 'с урока'
#     return f'{purpose} № {lesson} расписания {schedule_name}'
