import ugfx, gc, wifi, badge, deepsleep, utime, appglue, sys, easyrtc
from time import *
import urequests as requests

# Make sure WiFi is connected
wifi.init()
badge.init()
badge.vibrator_init()
badge.leds_init()
ugfx.init()

CHECKUP_INTERVAL = 10
MESSAGE_DISPLAY_TIME = 5
LED_SIGNAL_PATTERN = bytes([0, 0, 0, 0, 0, 0, 154, 1, 77, 91, 219, 1, 126, 44, 82, 1, 154, 66, 73, 1, 185, 6, 57, 1, 255, 255, 255, 255, 255, 255, 255])
WIFI_LOST_LED_PATTERN = bytes([255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0])
LED_OFF_PATTERN = bytes([1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

next_checkup = easyrtc.time.time() + CHECKUP_INTERVAL
message_displayed_flag = False


def connect_wifi(show_screen):
    """Wait for WiFi connection"""
    if show_screen:
        ugfx.clear(ugfx.WHITE)
        ugfx.string(10, 10, "Waiting for wifi...", "Roboto_Regular12", 0)
        ugfx.string(15, 70, "Press START to exit", "Roboto_Regular12", 0)
        ugfx.flush()
    else:
        # show wifi interruption
        badge.leds_send_data(WIFI_LOST_LED_PATTERN)

    # try to reconnect
    while not wifi.sta_if.isconnected():
        sleep(0.1)
        pass

    if not show_screen:
        badge.leds_send_data(LED_OFF_PATTERN)


def home():
    """return to launcher"""
    badge.eink_busy_wait()
    appglue.home()


def message_signal(enable):
    """blink led's to signal incomming messages"""
    print("blink " + str(enable))
    if enable:
        badge.leds_send_data(LED_SIGNAL_PATTERN)
        for i in range(0, 3):
            badge.vibrator_activate(255)
            sleep(0.3)
            badge.vibrator_activate(0)

    else:
        badge.leds_send_data(LED_OFF_PATTERN)


def display_message(title, content):
    ugfx.clear()
    ugfx.string(15, 5, title, "Roboto_Regular12", 0)

    if len(content) <= 22:
        ugfx.string(15, 30, content, "Roboto_Regular22", 0)
    elif len(content) <= 44:
        ugfx.string(15, 30, content[0:21], "Roboto_Regular22", 0)
        ugfx.string(15, 55, content[21:len(content)], "Roboto_Regular22", 0)
    else:
        ugfx.string(15, 30, content[0:21], "Roboto_Regular22", 0)
        ugfx.string(15, 55, content[21:43], "Roboto_Regular22", 0)
        ugfx.string(15, 75, content[43:len(content)], "Roboto_Regular22", 0)

    ugfx.string(15, 100, "Press START to exit", "Roboto_Regular12", 0)
    ugfx.flush(ugfx.LUT_FULL)

# set cancel button
ugfx.input_init()
ugfx.input_attach(ugfx.BTN_START, lambda pressed: home())

connect_wifi(True)

# loading screen
ugfx.clear(ugfx.WHITE)
ugfx.string(10, 10, "Getting latest updates from the Travellers Village ...", "Roboto_Regular12", 0)
ugfx.string(15, 70, "Press START to exit", "Roboto_Regular12", 0)
ugfx.flush()

# fetching data
data = []
newdata = []
next_message_timestamp = sys.maxsize

while True:
    print("time " + str(easyrtc.time.time()))
    print("next message timestamp " + str(next_message_timestamp))
    print("messages saved "+ str(len(data)))

    # displaying data if next message timestamp is now or in the past and messages are saved
    if next_message_timestamp <= easyrtc.time.time() and not len(data) <= 0:
        print("messages to display")

        # find youngest message
        youngest_message_ind, youngest_message_showAt = (0, sys.maxsize)
        for ind, message in enumerate(data):
            if message["showAt"] < youngest_message_showAt:
                youngest_message_ind, youngest_message_showAt = (ind, message["showAt"])

        message_to_display = data[youngest_message_ind]

        print("display message index " + str(youngest_message_ind) + " at " + str(youngest_message_showAt))
        print("content " + message_to_display["title"])

        # display youngest message
        display_message(message_to_display["title"], message_to_display["content"])

        message_signal(True)

        sleep(MESSAGE_DISPLAY_TIME)

        message_signal(False)

        message_displayed_flag = True
        next_message_timestamp = sys.maxsize

        # remove youngest message
        del data[youngest_message_ind]

    elif not message_displayed_flag:
        # display "no new messages" if no message is due
        ugfx.clear()
        ugfx.string(15, 5, "No new messages", "Roboto_Regular22", 0)
        ugfx.string(15, 70, "Press START to exit", "Roboto_Regular12", 0)
        ugfx.flush(ugfx.LUT_FULL)

        message_displayed_flag = False

    try:
        # get new messages
        url = "http://badge.jonasleitner.de"
        r = requests.get(url)
        gc.collect()
        newdata = r.json()
        r.close()

    except:
        print("connection failed!")
        """ugfx.clear(ugfx.WHITE)
        ugfx.string(10, 10, "Failed to retrieve message!", "Roboto_Regular12", 0)
        ugfx.string(15, 70, "Press START to exit", "Roboto_Regular12", 0)
        ugfx.flush()
        sleep(0.5)
        """
        connect_wifi(False)

        # message_displayed_flag = False
        continue

    print("got data")
    if newdata:
        print("got newdata")
        if newdata["messages"]:
            print("got messages")
            # only save data if it is not empty, else keep old data
            data = newdata["messages"]

            # ugfx.clear()
            # ugfx.string(15, 5, "Got new messages", "Roboto_Regular22", 0)
            # ugfx.string(15, 70, str(len(data)), "Roboto_Regular12", 0)
            # ugfx.flush(ugfx.LUT_FULL)

            # find and save next message timestamp
            for message in data:
                if message["showAt"] < next_message_timestamp:
                    next_message_timestamp = message["showAt"]
                    print("next message time stamp: " + str(next_message_timestamp))

        else:
            next_message_timestamp = sys.maxsize

    # calculate sleep time
    sleep_until = easyrtc.time.time() + CHECKUP_INTERVAL
    sleep_time = CHECKUP_INTERVAL

    if next_message_timestamp < sleep_until:
        sleep_time = max(next_message_timestamp - easyrtc.time.time(), 1)

    print("sleep time " + str(sleep_time))
    # ugfx.clear()
    # ugfx.string(15, 5, "Sleeping for " + str(sleep_time), "Roboto_Regular22", 0)
    # ugfx.string(15, 70, "Sleeping till " + str(sleep_until), "Roboto_Regular12", 0)
    # ugfx.flush(ugfx.LUT_FULL)

    sleep(sleep_time)
    #badge.eink_busy_wait()
    #deepsleep.start_sleeping(5000)