{ lib, ... }:
let
  inherit (lib) mkOption types;

  capitalize = (import ../text.nix { inherit lib; }).capitalize;

  userType = types.submodule (
    { ... }: {
      options = {
        displayName = mkOption {
          type = types.nullOr types.str;
          description = "The human-readable name of the user.";
          default = null;
        };

        mailAddress = mkOption {
          type = types.nullOr types.str;
          description = "The mail address of the user.";
          default = null;
        };

        groups = mkOption {
          type = types.listOf types.str;
          description = "The additional groups of the user.";
          default = [ ];
        };
      };
    });

  linuxUserType = types.submodule (
    { ... }: {
      options = {
        defaultShell = mkOption {
          type = types.nullOr types.str;
          description = "The default shell of the user.";
          default = null;
        };
      };
    });

  winUserType = types.submodule (
    { ... }: {
      options = {
        microsoftAccount = mkOption {
          type = types.bool;
          description = "A value indicating whether this user is a Microsoft Account.";
          default = false;
        };
      };
    });
in {
  options = {
    valhalla = {
      users = mkOption {
        type = types.attrsOf userType;
        description = "The users to create on the machine.";
        default = { };
      };

      linux.users = mkOption { type = types.attrsOf linuxUserType; };

      windows = mkOption {
        type = types.submoduleWith {
          modules = [
            ({ config, options, ... }: {
              options = {
                users = mkOption { type = types.attrsOf winUserType; };

                winUsers = mkOption {
                  type = options.users.type;
                  default = (lib.attrsets.concatMapAttrs
                    (name: options: { ${capitalize name} = options; })
                    config.users);
                };
              };
            })
          ];
        };
      };
    };
  };
}