{
  config,
  lib,
  pkgs,
  ...
}: let
  cfg = config.hive.gotify;
  cli-config = {
    token = config.sops.placeholder.${cfg.tokenSopsKey};
    inherit (cfg.cli) url defaultPriority;
  };
  daemon-config = {
    gotify =
      {
        inherit (cfg.daemon) url;
        token = config.sops.placeholder.${cfg.tokenSopsKey};
        auto_delete = cfg.daemon.autoDelete;
        min_priority = cfg.daemon.minPriority;
      }
      // lib.optionalAttrs (cfg.daemon.onMsgCommand != null) {
        on_msg_command = cfg.daemon.onMsgCommand;
      };
  };
in {
  options.hive.gotify = {
    cli = {
      enable = lib.mkEnableOption "Enable Gotify cli tool";
      url = lib.mkOption {
        type = lib.types.singleLineStr;
        default = "https://${cfg.host}:${toString cfg.port}";
        example = "http://gotify.example.com";
        description = "The http url of the gotify server (for the cli tool)";
      };
      defaultPriority = lib.mkOption {
        type = lib.types.int;
        default = 0;
        example = 3;
        description = "The default priority of the dispatched messages";
      };
    };
    daemon = {
      enable = lib.mkEnableOption "Enable the Gotify desktop notification daemon";
      url = lib.mkOption {
        type = lib.types.singleLineStr;
        default = "wss://${cfg.host}:${toString cfg.port}";
        example = "ws://gotify.example.com";
        description = "The websocket url of the gotify server (for the desktop tool)";
      };
      autoDelete = lib.mkOption {
        type = lib.types.bool;
        default = false;
        example = true;
        description = "Delete messages that have been handled";
      };
      minPriority = lib.mkOption {
        type = lib.types.int;
        default = 0;
        example = 1;
        description = "Ignore messages with priority lower than given value";
      };
      onMsgCommand = lib.mkOption {
        type = lib.types.nullOr lib.types.singleLineStr;
        default = null;
        example = "/usr/bin/beep";
        description = ''          A command to tun for each message with env vars
                    GOTIFY_MSG_PRIORITY, GOTIFY_MSG_TITLE and GOTIFY_MSG_TEXTs
                    If unset use the standard desktop notification passing
        '';
      };
    };
    host = lib.mkOption {
      type = lib.types.singleLineStr;
      example = "example.com";
      description = "The hostname of the gotify server";
    };
    port = lib.mkOption {
      type = lib.types.int;
      default = 443;
      example = 443;
      description = "The port of the gotify server";
    };
    tokenSopsKey = lib.mkOption {
      type = lib.types.singleLineStr;
      description = "The sops key of the token secret";
    };
  };

  config = let
    cli = lib.mkIf cfg.cli.enable {
      home.packages = [pkgs.gotify-cli];
      sops.templates."gotify-cli-json" = {
        content = lib.generators.toJSON {} cli-config;
        path = "${config.xdg.configHome}/gotify/cli.json";
      };
    };
    daemon = lib.mkIf cfg.daemon.enable {
      systemd.user.services.gotify-desktop = {
        Unit = {
          Description = "Gotify Desktop notification service";
          After = ["sops-nix.service"]; # After the secrets have been rendered
        };
        Service = {
          ExecStart = "${pkgs.gotify-desktop}";
        };
        Install = {
          WantedBy = ["multi-user.target"];
        };
      };
      sops.templates."gotify-daemon-toml" = {
        content = lib.generators.toINI {} daemon-config;
        path = "${config.xdg.configHome}/gotify-desktop/config.toml";
      };
    };
  in
    lib.mkMerge [cli daemon];
}
