import os
import threading
import time
import smbus
from text_to_audio import TextToAudio
from gif_player import GifPlayer
from oled_display import OLEDDisplay
from audio_to_text import AudioToText
from arduino_comm import ArduinoI2C
import random

# Paths
timegif = "YOUR_GIF_LOCATION.GIF"
blackscreen = "YOUR_IMAGE_LOCATION.GIF"
hydgif = "YOUR_GIF_LOCATION.GIF"
playimg = "YOUR_IMAGE_LOCATION.GIF"


# Init
speaker = TextToAudio()
gif_player = GifPlayer()
oled = OLEDDisplay()
arduino = ArduinoI2C()

hydration_reminder_active = False
hydration_thread = None
play_mode_active = False
songs = []

def bcd_to_dec(bcd):
    return (bcd // 16) * 10 + (bcd % 16)

def read_time_from_rtc():
    bus = smbus.SMBus(1)
    address = 0x68
    try:
        data = bus.read_i2c_block_data(address, 0x00, 7)
        seconds = bcd_to_dec(data[0] & 0x7F)
        minutes = bcd_to_dec(data[1])
        hours = bcd_to_dec(data[2] & 0x3F)
        return f"The time is {hours:02}:{minutes:02}:{seconds:02}"
    except Exception as e:
        return f"Error reading time: {e}"

def hydration_reminder_loop(interval):
    global hydration_reminder_active
    while hydration_reminder_active:
        time.sleep(interval * 60)
        if hydration_reminder_active:
            gif_player.play_gif_loop(hydgif, duration=3)
            print("Hydration time!")
            speaker.speak("Hydration time! Please drink water.")
            oled.show_message("Hydration time!")
            gif_player.display_image(blackscreen)

def play_mode_loop():
    global play_mode_active
    audio_listener = AudioToText()
    speaker.speak("Play mode started. Ready for commands.")
    gif_player.display_image(playimg)
    oled.show_message("Play mode ON")

    command_map = {
        "right hand up": 3,
        "left hand up": 4,
        "both hand up": 6,
        "shake head": 5,
        "shake hands": 7,
        "home": 0
    }

    while play_mode_active:
        try:
            play_command = audio_listener.listen(duration=4).lower().strip()
            print(f"Play mode heard: '{play_command}'")

            if "play mode stop" in play_command:
                play_mode_active = False
                speaker.speak("Exiting play mode.")
                gif_player.display_image(blackscreen)
                arduino.send_command(0)
                oled.show_message("Play mode OFF")
                break

            for cmd, num in command_map.items():
                if cmd in play_command:
                    print(f"Executing command: '{cmd}' -> {num}")
                    arduino.send_command(num)
                    break

        except Exception as e:
            print("Error in play mode:", e)

def handle_command(command, audio_listener, speaker):
    global hydration_reminder_active, hydration_thread, play_mode_active

    command = command.lower()

    if "time" in command:
        arduino.send_command(3)
        gif_player.play_gif_loop(timegif, duration=3)
        time_response = read_time_from_rtc()
        oled.show_message(time_response)
        print("Assistant:", time_response)
        speaker.speak(time_response)
        arduino.send_command(0)
        gif_player.display_image(blackscreen)
        time.sleep(0.2)

    elif "hydration" in command:
        print("Entering hydration reminder mode...")
        speaker.speak("Entering hydration reminder mode please say start ot stop")
        oled.show_message("Hydration mode")

        audio_listener = AudioToText()
        hydration_command = audio_listener.listen(duration=5).lower()
        print("Heard inside hydration:", hydration_command)

        if "start" in hydration_command:
            speaker.speak("Please say the reminder time in minutes")
            oled.show_message("Say time in\nminutes")
            time_response = audio_listener.listen(duration=5).lower()
            print("Received time:", time_response)

            try:
                minutes = int([int(s) for s in time_response.split() if s.isdigit()][0])
            except (IndexError, ValueError):
                minutes = 10
                speaker.speak("Could not understand time. Using default of 10 minutes.")

            if hydration_reminder_active:
                hydration_reminder_active = False
                if hydration_thread and hydration_thread.is_alive():
                    hydration_thread.join()

            hydration_reminder_active = True
            hydration_thread = threading.Thread(target=hydration_reminder_loop, args=(minutes,))
            hydration_thread.daemon = True
            hydration_thread.start()
            speaker.speak(f"Hydration reminder set every {minutes} minutes.")
            oled.show_message(f"Reminder set:\n{minutes} mins")

        elif "stop" in hydration_command:
            hydration_reminder_active = False
            if hydration_thread and hydration_thread.is_alive():
                hydration_thread.join()
            speaker.speak("Hydration reminder stopped.")
            oled.show_message("Hydration stopped")

    elif "play mode ON" in command:
        play_mode_active = True
        play_mode_loop()