import uasyncio
from umqtt import simple
import time

from blink import blink

from A9G import A9G

# TCP config
port = 11925 # replace with your port number
tcp_host = 'YOUR_NGROK_URL_HERE'

# important to call this to initialize the device (start GPRS, GPS)
A9G = A9G()
try:
    A9G.initialize_device()
except Exception:
    A9G.reset()

# MQTT configuration
device_name = "YOUR_DEVICE_NAME" # you can choose your device name
mqtt_server_domain = "broker.hivemq.com"
mqtt_topic = "YOUR_TOPIC" # you may choose your topic

DEVICE_STATE_IDLE = "IDLE"
DEVICE_STATE_ACTIVELY_TRACKING = "ACTIVELY_TRACKING"
POSSIBLE_DEVICE_STATES = [DEVICE_STATE_IDLE, DEVICE_STATE_ACTIVELY_TRACKING]

# initialize to IDLE on boot
DEVICE_STATE = "IDLE"

thread = None

print("FindMyCat :) v1.4")
def on_message_from_mqtt_server(_, message):
    state = message.decode("utf-8")
    print("Message: ", state)
    if state in POSSIBLE_DEVICE_STATES:
        global DEVICE_STATE
        DEVICE_STATE = state
        blink(500)

        thread.cancel()


# setup MQTT connection
mqtt_client = simple.MQTTClient(device_name, mqtt_server_domain)
mqtt_client.connect()
mqtt_client.set_callback(on_message_from_mqtt_server)
mqtt_client.subscribe(mqtt_topic)


async def check_for_messages():
    while True:
        print(A9G.get_device_summary())
        mqtt_client.check_msg()
        time.sleep(0.5)
        await uasyncio.sleep(1)
        A9G.watchdog_reset()
        blink(10)


async def react_to_state_changes():
    while True:
        delay = 600  # 10 mins
        if DEVICE_STATE == DEVICE_STATE_IDLE:
            delay = 600
            blink(10)
            print("IDLE", delay)
            A9G.gps(False)
            A9G.set_idle(True)
            A9G.watchdog_reset()

        elif DEVICE_STATE == DEVICE_STATE_ACTIVELY_TRACKING:
            delay = 10
            print("ACTIVELY_TRACKING", delay)
            A9G.report_location_to_server(tcp_host, port)
            print("sleeping 10 seconds")
            A9G.watchdog_reset()


        await uasyncio.sleep(delay)


async def main():
    global thread
    await uasyncio.gather(
        uasyncio.create_task(react_to_state_changes()),
        uasyncio.create_task(check_for_messages())
    )


async def run():
    global thread
    thread = uasyncio.create_task(main())
    try:
        await thread
    except uasyncio.CancelledError as e:
        print("Restarting the thread", e)
        await run()
    except OSError as os_e:
        print("Restarting the Thread because of OSError", os_e)
        await run()


uasyncio.run(run())
