#!/usr/bin/env bash

FALLBACK='{"temp":0,"feelslike":0,"humidity":0,"wind":0,"desc":"Unavailable","icon":"󰖐","city":""}'
CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/eww"
LOC_CACHE="$CACHE_DIR/weather-location"
UA="eww-bar/1.0 cedric.hoelzl@gmail.com"

mkdir -p "$CACHE_DIR"

get_location() {
  # Cache location for 1 hour; IP rarely changes
  if [ -f "$LOC_CACHE" ] && [ -n "$(find "$LOC_CACHE" -mmin -60 2>/dev/null)" ]; then
    cat "$LOC_CACHE"
    return 0
  fi
  data=$(curl -sf --max-time 5 "http://ip-api.com/json?fields=lat,lon,city") || return 1
  echo "$data" | tee "$LOC_CACHE"
}

icon_for() {
  case "$1" in
    *thunder*)                     echo "󰖔" ;;
    *snow*|*sleet*)                echo "󰖘" ;;
    heavyrain*|*heavyrainshowers*) echo "󰖖" ;;
    *rain*|*shower*)               echo "󰖗" ;;
    fog*)                          echo "󰖑" ;;
    cloudy*)                       echo "󰖐" ;;
    partlycloudy*)                 echo "󰖕" ;;
    fair*|clearsky*)               echo "󰖙" ;;
    *)                             echo "󰖐" ;;
  esac
}

desc_for() {
  case "$(echo "$1" | sed 's/_day//;s/_night//;s/_polartwilight//')" in
    clearsky)                      echo "Clear sky" ;;
    fair)                          echo "Fair" ;;
    partlycloudy)                  echo "Partly cloudy" ;;
    cloudy)                        echo "Cloudy" ;;
    fog)                           echo "Foggy" ;;
    lightrain)                     echo "Light rain" ;;
    rain)                          echo "Rain" ;;
    heavyrain)                     echo "Heavy rain" ;;
    lightrainshowers)              echo "Light showers" ;;
    rainshowers)                   echo "Rain showers" ;;
    heavyrainshowers)              echo "Heavy showers" ;;
    lightrainandthunder)           echo "Light rain & thunder" ;;
    rainandthunder)                echo "Rain & thunder" ;;
    heavyrainandthunder)           echo "Heavy rain & thunder" ;;
    *showersandthunder)            echo "Showers & thunder" ;;
    lightsleet|lightsleetshowers)  echo "Light sleet" ;;
    sleet|sleetshowers)            echo "Sleet" ;;
    heavysleet|heavysleetshowers)  echo "Heavy sleet" ;;
    *sleetandthunder)              echo "Sleet & thunder" ;;
    lightsnow|lightsnowshowers)    echo "Light snow" ;;
    snow|snowshowers)              echo "Snow" ;;
    heavysnow|heavysnowshowers)    echo "Heavy snow" ;;
    *snowandthunder)               echo "Snow & thunder" ;;
    *)                             echo "$1" ;;
  esac
}

fetch() {
  loc=$(get_location) || { echo "$FALLBACK"; return; }
  lat=$(echo "$loc" | jq -r '.lat')
  lon=$(echo "$loc" | jq -r '.lon')
  city=$(echo "$loc" | jq -r '.city')

  data=$(curl -sf --max-time 8 \
    -H "User-Agent: $UA" \
    -H "Accept: application/json" \
    "https://api.met.no/weatherapi/locationforecast/2.0/compact?lat=$lat&lon=$lon") \
    || { echo "$FALLBACK"; return; }

  d='.properties.timeseries[0].data'
  temp=$(    echo "$data" | jq -r "${d}.instant.details.air_temperature | round")
  humidity=$(echo "$data" | jq -r "${d}.instant.details.relative_humidity | round")
  wind_ms=$( echo "$data" | jq -r "${d}.instant.details.wind_speed")
  wind=$(    echo "$wind_ms" | awk '{printf "%d", $1 * 3.6}')
  code=$(    echo "$data" | jq -r \
    "(${d}.next_1_hours.summary.symbol_code) // (${d}.next_6_hours.summary.symbol_code) // \"cloudy\"")

  # Simplified apparent temperature: wind chill below 10°C, else = temp
  feelslike=$(echo "$temp $wind" | awk '{
    t=$1; v=$2
    if (v > 4.8 && t < 10)
      printf "%d", 13.12 + 0.6215*t - 11.37*(v^0.16) + 0.3965*t*(v^0.16)
    else
      printf "%d", t
  }')

  icon=$(icon_for "$code")
  desc=$(desc_for "$code")

  printf '{"temp":%s,"feelslike":%s,"humidity":%s,"wind":%s,"desc":"%s","icon":"%s","city":"%s"}\n' \
    "$temp" "$feelslike" "$humidity" "$wind" "$desc" "$icon" "$city"
}

fetch
while true; do sleep 600; fetch; done
