import ugfx
import wifi
import badge, json
import urequests as requests
import utime as time

api_key = "5af1beca494712ed38d313714d4caff6"
query_url_name = "https://www.mvg.de/fahrinfo/api/location/queryWeb?q=" #for station names
query_url_id = "https://www.mvg.de/fahrinfo/api/location/query?q=" #for station ids
departure_url = "https://www.mvg.de/fahrinfo/api/departure/"
departure_url_postfix = "?footway=0"
product = {'u': 'U', 's': 'S', 't':'', 'b':''}

timezone_offset = 0

def make_timedelta_tuple(timedelta_int):
    t_tuple = time.localtime(timedelta_int)
    differences = (1970, 1, 1, 0, 0, 0, 5, 0)
    timedelta = []
    for delta, dif in zip(t_tuple, differences):
        timedelta.append(delta - dif)
    return timedelta

def generate_timedelta_minutes(start):
    now = time.time() + timezone_offset
    delta = start - now
    t = make_timedelta_tuple(delta)
    return t[4]
    print(t)

def fancy_product(raw):
    try:
        return product[raw]
    except:
        return ''

def _perform_api_request(url):
    resp = requests.get(url, headers={'X-MVG-Authorization-Key': api_key})
    return resp.json()

def get_id_for_station(station_name):
    station = get_stations(station_name)[0]
    return station['id']

def get_locations(query):
    try:
        query = int(query)  # converts station ids to int if thay aren't already
    except(ValueError):  # happens if it is a station name
        url = query_url_name + query
    else:  # happens if it is a station id
        url = query_url_id + str(query)

    results = _perform_api_request(url)
    return results["locations"]

def get_stations(station):
    """Like :func:`.get_locations`, but filters out all results which
    are not stations.
    """
    results = get_locations(station)
    stations = []
    for result in results:
        if result['type'] == 'station':
            stations.append(result)
    return stations

class Station:

    def __init__(self, station):
        if isinstance(station, str):
            self.station_id = get_id_for_station(station)
            if self.station_id is None:
                raise NameError("No matching station found")
        elif isinstance(station, int):
            self.station_id = station
        else:
            raise ValueError("Please provide a Station Name or ID")
        self.name = get_stations(self.station_id)[0]['name']

    def get_departures(self):
        """Get the next departures for `station_id`.

        To get the `station_id` associated with a station name,
        use :func:`get_id_for_station`.

        Returns a list like::

            [
                {
                    'departureTimeMinutes': 0,
                    'destination': 'Laimer Platz',
                    'sev': False,
                    'departureId': 1188266868,
                    'live': True,
                    'departureTime': 1478644495000,
                    'lineBackgroundColor': '#b78730',
                    'label': '5',
                    'product': 'u'
                },
            ]

        `departureTimeMinutes`, the time left to the departure in minutes,
        is added to the response from the api for your convenience.
        """
        url = departure_url + str(self.station_id) + departure_url_postfix
        departures = _perform_api_request(url)['departures']
        for departure in departures:
            timestamp = int(int(departure['departureTime']) / 1000)
            departure['departureTime'] = timestamp
            relative_time = timestamp - time.time()
            departure[u'departureTimeMinutes'] = int(relative_time) + 120*60
        return departures

ugfx.init()
ugfx.LUT_FULL
ugfx.input_init()
ugfx.clear(ugfx.BLACK)
ugfx.flush()
ugfx.clear(ugfx.WHITE)
ugfx.flush()
ugfx.clear(ugfx.BLACK)
ugfx.flush()
ugfx.clear(ugfx.WHITE)
ugfx.flush()
# Make sure WiFi is connected
wifi.init()

ugfx.clear(ugfx.WHITE);
ugfx.string(10,10,"Waiting for wifi...","Roboto_Regular12", 0)
ugfx.flush()

# Wait for WiFi connection
while not wifi.sta_if.isconnected():
    time.sleep(0.1)
    pass


ugfx.clear(ugfx.WHITE);
ugfx.flush()

station_raw = 5

harthof = Station("Harthof")
rockefeller = Station(446)

def main():
    print ("updating")
    ugfx.string(0,0,".","Roboto_Regular12", 0)
    ugfx.flush()
    ugfx.clear(ugfx.WHITE);
    #ugfx.box(0, 0, 296, 24, ugfx.BLACK)
    line = 0

    ugfx.string(1, line, "Rockefellerstrasse", "Roboto_Regular18", ugfx.BLACK)
    line += 20

    departures = rockefeller.get_departures()
    dests = set(d['destination'] for d in departures)
    for dest in ['Dülferstraße', 'Feldmoching Bf.', 'Scheidplatz', 'Kieferngarten']:
        dest_departures = list(filter(lambda d: d['destination'] == dest, departures))[:3]
        if not dest_departures:
            continue
        times = format_departure_times(dest_departures)
        print_departure(
                line,
                fancy_product(dest_departures[0]['product'])+dest_departures[0]['label'],
                dest,
                times)
        line += 16

    ugfx.string(1, line, "Harthof", "Roboto_Regular18", ugfx.BLACK)
    line += 20

    departures = harthof.get_departures()
    departures = list(filter(lambda d: d['product'] == 'UBAHN' and d['destination'] == 'Messestadt Ost', departures))

    dests = set(d['destination'] for d in departures)
    for dest in dests:
        dest_departures = list(filter(lambda d: d['destination'] == dest, departures))[:7]
        times = format_departure_times(dest_departures)
        print_departure(
                line,
                fancy_product(dest_departures[0]['product'])+dest_departures[0]['label'],
                dest,
                times)
        line += 16

    ugfx.flush()
    time.sleep(20)

def print_departure(line, product, destination, times):
        ugfx.string_box(1,line,30,13, product, "Roboto_Regular12", ugfx.BLACK, ugfx.justifyLeft)
        destination = destination.replace('ü', 'u')
        destination = destination.replace('ß', 'ss')
        ugfx.string_box(30,line,236,13, destination, "Roboto_Regular12", ugfx.BLACK, ugfx.justifyLeft)
        ugfx.string_box(100,line,196,13, times, "Roboto_Regular12", ugfx.BLACK, ugfx.justifyRight)

def format_departure_times(departures):
    times = []

    now = time.time() + timezone_offset
    for d in departures:
        delta = int(d['departureTime'] - now)
        if delta > 0:
            times.append(delta // 60)

    return '  '.join(map(str, times)) + 'min'



ugfx.clear(ugfx.WHITE);
ugfx.flush()
while True:
    main()