import wifi
import time
import binascii
from tidal import *
from app import TextApp
import urequests, ujson

GOOGLE_API_KEY='AIzaSyDwr302FpOSkGRpLlUpPThNTDPbXcIn_FM'
OWM_API_KEY='91dff0d7e85c52ce1020a3376cadf677'
GEOLOCATE_API=f"https://www.googleapis.com/geolocation/v1/geolocate?key={GOOGLE_API_KEY}"
HEADERS={
  'content-type': 'application/json',
  'User-Agent': 'Universal Weather -- https://2022.badge.emfcamp.org/projects/universal_weather',
  'From': 'remy@grunblatt.org'
}

class UniversalWeatherApp(TextApp):
 BG = BLACK
 FG = WHITE

 def on_activate(self):
  super().on_activate()   
  self.window.println("WEATHER FORECAST")
  self.window.println("===============")
  networks = wifi.scan()
  l = []
  for network in networks:
    bssid = binascii.hexlify(network[1]).decode()
    formatted_bssid = ':'.join(bssid[i:i+2] for i in range(0, len(bssid), 2))
    l.append({ "macAddress": formatted_bssid })
  payload = { 'wifiAccessPoints' : l }
  self.window.println("Acquiring pos...")
  self.assert_wifi()
  res = urequests.post(GEOLOCATE_API, headers = HEADERS, data = str(payload))
  if res.status_code != 200:
    self.window.println("Error acquiring pos.")
    return
  res = res.json()
  if 'location' in res:
    location = res['location']
    if 'lat' in location and 'lng' in location:
      self.window.println("Pos. acquired...")
      lat = location['lat']
      lng = location['lng']
      url = f'https://nominatim.openstreetmap.org/reverse?format=json&lat={lat}&lon={lng}'
      self.assert_wifi()
      res = urequests.get(url, headers = HEADERS)
      if res.status_code == 200:
        res = res.json()
        if 'address' in res:
          if 'country' in res['address']:
            self.window.println(f"Country: {res['address']['country']}")
          if 'city' in res['address']:
            self.window.println(f"City: {res['address']['city']}")
      else:
          print(res.status_code)
          print(res.text)
      url = f'http://api.openweathermap.org/data/2.5/onecall?lat={lat}&lon={lng}&units=metric&appid={OWM_API_KEY}'
      self.assert_wifi()
      res = urequests.get(url)
      if res.status_code != 200:
        self.window.println("Error getting weather...")
        return
      res = res.json()
      self.window.println(f"Now: {res['current']['weather'][0]['main']}")
      self.window.println("Next five hours:")
      for (i, hour) in enumerate(res['hourly'][:5]):
        self.window.println(f"[{i}] -> {hour['weather'][0]['main']}")
  else:
    self.window.println("Unknown pos.")
    return

 def assert_wifi(self):
  wifi_attempts = 0
  while not wifi.status():
    self.window.println("Connecting...")
    wifi_attempts += 1
    self.window.println("Attempt {}".format(wifi_attempts))
    try:
      wifi.connect()
      wifi.wait()
    except OSError:
      time.sleep(1)
      continue
    if wifi_attempts > 10:
      self.window.println("Con. failed.")
      return

main = UniversalWeatherApp