import subprocess
from typing import Optional

from alarm import BaseAlarmClock, AlarmState
from datetime import time, datetime, timezone, timedelta
from time import sleep
# from pynput import keyboard
import keyboard as kb
# SONG = ".model/Viennese_Poets.mp3"

# Simple Alarm Clock has 5 functionalities:
# 1. Set Alarm Time - Set the time for the alarm to sound, does NOT make the alarm active
# 2. Start Alarm    - Make the alarm active, which will run the timer until it reaches the specified time
# 3. Sound Alarm    - Play the sound for the alarm
# 4. Snooze Alarm   - Stop the alarm sound and wait for some time to play the alarm again
# 5. Stop Alarm     - If the alarm is active or is playing, stop the alarm (deactivate state)

# ALARM_TIME = datetime.combine(
#     datetime.today(),
#     # (datetime.today() + timedelta(days=1)).date(),
#     time(16, 40, 0)
# ).astimezone(tz=timezone.utc)
# SNOOZE_KEY = keyboard.Key.up
# ALARM_OFF_KEY = keyboard.Key.esc
SNOOZE_SEC = 5


class SimpleAlarmClock(BaseAlarmClock):
    def __init__(self, wake_time: Optional[datetime] = None):
        super().__init__(wake_time)
        # self._alarm = None

    def set_alarm(self, wake_time: datetime) -> datetime:
        print(f"SETTING ALARM to: {wake_time}")
        return super(SimpleAlarmClock, self).set_alarm(wake_time)

    def start_alarm(self) -> None:
        print("STARTING ALARM")
        super(SimpleAlarmClock, self).start_alarm()

    def sound_alarm(self) -> None:
        print("SOUNDING ALARM")
        # if not self._alarm:
        #     self._alarm = subprocess.Popen(["omxplayer", "--no-keys", SONG, "&"])
        super(SimpleAlarmClock, self).sound_alarm()

    def snooze_alarm(self) -> None:
        if self.current_state is AlarmState.PLAYING:
            print("SNOOZING ALARM")
            # print(f"{self._alarm.pid}")
            # if self._alarm is not None:
            #     subprocess.Popen(["sudo", "kill", f"{self._alarm.pid}"])
            #     self._alarm = None
            super(SimpleAlarmClock, self).snooze_alarm()
            sleep(SNOOZE_SEC)
            print("UN-SNOOZING ALARM")
            self.sound_alarm()

    def stop_alarm(self, deactivate: bool = True) -> None:
        print("STOPPING ALARM")
        # if self._alarm is not None:
        #     subprocess.Popen(["sudo", "kill", f"{self._alarm.pid}"])
        #     self._alarm = None
        if self.current_state is AlarmState.PLAYING:
            print("STOPPED PLAYING ALARM")
        super(SimpleAlarmClock, self).stop_alarm()

    def alarm_check_reached(self, current_time: datetime) -> bool:
        # print(f"{self.wake_time}")
        # print(f"{current_time}")
        return super(SimpleAlarmClock, self).alarm_check_reached(current_time)

    def run_simple_alarm_mode(self):
        self.start_alarm()
        kb.add_hotkey("esc", lambda: self.stop_alarm())
        kb.add_hotkey("space", lambda: self.snooze_alarm())
        while not self.alarm_check_reached(datetime.now(tz=timezone.utc)):
            print(f"ALARM SLEEPING @: {datetime.now(tz=timezone.utc)}")
            sleep(1)
        self.sound_alarm()
        while self.current_state is not AlarmState.DEACTIVATED:
            pass
            # with keyboard.Events() as events:
            #     for event in events:
            #         if event.key == ALARM_OFF_KEY:
            #             self.stop_alarm()
            #             break
            #         elif event.key == SNOOZE_KEY:
            #             self.snooze_alarm()
            #             break


if __name__ == '__main__':
    alarm_hour = int(input("What hour do you want the alarm to go off at? "))
    alarm_minute = int(input("What minute do you want the alarm to go off at? "))
    run_alarm_today = map(
        lambda response: response.lower() in ["y", "yes", "t", "true"],
        input("Will the alarm run today? [y/N]")
    )
    alarm_time = datetime.combine(
        datetime.today() if run_alarm_today else (datetime.today() + timedelta(days=1)).date(),
        time(alarm_hour, alarm_minute, 0)
    ).astimezone(tz=timezone.utc)
    alarm_clock = SimpleAlarmClock(alarm_time)
    alarm_clock.run_simple_alarm_mode()