{
  pkgs,
  config,
  lib,
  ...
}:
with lib;
let

  networkStatus =
    let

      q-online = ''
        if ${pkgs.curl}/bin/curl -s google.com >/dev/null; then
          echo 'status: online'
        else
          echo 'status: offline '
        fi
      '';

      q-wireless = ''
        for dev in $(
          ${pkgs.iw}/bin/iw dev \
            | ${pkgs.gnused}/bin/sed -n 's/^\s*Interface\s\+\([0-9a-z]\+\)$/\1/p'
        ); do
          inet=$(${pkgs.iproute2}/bin/ip addr show $dev \
            | ${pkgs.gnused}/bin/sed -n 's/.*inet \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p') \
            || unset inet
          ssid=$(${pkgs.iw}/bin/iw dev $dev link \
            | ${pkgs.gnused}/bin/sed -n 's/.*\tSSID: \(.*\)/\1/p' \
            | ${pkgs.coreutils}/bin/tr -d '\r') \
            || unset ssid
          printf '%s: %s %s\n' $dev ''${inet+ $inet} ''${ssid+ $ssid}
        done
      '';

    in
    pkgs.writers.writeBash "network-status" ''
      ${q-wireless}
      ${q-online}
      ${pkgs.coreutils}/bin/uptime
    '';

  taskNextWeek = pkgs.writers.writeDash "taskweek" ''
    ${pkgs.taskwarrior}/bin/task \
                        export "(due.before:today+7days and due.after:today)" \
        | ${pkgs.jq}/bin/jq '[.[] | { Day: .due, ID: .id, Description: .description | sub("\n.*";"")} ] | sort_by(.Day)' \
        | ${pkgs.miller}/bin/mlr --ijson --opprint put '$Day = strftime(strptime($Day,"%Y%m%dT%H%M%SZ")'$(date +%z)'00,"%a")'
  '';

  activeTasks = pkgs.writers.writeBash "active-tasks" ''
    ${pkgs.taskwarrior}/bin/task export status:pending and "( +ACTIVE or +DUETODAY or +TODAY or +OVERDUE )" | \
    ${pkgs.jq}/bin/jq  \
      --raw-output '
      sort_by(.description) | reverse |
      .[] |
      "[ \( .id ) ] \( .description )"
    '
    echo
  '';

  userHighlight =
    map ({ user, ... }: user) (builtins.attrValues config.services.browser.configList)
    ++ [ "steam" ];

  activeUsers = pkgs.writers.writeBash "active-users" ''
    ${pkgs.procps}/bin/ps -eo user \
     | ${pkgs.gnused}/bin/sed '1 d' \
     | ${pkgs.coreutils}/bin/sort  \
     | ${pkgs.coreutils}/bin/uniq \
     | ${pkgs.gnugrep}/bin/egrep --color=always '(${pkgs.lib.concatStringsSep "|" userHighlight})|$'
  '';

  # default settings
  wtfModule =
    args@{
      height ? 1,
      width ? 1,
      top,
      left,
      enabled ? true,
      type,
      ...
    }:
    {
      enabled = enabled;
      focusable = false;
      position.top = top;
      position.left = left;
      position.height = height;
      position.width = width;
    }
    // (lib.filterAttrs (
      key: _:
      lib.all (x: x != key) [
        "height"
        "width"
        "top"
        "left"
      ]
    ) args);

  # command runner module
  cmdRunner =
    args@{ cmd, ... }:
    wtfModule (
      {
        type = "cmdrunner";
        focusable = false;
        refreshInterval = 300;
      }
      // args
    );

  modules = {
    inherit cmdRunner;

    digitalclock =
      args@{ top, left, ... }:
      cmdRunner (
        {
          cmd = pkgs.writers.writeDash "clock" ''
            ${pkgs.toilet}/bin/toilet --font future `${pkgs.coreutils}/bin/date +"%a %H:%M"`
            ${pkgs.coreutils}/bin/date +"%B %d %Y"
          '';
          title = "";
          refreshInterval = 30;
        }
        // args
      );

    clocks =
      args@{ top, left, ... }:
      wtfModule (
        {
          type = "clocks";
          title = "";
          border = false;
          colors.rows = {
            even = "white";
            odd = "white";
          };
          locations = {
            UTC = "Etc/UTC";
            Berlin = "Europe/Berlin";
            Thailand = "Asia/Bangkok";
            #Cuba = "America/Havana";
            #Wellington = "Pacific/Auckland";
          };
          sort = "alphabetical";
          refreshInterval = 60;
        }
        // args
      );

    resourceusage =
      args@{ top, left, ... }:
      wtfModule (
        {
          type = "resourceusage";
          title = "";
          cpuCombined = false;
          refreshInterval = 5;
        }
        // args
      );

    power =
      args@{ top, left, ... }:
      wtfModule (
        {
          type = "power";
          title = "";
          refreshInterval = 100;
        }
        // args
      );

    prettyweather =
      args@{ top, left, ... }:
      wtfModule (
        {
          type = "prettyweather";
          title = "";
          city = "Essen";
          unit = "m";
          view = 0;
          language = "en";
          refreshInterval = 3600;
        }
        // args
      );

    feedreader =
      args@{
        top,
        left,
        feeds,
        ...
      }:
      wtfModule (
        {
          type = "feedreader";
          title = "";
          refreshInterval = 3600;
          focusable = true;
          #feedLimit = 10;
          colors.rows = {
            even = "white";
            odd = "white";
          };
        }
        // args
      );

    github =
      args@{
        top,
        left,
        username,
        apiKey,
        ...
      }:
      wtfModule (
        {
          type = "github";
          title = "";
          refreshInterval = 3600;
          feedlimit = 10;

          enableStatus = true;
          #  customQueries:
          #    othersPRs:
          #      title: "Others Pull Requests"
          #      filter: "is:open is:pr -author:wtfutil"
          #  repositories:
          #    - "wtfutil/wtf"
          #    - "wtfutil/docs"
          #    - "umbrella-corp/wesker-api"
        }
        // args
      );

  };

  newsJson = {
    wtf = {
      term = "rxvt-unicode-256color";
      colors.border = {
        focusable = "darkslateblue";
        focused = "orange";
        normal = "green";
      };
      grid = {
        columns = [
          28
          0
          0
        ];
        rows = [
          9
          9
          9
          9
          9
          9
          0
        ];
      };
      refreshInterval = 1;
      mods = with modules; {

        clock = digitalclock {
          top = 0;
          left = 0;
        };
        weather = prettyweather {
          top = 1;
          left = 0;
        };

        # feeds
        hackernews = feedreader {
          title = "Hacker News";
          top = 0;
          left = 1;
          height = 3;
          feeds = [ "https://news.ycombinator.com/rss" ];
        };
        lopster = feedreader {
          title = "Lopsters";
          top = 0;
          left = 2;
          height = 3;
          feeds = [ "https://lobste.rs/rss" ];
        };

        hackernews_tools = feedreader {
          title = "Hacker News Tools";
          top = 4;
          left = 1;
          height = 1;
          feeds = [ "https://latesthackingnews.com/category/hacking-tools/feed/" ];
        };
        nixos = feedreader {
          title = "NixOS Weekly";
          top = 3;
          left = 1;
          height = 1;
          feeds = [ "https://weekly.nixos.org/feeds/all.rss.xml" ];
        };
        taskwarrior = feedreader {
          title = "Taskwarrior";
          top = 3;
          left = 2;
          height = 1;
          feeds = [ "https://taskwarrior.org/feed.rss" ];
        };

        #github = github {
        #  username = "mrVanDalo";
        #  apiKey = "";
        #  repositories = [
        #    "nixos/nixpkgs"
        #  ];
        #};
      };
    };
  };

  qJson = {
    wtf = {
      term = "rxvt-unicode-256color";
      colors.border = {
        focusable = "darkslateblue";
        focused = "orange";
        normal = "green";
      };
      grid = {
        columns = [
          33
          12
          28
          36
          0
        ];
        rows = [
          9
          4
          6
          6
          0
        ];
      };
      refreshInterval = 1;
      mods = with modules; {

        digitalclock = digitalclock {
          top = 0;
          left = 0;
        };

        clocks = clocks {
          top = 1;
          left = 0;
        };

        top = resourceusage {
          top = 0;
          left = 1;
          width = 2;
        };

        power = power {
          top = 2;
          left = 0;
        };

        yfinance = wtfModule {
          type = "yfinance";
          top = 3;
          left = 0;
          title = "rates";
          symbols = [
            "EURUSD=X"
            "EURNZD=X"
            "EURTHB=X"
          ];
          refreshInterval = 60;
        };

        weather = prettyweather {
          top = 0;
          left = 3;
        };

        calendar = cmdRunner {
          title = "";
          args = [
            "-3"
            "--monday"
            "--color=never"
            "-w"
          ];
          cmd = "cal";
          top = 1;
          left = 1;
          height = 2;
          width = 3;
          refreshInterval = 3600;
        };

        active-users = cmdRunner {
          title = "users";
          cmd = activeUsers;
          top = 0;
          left = 4;
          height = 4;
          width = 1;
          refreshInterval = 30;
        };

        #active-tasks = cmdRunner {
        #  title = "active tasks";
        #  cmd = activeTasks;
        #  top = 4;
        #  left = 2;
        #  height = 1;
        #  width = 3;
        #  refreshInterval = 60;
        #};

        #next-week-tasks = cmdRunner {
        #  title = "upcoming";
        #  cmd = taskNextWeek;
        #  top = 4;
        #  left = 0;
        #  height = 1;
        #  width = 2;
        #  refreshInterval = 60;
        #};

        network-status = cmdRunner {
          title = "network status";
          cmd = networkStatus;
          top = 3;
          left = 1;
          height = 1;
          width = 3;
          refreshInterval = 7;
        };

        uptime = cmdRunner {
          enabled = false;
          title = "uptime";
          cmd = "uptime";
          top = 3;
          left = 1;
          height = 1;
          width = 3;
        };
      };
    };
  };

  createDashboard =
    { json, name }:
    let
      configuration = pkgs.writeText "config.yml" (builtins.toJSON json);
    in
    pkgs.writers.writeBashBin name ''
      ${pkgs.wtf}/bin/wtfutil --config=${toString configuration}
    '';

in

{
  options.components.terminal.wtf.enable = mkOption {
    type = lib.types.bool;
    default = config.components.terminal.enable;
  };
  config = mkIf (config.components.terminal.wtf.enable) {

    services.upower.enable = true;

    environment.systemPackages = [
      pkgs.wtf
      (createDashboard {
        json = qJson;
        name = "q";
      })
      (createDashboard {
        json = newsJson;
        name = "news";
      })
      #activeUsers
      #activeTasks
      pkgs.upower
    ];

  };
}