{
  config,
  lib,
  pkgs,
  ...
}:
with lib; let
  cfg = config.local.sys.users;
  userType = types.submodule {
    options = {
      enable = mkEnableOption "user settings";
      unixId = mkOption {
        # gid and uid are always the same
        type = types.int;
      };
      admin = mkOption {
        type = types.bool;
        default = false;
      };
      sshKeyPublicFile = mkOption {
        type = types.listOf types.path;
        default = [];
      };
    };
  };
in {
  options.local.sys.users = mkOption {
    type = types.attrsOf userType;
    default = {};
  };

  config = {
    local.sys.users = {
      fabian = {
        unixId = mkDefault 1000;
        admin = true;
      };
      vanessa = {
        unixId = mkDefault 1001;
        admin = false;
      };
      soto = {
        unixId = mkDefault 1010;
        admin = false;
      };
      diaz = {
        unixId = mkDefault 1011;
        admin = false;
      };
    };

    users = let
      enabledUsers = filterAttrs (k: v: v.enable) cfg;
    in {
      groups =
        mapAttrs (k: v: {
          gid = v.unixId;
        })
        enabledUsers;

      users =
        mapAttrs (k: v: {
          isNormalUser = true;
          uid = v.unixId;
          group = k;
          shell = pkgs.zsh;
          extraGroups =
            ["users" "networkmanager"]
            ++ optionals (v.admin) ["wheel" "libvirtd" "dialout" "adbusers"];
          openssh.authorizedKeys.keyFiles = v.sshKeyPublicFile;
        })
        enabledUsers;
    };
  };
}