{
  lib,
  nglib,
  pkgs,
  config,
  ...
}: let
  cfg = config.services.mealie;
  cfgInit = config.init.services.mealie;
in {
  options.services.mealie = {
    enable = lib.mkEnableOption "mealie";
    package = lib.mkPackageOption pkgs "mealie" {};
    settings = lib.mkOption {
      type = lib.types.submodule {
        freeformType = with lib.types; attrsOf str;

        options = {
          PRODUCTION = lib.mkOption {
            type = lib.types.str;
            default = "true";
          };

          DATA_DIR = lib.mkOption {
            type = with lib.types; nullOr str;
            default = null;
          };

          DB_ENGINE = lib.mkOption {
            type = with lib.types; nullOr str;
            default = "sqlite";
          };

          ALEMBIC_CONFIG_FILE = lib.mkOption {
            type = with lib.types; nullOr str;
            default = "${cfg.package}/alembic.ini";
          };
        };
      };

      description = ''
        Configuration of the Mealie service.

        See [the Mealie documentation](https://nightly.mealie.io/documentation/getting-started/installation/backend-config/) for available options and default values.
      '';
      default = {};
    };
  };

  config = lib.mkIf cfg.enable {
    init.services.mealie = {
      enabled = true;
      user = lib.mkDefault "mealie";
      group = lib.mkDefault "mealie";

      tmpfiles = with nglib.nottmpfiles.dsl; lib.optional (cfg.settings.DATA_DIR != null) (d "${cfg.settings.DATA_DIR}" "-" cfgInit.user cfgInit.group "-" _);

      execStart =
        pkgs.writeShellScript "mealie-run"
        (let
          # Mealie can only be configured via environmental variables.
          # With this, we don't accidentally overwrite env variables set by the user.
          extraEnvLines = lib.mapAttrsToList (key: value: ''export ${key}=''${${key}:=${value}}'') cfg.settings;
        in ''
          ${lib.concatStringsSep "\n" extraEnvLines}
          ${cfg.package}/libexec/init_db

          ${lib.getExe cfg.package} -b 0.0.0.0:8000
        '');
    };

    environment.systemPackages = [cfg.package];

    users.users.${cfgInit.user} = nglib.mkDefaultRec {
      description = "mealie";
      inherit (cfgInit) group;
      createHome = false;
      home = "/var/empty";
      useDefaultShell = true;
      uid = config.ids.uids.mealie;
    };

    users.groups.${cfgInit.group} = nglib.mkDefaultRec {gid = config.ids.gids.mealie;};
  };
}