import ugfx, wifi, urandom, json
from time import sleep, time
from umqtt.simple import MQTTClient

mqtt_last_ping = time()
done = False


# Received messages from subscriptions will be delivered to this callback
def sub_cb(topic, msg):
    data = json.loads(msg.decode('utf-8'))
    ugfx.clear(ugfx.WHITE)
    ugfx.flush()
    ugfx.clear(ugfx.BLACK)
    ugfx.flush()
    ugfx.clear(ugfx.WHITE)
    ugfx.flush()
    ugfx.string(60,10,'Available: %s' % str(data['available_number']),"Roboto_BlackItalic24",ugfx.BLACK)
    ugfx.string(40,40,'Sold: %s' % str(data['sold']),"PermanentMarker36",ugfx.BLACK)
    ugfx.string(35,90,"tickets.mch2022.org","Roboto_BlackItalic24",ugfx.BLACK)
    ugfx.flush()


def connect(server, connect_print):
    if connect_print:
        ugfx.clear(ugfx.WHITE)
        ugfx.string(10,10,"Connecting to MQTT...","Roboto_Regular12", 0)
        ugfx.flush()

    clientname = 'SHA2017Badge ' + str(urandom.getrandbits(30))
    c = MQTTClient(clientname, server, keepalive=60)
    c.set_callback(sub_cb)
    c.connect()
    c.subscribe(b"mch2022/ticketshop/RegularTickets")
    print('mqtt connected')
    return c


def main(server="mqtt.mch2022.org", connect_print=True):
    global mqtt_last_ping, mqtt_keepalive, done
    while not done:
        c = connect(server, connect_print)
        c.check_msg()
        try:
            while not done:
                # Workaround: The MQTT lib does not send ping messages
                current_time = time()
                if current_time > mqtt_last_ping + c.keepalive:
                    c.ping()
                    mqtt_last_ping = current_time

                c.check_msg()
                sleep(1)
            c.disconnect()
        except OSError:
            # Restart...
            pass


def go_home(pushed):
    global done
    if pushed:
        done = True


def run():
    global done
    inited_once = False

    while not done:
        try:
            wifi.connect()
        except:
            wifi.init()
        
        if not inited_once:
            ugfx.init()
            ugfx.input_init()
            ugfx.clear(ugfx.WHITE)
            ugfx.string(10,10,"Waiting for wifi...","Roboto_Regular12", 0)
            ugfx.flush()

        try:
            wifi.wait()
        except:
            while not wifi.sta_if.isconnected() and not done:
                sleep(0.1)
            
        if not inited_once:
            ugfx.input_attach(ugfx.BTN_B, go_home)

        connect_print = not inited_once
        inited_once = True
        try:
            main(connect_print=connect_print)
        except:
            # The MQTT library is buggy when the WiFi connection is unstable
            pass