import ugfx, wifi, urandom
from time import sleep, time
from umqtt.simple import MQTTClient

mqtt_last_ping = time()
done = False

remaining = b'why2025/ticketshop/quotas/Event Visitors/available_number'
sold = 	    b'why2025/ticketshop/quotas/Event Visitors/paid_orders'
pending =   b'why2025/ticketshop/quotas/Event Visitors/pending_orders'

ctr_remaining = 0
ctr_sold = 0
ctr_pending = 0
changed = False


# Received messages from subscriptions will be delivered to this callback
def sub_cb(topic, msg):
    print("Received data on topic " + topic.decode('utf-8'))
    global ctr_remaining, ctr_sold, ctr_pending, changed
    try:
        val = int(msg.decode('utf-8'))
        print("Value: " + str(val))
        if topic == remaining:
            changed |= ctr_remaining != val
            ctr_remaining = val
        elif topic == sold:
            changed |= ctr_sold != val
            ctr_sold = val
        elif topic == pending:
            changed |= ctr_pending != val
            ctr_pending = val
    except:
        pass
    if changed:
        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(ctr_remaining),"Roboto_BlackItalic24",ugfx.BLACK)
        ugfx.string(40,40,'Sold: %s' % str(ctr_sold + ctr_pending),"PermanentMarker36",ugfx.BLACK)
        ugfx.string(35,90,"tickets.why2025.org","Roboto_BlackItalic24",ugfx.BLACK)
        ugfx.flush()
        changed = False


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(sold)
    c.subscribe(pending)
    c.subscribe(remaining)
    print('mqtt connected')
    return c


def main(server="mqtt.why2025.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:
            print('Disconnected...')
            # 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:
            print("Crash loop")
            # The MQTT library is buggy when the WiFi connection is unstable
            pass