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:
    """
    Обновляет список звонков для фоновой службы
    """
    schedules = AllSchedules()
    all_groups_of_calls = AllGroupsOfCalls()
    all_calls = dict()
    print('updating all calls')
    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] != '-':
                        all_calls[current_schedule_object.lessons[lesson][lesson_event]] = {
                            "schedule_name": schedule_name,
                            "lesson_number": lesson,
                            "type": lesson_event,
                            "sound": all_groups_of_calls.groups[group][lesson_event]
                        }
                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[time_of_pre_call] = {
                        "schedule_name": schedule_name,
                        "lesson_number": lesson,
                        "type": "start",
                        "sound": all_groups_of_calls.groups[group]["pre"]
                    }
    # print(all_calls)
    if '-' in all_calls:
        all_calls.pop('-')
    return all_calls


def schedule_all_calls(all_calls_dict: object, function=ring_the_call) -> list:
    """
    Планирует звонки по указанному расписанию
    """
    schedules = AllSchedules()
    schedule.clear()
    allCalls = all_calls_dict
    allTimes = list(all_calls_dict.keys())
    allTimes.sort(key=time_string_to_minute)
    for time in allTimes:
        current_schedule = allCalls[time]["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[time]["sound"],
                                                play_music=psble if all_calls_dict[time]["type"] == "end" else False)
        if current_weekdays["tuesday"] is True:
            schedule.every().tuesday.at(time).do(function, filename=all_calls_dict[time]["sound"],
                                                 play_music=psble if all_calls_dict[time]["type"] == "end" else False)
        if current_weekdays["wednesday"] is True:
            schedule.every().wednesday.at(time).do(function, filename=all_calls_dict[time]["sound"],
                                                   play_music=psble if all_calls_dict[time]["type"] == "end" else False)
        if current_weekdays["thursday"] is True:
            schedule.every().thursday.at(time).do(function, filename=all_calls_dict[time]["sound"],
                                                  play_music=psble if all_calls_dict[time]["type"] == "end" else False)
        if current_weekdays["friday"] is True:
            schedule.every().friday.at(time).do(function, filename=all_calls_dict[time]["sound"],
                                                play_music=psble if all_calls_dict[time]["type"] == "end" else False)
        if current_weekdays["saturday"] is True:
            schedule.every().saturday.at(time).do(function, filename=all_calls_dict[time]["sound"],
                                                  play_music=psble if all_calls_dict[time]["type"] == "end" else False)
        if current_weekdays["sunday"] is True:
            schedule.every().sunday.at(time).do(function, filename=all_calls_dict[time]["sound"],
                                                play_music=psble if all_calls_dict[time]["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: list[schedule.Job]
    @return: schedule.next_run or None if error
    """
    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: schedule.next_run
    @return: str
    """
    # FIXME используется только для лога, чтобы описать первый звонок. Это точно необходимо?
    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}'
