{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.mjallen.programs.waybar;

  waybar-weather = pkgs.writeScriptBin "waybar-weather" ''
    #!/usr/bin/env nix-shell
    #! nix-shell -i python3 --pure
    #! nix-shell -p python3 python3Packages.requests

    import os
    import json
    import shutil
    from datetime import datetime, timedelta

    import requests

    WWO_CODE = {
        "113": "Sunny",
        "116": "PartlyCloudy",
        "119": "Cloudy",
        "122": "VeryCloudy",
        "143": "Fog",
        "176": "LightShowers",
        "179": "LightSleetShowers",
        "182": "LightSleet",
        "185": "LightSleet",
        "200": "ThunderyShowers",
        "227": "LightSnow",
        "230": "HeavySnow",
        "248": "Fog",
        "260": "Fog",
        "263": "LightShowers",
        "266": "LightRain",
        "281": "LightSleet",
        "284": "LightSleet",
        "293": "LightRain",
        "296": "LightRain",
        "299": "HeavyShowers",
        "302": "HeavyRain",
        "305": "HeavyShowers",
        "308": "HeavyRain",
        "311": "LightSleet",
        "314": "LightSleet",
        "317": "LightSleet",
        "320": "LightSnow",
        "323": "LightSnowShowers",
        "326": "LightSnowShowers",
        "329": "HeavySnow",
        "332": "HeavySnow",
        "335": "HeavySnowShowers",
        "338": "HeavySnow",
        "350": "LightSleet",
        "353": "LightShowers",
        "356": "HeavyShowers",
        "359": "HeavyRain",
        "362": "LightSleetShowers",
        "365": "LightSleetShowers",
        "368": "LightSnowShowers",
        "371": "HeavySnowShowers",
        "374": "LightSleetShowers",
        "377": "LightSleet",
        "386": "ThunderyShowers",
        "389": "ThunderyHeavyRain",
        "392": "ThunderySnowShowers",
        "395": "HeavySnowShowers",
    }

    WEATHER_SYMBOL = {
        "Unknown":             "",
        "Cloudy":              "",
        "Fog":                 "",
        "HeavyRain":           "",
        "HeavyShowers":        "",
        "HeavySnow":           "",
        "HeavySnowShowers":    "",
        "LightRain":           "",
        "LightShowers":        "",
        "LightSleet":          "",
        "LightSleetShowers":   "",
        "LightSnow":           "",
        "LightSnowShowers":    "",
        "PartlyCloudy":        "󰖕",
        "Sunny":               "",
        "ThunderyHeavyRain":   "",
        "ThunderyShowers":     "",
        "ThunderySnowShowers": "",
        "VeryCloudy": "",
    }

    WEATHER_CODES = {key: WEATHER_SYMBOL[value] for key, value in WWO_CODE.items()}

    WIND_DIRECTION = {
        "S": "↓", 
        "SW": "↙",
        "SSW": "↙",
        "W": "←", 
        "NW": "↖", 
        "NNW": "↖", 
        "N": "↑", 
        "NE": "↗", 
        "NNE": "↗", 
        "E": "→", 
        "SE": "↘",
        "SSE": "↘",
    }

    MOON_PHASES = (
        "󰽤", "󰽧", "󰽡", "󰽨", "󰽢", "󰽦", "󰽣", "󰽥"
    )

    WEATHER_SYMBOL_WI_DAY = {
        "Unknown":             "",
        "Cloudy":              "",
        "Fog":                 "",
        "HeavyRain":           "",
        "HeavyShowers":        "",
        "HeavySnow":           "",
        "HeavySnowShowers":    "",
        "LightRain":           "",
        "LightShowers":        "",
        "LightSleet":          "",
        "LightSleetShowers":   "",
        "LightSnow":           "",
        "LightSnowShowers":    "",
        "PartlyCloudy":        "󰖕",
        "Sunny":               "",
        "ThunderyHeavyRain":   "",
        "ThunderyShowers":     "",
        "ThunderySnowShowers": "",
        "VeryCloudy": "",
    }

    WEATHER_CODES_WI_DAY = {key: WEATHER_SYMBOL_WI_DAY[value] for key, value in WWO_CODE.items()}

    WEATHER_SYMBOL_WI_NIGHT = {
        "Unknown":             "",
        "Cloudy":              "",
        "Fog":                 "",
        "HeavyRain":           "",
        "HeavyShowers":        "",
        "HeavySnow":           "",
        "HeavySnowShowers":    "",
        "LightRain":           "",
        "LightShowers":        "",
        "LightSleet":          "",
        "LightSleetShowers":   "",
        "LightSnow":           "",
        "LightSnowShowers":    "",
        "PartlyCloudy":        "󰼱",
        "Sunny":               "󰖔",
        "ThunderyHeavyRain":   "",
        "ThunderyShowers":     "",
        "ThunderySnowShowers": "",
        "VeryCloudy": "",
    }

    WEATHER_CODES_WI_NIGHT = {key: WEATHER_SYMBOL_WI_NIGHT[value] for key, value in WWO_CODE.items()}

    WEATHER_SYMBOL_WEGO = {
        "Unknown": [
            "    .-.      ",
            "     __)     ",
            "    (        ",
            "     `-’     ",
            "      •      "],
        "Sunny": [
            '<span foreground=\"#FFFF00\">    \\   /    </span>',
            '<span foreground=\"#FFFF00\">     .-.     </span>',
            '<span foreground=\"#FFFF00\">  ― (   ) ―  </span>',
            '<span foreground=\"#FFFF00\">     `-’     </span>',
            '<span foreground=\"#FFFF00\">    /   \\    </span>'],
        "PartlyCloudy": [
            '<span foreground=\"#FFFF00\">   \\  /      </span>',
            '<span foreground=\"#FFFF00\"> _ /\'\'</span>"<span foreground=\"#BBBBBB\">.-.    </span>',
            '<span foreground=\"#FFFF00\">   \\_</span>"<span foreground=\"#BBBBBB\">(   ).  </span>',
            '<span foreground=\"#FFFF00\">   /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
            '             '
            ],
        "Cloudy": [
            '             ',
            '<span foreground=\"#BBBBBB\">     .--.    </span>',
            '<span foreground=\"#BBBBBB\">  .-(    ).  </span>',
            '<span foreground=\"#BBBBBB\"> (___.__)__) </span>',
            '             '],
        "VeryCloudy": [
            '             ',
            '<span foreground=\"#585858\"; font-weight: bold;">     .--.    </span>',
            '<span foreground=\"#585858\"; font-weight: bold;">  .-(    ).  </span>',
            '<span foreground=\"#585858\"; font-weight: bold;"> (___.__)__) </span>',
            '             '],
        "LightShowers": [
            '<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-.    </span>',
            '<span foreground=\"#FFFF00\">  ,\\_</span>"<span foreground=\"#BBBBBB\">(   ).  </span>',
            '<span foreground=\"#FFFF00\">   /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
            '<span foreground=\"#87afff\";">     ‘ ‘ ‘ ‘ </span>',
            '<span foreground=\"#87afff\";">    ‘ ‘ ‘ ‘  </span>'],
        "HeavyShowers": [
            '<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#585858\"; font-weight: bold;">.-.    </span>',
            '<span foreground=\"#FFFF00\">  ,\\_</span>"<span foreground=\"#585858\"; font-weight: bold;">(   ).  </span>',
            '<span foreground=\"#FFFF00\">   /</span>"<span foreground=\"#585858\"; font-weight: bold;">(___(__) </span>',
            '<span foreground=\"#0000ff\"; font-weight: bold;">   ‚‘‚‘‚‘‚‘  </span>',
            '<span foreground=\"#0000ff\"; font-weight: bold;">   ‚’‚’‚’‚’  </span>'],
        "LightSnowShowers": [
            '<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-.    </span>',
            '<span foreground=\"#FFFF00\">  ,\\_</span>"<span foreground=\"#BBBBBB\">(   ).  </span>',
            '<span foreground=\"#FFFF00\">   /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
            '<span foreground=\"#eeeeee\";">     *  *  * </span>',
            '<span foreground=\"#eeeeee\";">    *  *  *  </span>'],
        "HeavySnowShowers": [
            '<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#585858\"; font-weight: bold;">.-.    </span>',
            '<span foreground=\"#FFFF00\">  ,\\_</span>"<span foreground=\"#585858\"; font-weight: bold;">(   ).  </span>',
            '<span foreground=\"#FFFF00\">   /</span>"<span foreground=\"#585858\"; font-weight: bold;">(___(__) </span>',
            '<span foreground=\"#eeeeee\"; font-weight: bold;">    * * * *  </span>',
            '<span foreground=\"#eeeeee\"; font-weight: bold;">   * * * *   </span>'],
        "LightSleetShowers": [
            '<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-.    </span>',
            '<span foreground=\"#FFFF00\">  ,\\_</span>"<span foreground=\"#BBBBBB\">(   ).  </span>',
            '<span foreground=\"#FFFF00\">   /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
            '<span foreground=\"#87afff\";">     ‘ </span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">* </span>',
            '<span foreground=\"#eeeeee\";">    *</span>"<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#87afff\";"> ‘  </span>'],
        "ThunderyShowers": [
            '<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-.    </span>',
            '<span foreground=\"#FFFF00\">  ,\\_</span>"<span foreground=\"#BBBBBB\">(   ).  </span>',
            '<span foreground=\"#FFFF00\">   /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
            '<span foreground=\"#ffff87\";">    ⚡\\</span>"<span foreground=\"#87afff\";">‘ ‘</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#87afff\";">‘ ‘ </span>',
            '<span foreground=\"#87afff\";">    ‘ ‘ ‘ ‘  </span>'],
        "ThunderyHeavyRain": [
            '<span foreground=\"#585858\"; font-weight: bold;">     .-.     </span>',
            '<span foreground=\"#585858\"; font-weight: bold;">    (   ).   </span>',
            '<span foreground=\"#585858\"; font-weight: bold;">   (___(__)  </span>',
            '<span foreground=\"#0000ff\"; font-weight: bold;">  ‚‘</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#0000ff\";">‘‚</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#0000ff\";">‚‘ </span>',
            '<span foreground=\"#0000ff\"; font-weight: bold;">  ‚’‚’</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#0000ff\";">’‚’  </span>'],
        "ThunderySnowShowers": [
            '<span foreground=\"#FFFF00\"> _`/\'\'</span>"<span foreground=\"#BBBBBB\">.-.    </span>',
            '<span foreground=\"#FFFF00\">  ,\\_</span>"<span foreground=\"#BBBBBB\">(   ).  </span>',
            '<span foreground=\"#FFFF00\">   /</span>"<span foreground=\"#BBBBBB\">(___(__) </span>',
            '<span foreground=\"#eeeeee\";">     *</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#ffff87\";">⚡\\</span>"<span foreground=\"#eeeeee\";">* </span>',
            '<span foreground=\"#eeeeee\";">    *  *  *  </span>'],
        "LightRain": [
            '<span foreground=\"#BBBBBB\">     .-.     </span>',
            '<span foreground=\"#BBBBBB\">    (   ).   </span>',
            '<span foreground=\"#BBBBBB\">   (___(__)  </span>',
            '<span foreground=\"#87afff\";">    ‘ ‘ ‘ ‘  </span>',
            '<span foreground=\"#87afff\";">   ‘ ‘ ‘ ‘   </span>'],
        "HeavyRain": [
            '<span foreground=\"#585858\"; font-weight: bold;">     .-.     </span>',
            '<span foreground=\"#585858\"; font-weight: bold;">    (   ).   </span>',
            '<span foreground=\"#585858\"; font-weight: bold;">   (___(__)  </span>',
            '<span foreground=\"#0000ff\"; font-weight: bold;">  ‚‘‚‘‚‘‚‘   </span>',
            '<span foreground=\"#0000ff\"; font-weight: bold;">  ‚’‚’‚’‚’   </span>'],
        "LightSnow": [
            '<span foreground=\"#BBBBBB\">     .-.     </span>',
            '<span foreground=\"#BBBBBB\">    (   ).   </span>',
            '<span foreground=\"#BBBBBB\">   (___(__)  </span>',
            '<span foreground=\"#eeeeee\";">    *  *  *  </span>',
            '<span foreground=\"#eeeeee\";">   *  *  *   </span>'],
        "HeavySnow": [
            '<span foreground=\"#585858\"; font-weight: bold;">     .-.     </span>',
            '<span foreground=\"#585858\"; font-weight: bold;">    (   ).   </span>',
            '<span foreground=\"#585858\"; font-weight: bold;">   (___(__)  </span>',
            '<span foreground=\"#eeeeee\"; font-weight: bold;">   * * * *   </span>',
            '<span foreground=\"#eeeeee\"; font-weight: bold;">  * * * *    </span>'],
        "LightSleet": [
            '<span foreground=\"#BBBBBB\">     .-.     </span>',
            '<span foreground=\"#BBBBBB\">    (   ).   </span>',
            '<span foreground=\"#BBBBBB\">   (___(__)  </span>',
            '<span foreground=\"#87afff\";">    ‘ </span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">*  </span>',
            '<span foreground=\"#eeeeee\";">   *</span>"<span foreground=\"#87afff\";"> ‘ </span>"<span foreground=\"#eeeeee\";">*</span>"<span foreground=\"#87afff\";"> ‘   </span>'],
        "Fog": [
            '             ',
            '<span foreground=\"#c0c0c0\";"> _ - _ - _ - </span>',
            '<span foreground=\"#c0c0c0\";">  _ - _ - _  </span>',
            '<span foreground=\"#c0c0c0\";"> _ - _ - _ - </span>',
            '             '],
    }

    WEATHER_CODES_WEGO = {key: WEATHER_SYMBOL_WEGO[value] for key, value in WWO_CODE.items()}

    data = {}


    def format_time(time):
        """get the time formatted"""
        return datetime.strptime(format_24_time(time), "%H").strftime("%I %p")

    def format_24_time(time):
        """get the time formatted"""
        return time.replace("00", "").zfill(2)


    def format_temp(temp):
        """get the temp formatted"""
        return (temp + "°").ljust(3)


    def format_chances(hour):
        """get the chances formatted"""
        chances = {
            "chanceoffog": "Fog",
            "chanceoffrost": "Frost",
            "chanceofovercast": "Overcast",
            "chanceofrain": "Rain",
            "chanceofsnow": "Snow",
            "chanceofsunshine": "Sunshine",
            "chanceofthunder": "Thunder",
            "chanceofwindy": "Wind",
        }

        conditions = []
        for chance, event in chances.items():
            if int(hour[chance]) > 0:
                conditions.append(event + " " + hour[chance] + "%")
        return ", ".join(conditions)

    def build_text(current_condition):
        """build the text string"""
        feels_like_f = current_condition["FeelsLikeF"]
        weather_code = current_condition["weatherCode"]

        tempint = int(feels_like_f)
        extrachar = ""
        if 0 < tempint < 10:
            extrachar = "+"

        current_weather = f"{WEATHER_CODES[weather_code]} {extrachar} {feels_like_f}°F"

        return current_weather

    def build_tooltip(current_condition, astronomy, moon_icon):
        """build the tooltip text"""
        weather_description = current_condition['weatherDesc'][0]['value']
        feels_like_f = current_condition["FeelsLikeF"]
        temp_f = current_condition['temp_F']
        humidity = current_condition['humidity']
        wind_speed = current_condition['windspeedMiles']
        wind_dir = current_condition['winddir16Point']
        moon_phase = astronomy['moon_phase']
        wego = WEATHER_CODES_WEGO[current_condition['weatherCode']]

        current = f"{wego[0]}{weather_description} {temp_f}°\n"
        feels = f"{wego[1]}Feels like: {feels_like_f}°\n"
        wind = f"{wego[2]}Wind: {wind_speed}mph {WIND_DIRECTION[wind_dir]}\n"
        humidityl = f"{wego[3]}Humidity: {humidity}%\n"
        moon = f"{wego[4]}Moon phase: {moon_phase} " + moon_icon + "\n"

        tooltip = current + feels + wind + humidityl + moon

        return tooltip

    def build_forecast(weather):
        """build a 3 day forecast"""
        tooltip = "\n"

        for i, day in enumerate(weather):
            # determine day
            if i == 0:
                tooltip += "Today, "
            if i == 1:
                tooltip += "Tomorrow, "
            # format the date
            date = datetime.strptime(day['date'], "%Y-%m-%d").strftime("%a %b %d %Y")
            tooltip += f"<b>{date}</b>\n"
            # set the high and low
            max_temp = day['maxtempF']
            min_temp = day['mintempF']
            tooltip += f" {max_temp}°F  {min_temp}°F"

            sunrise = day['astronomy'][0]['sunrise']
            sunset = day['astronomy'][0]['sunset']
            tooltip += f" {sunrise}  {sunset}\n"

            tooltip += build_hourly_forecast(i, day['hourly'], sunrise, sunset)
        return tooltip


    def build_hourly_forecast(day_num, hourly, sunrise, sunset):
        """build an hourly forecast"""
        sunrise_hour = datetime.strptime(sunrise, "%I:%M %p").hour
        sunset_hour = datetime.strptime(sunset, "%I:%M %p").hour
        current_hour = datetime.now().hour
        tooltip = ""

        for hour in hourly:
            time_24_hr = int(format_24_time(hour["time"]))

            if day_num == 0:
                if time_24_hr < current_hour - 2:
                    continue

            # determine which code to use
            if is_night_hour(time_24_hr, sunrise_hour, sunset_hour):
                codes = WEATHER_CODES_WI_NIGHT
            else:
                codes = WEATHER_CODES_WI_DAY

            current_time = format_time(hour['time'])
            current_weather_code = codes[hour['weatherCode']]
            feels_like = format_temp(hour['FeelsLikeF'])
            weather_desc = hour['weatherDesc'][0]['value']
            current_chances = format_chances(hour)

            tooltip += f"{current_time} {current_weather_code} "
            tooltip += f"{feels_like} {weather_desc}, {current_chances}\n"

        return tooltip

    def is_night_hour(time_24_hr, sunrise_hour, sunset_hour):
        """returns true if the hour is night"""
        before_sunrise = time_24_hr < sunrise_hour
        after_sunset = time_24_hr > sunset_hour
        return after_sunset or before_sunrise

    def get_wttr_json():
        """get the weather json"""
        weather = requests.get("https://wttr.in/?u&format=j1", timeout=30).json()
        moon = requests.get("https://wttr.in/?format=%m", timeout=30)
        moon_icon = moon.text

        current_condition = weather["current_condition"][0]
        astronomy = weather["weather"][0]['astronomy'][0]

        text = build_text(current_condition)

        tooltip = build_tooltip(current_condition, astronomy, moon_icon) + build_forecast(weather["weather"])

        data["text"] = text
        data["tooltip"] = tooltip

        return json.dumps(data)

    def main():
        """main"""
        try:
            print(get_wttr_json())
        except Exception as e:
            print("error")
            print(e)

    main()
  '';
in
{
  imports = [ ../options.nix ];

  config = lib.mkIf cfg.enable {
    home.packages = [ waybar-weather ];
  };
}
