{ config, lib, pkgs, ... }:

let
  cfg = config.services.hyprvoice;

  hyprvoice = pkgs.buildGoModule rec {
    pname = "hyprvoice";
    version = "1.0.2";

    src = pkgs.fetchFromGitHub {
      owner = "LeonardoTrapani";
      repo = "hyprvoice";
      rev = "v${version}";
      hash = "sha256-ng17y53L9cyxSjupSGKyZkBXOGneJrjprjvODYch6EE=";
    };

    vendorHash = "sha256-b1IsFlhj+xTQT/4PzL97YjVjjS7TQtcIsbeK3dLOxR4=";

    subPackages = [ "cmd/hyprvoice" ];

    # Runtime deps need to be available for whisper-cpp transcription,
    # audio capture, text injection, and notifications.
    nativeBuildInputs = [ pkgs.makeWrapper ];

    postInstall = ''
      wrapProgram $out/bin/hyprvoice \
        --prefix PATH : ${lib.makeBinPath runtimeDeps}
    '';

    meta = {
      description = "Voice-powered typing for Wayland desktops";
      homepage = "https://github.com/LeonardoTrapani/hyprvoice";
      license = lib.licenses.mit;
      mainProgram = "hyprvoice";
    };
  };

  runtimeDeps = with pkgs; [
    whisper-cpp
    pipewire
    wl-clipboard
    wtype
    libnotify
  ] ++ lib.optionals cfg.ydotool [ pkgs.ydotool ];

in
{
  options.services.hyprvoice = {
    enable = lib.mkEnableOption "hyprvoice voice-to-text dictation";

    model = lib.mkOption {
      type = lib.types.str;
      default = "small.en";
      description = "Whisper model to use (e.g., tiny.en, base.en, small.en, medium.en, large-v3-turbo)";
    };

    ydotool = lib.mkOption {
      type = lib.types.bool;
      default = false;
      description = "Include ydotool as an alternative text injection backend (recommended for Chromium apps)";
    };

    user = lib.mkOption {
      type = lib.types.str;
      description = "User to run the hyprvoice service as";
    };
  };

  config = lib.mkIf cfg.enable {
    environment.systemPackages = [ hyprvoice ];

    systemd.user.services.hyprvoice = {
      description = "Hyprvoice voice-to-text daemon";
      after = [ "pipewire.service" "graphical-session.target" ];
      wants = [ "pipewire.service" ];
      wantedBy = [ "graphical-session.target" ];

      serviceConfig = {
        Type = "simple";
        ExecStart = "${hyprvoice}/bin/hyprvoice serve";
        Restart = "on-failure";
        RestartSec = 5;
      };
    };
  };
}
