{ config, lib, pkgs, ... }:
# Source: https://github.com/Lykos153/numen-nix
with lib;

let
  cfg = config.services.numen;
in
{
  options.services.numen = {
    enable = mkOption {
      type = types.bool;
      default = false;
      description = ''
        Enables Numen Voice Control. Only available to Users in Group "input".
      '';
    };

    numenPkg = mkOption {
      type = types.package;
      default = pkgs.kb-one.numen;
    };

    modelPkg = mkOption {
      type = types.package;
      default = pkgs.kb-one.vosk-model-small-en-us;
      description = ''
        Vosk model to be loaded by numen. Overrides modelPkg!
      '';
    };

    # models = mkOption {
    #   type = types.uniq types.listOf types.package;
    #   default = [vosk-model-small-en-us];
    #   example = "[vosk-model-small-en-us]";
    #   description = ''
    #     List of vosk models to be loaded by numen. They can be referred to using the index, eg. model0 or model1.
    #   '';
    # };

    dotoolPkg = mkOption {
      type = types.package;
      default = pkgs.kb-one.dotool;
    };

    autoStart = mkOption {
      type = types.bool;
      default = true;
    };

    phrases = mkOption {
      type = types.listOf types.path;
      default = [
        ./phrases/character.phrases
        ./phrases/control.phrases
        ./phrases/environment.phrases
        ./phrases/voice.phrases
      ];
      description = ''
        Phrases to be loaded by numen. If empty, the default phrases are used.
      '';
    };

    extraArgs = mkOption {
      type = types.singleLineStr;
      default = "";
      description = ''
        Additional arguments to be passed to numen.
      '';
    };

    dotoolXkbLayout = mkOption {
      type = types.singleLineStr;
      default = "de";
      description = ''
        The XKB keyboard layout that should be used by dotool.
      '';
    };
  };

  config = mkIf cfg.enable {

    # System Configuration
    environment.systemPackages = [
      cfg.numenPkg
      cfg.dotoolPkg
      cfg.modelPkg
    ];
    services.udev.extraRules = ''
      KERNEL=="uinput", GROUP="input", MODE="0660", OPTIONS+="static_node=uinput"
    '';

    # Enable AutoStart Service
    systemd.user.services.numen = mkIf cfg.autoStart {
      description = "Numen voice control";
      after = [ "graphical-session-pre.target" ];
      partOf = [ "graphical-session.target" ];
      wantedBy = [ "graphical-session.target" ];
      environment = {
        DOTOOL_XKB_LAYOUT = "${cfg.dotoolXkbLayout}";
        NUMEN_MODEL = "${cfg.modelPkg}/usr/share/vosk-models/small-en-us/";
      };
      serviceConfig.ExecStart = "${cfg.numenPkg}/bin/numen ${cfg.extraArgs} ${lib.strings.concatStringsSep " " cfg.phrases}";
    };
  };
}