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

with lib;
let
  cfg = config.my.programs.lazygit;

  wrapper = pkgs.writeShellApplication {
    name = "lg";
    text = ''
      export LAZYGIT_NEW_DIR_FILE="$HOME/.lazygit/newdir"

      lazygit "$@"

      if [ -f "$LAZYGIT_NEW_DIR_FILE" ]; then
        cd "$(cat "$LAZYGIT_NEW_DIR_FILE")"
        rm -f "$LAZYGIT_NEW_DIR_FILE" > /dev/null
      fi
    '';
    runtimeInputs = [ pkgs.lazygit ];
  };
in
{
  options.my.programs.lazygit.enable = mkEnableOption "lazygit";

  config = mkIf cfg.enable {
    home-manager.users.moritz.home.packages = [
      wrapper
    ];
    home-manager.users.moritz.programs.lazygit = {
      enable = true;
      settings = {
        customCommands = [
          {
            key = "<c-v>";
            context = "global";
            description = "Create new conventional commit";
            prompts = [
              {
                type = "menu";
                key = "Type";
                title = "Type of change";
                options = [
                  { name = "build"; description = "Changes that affect the build system or external dependencies"; value = "build"; }
                  { name = "feat"; description = "A new feature"; value = "feat"; }
                  { name = "fix"; description = "A bug fix"; value = "fix"; }
                  { name = "chore"; description = "Other changes that don't modify src or test files"; value = "chore"; }
                  { name = "ci"; description = "Changes to CI configuration files and scripts"; value = "ci"; }
                  { name = "docs"; description = "Documentation only changes"; value = "docs"; }
                  { name = "perf"; description = "A code change that improves performance"; value = "perf"; }
                  { name = "refactor"; description = "A code change that neither fixes a bug nor adds a feature"; value = "refactor"; }
                  { name = "revert"; description = "Reverts a previous commit"; value = "revert"; }
                  { name = "style"; description = "Changes that do not affect the meaning of the code"; value = "style"; }
                  { name = "test"; description = "Adding missing tests or correcting existing tests"; value = "test"; }
                ];
              }
              {
                type = "input";
                title = "Scope";
                key = "Scope";
                initialValue = "";
              }
              {
                type = "menu";
                key = "Breaking";
                title = "Breaking change";
                options = [
                  { name = "no"; value = ""; }
                  { name = "yes"; value = "!"; }
                ];
              }
              {
                type = "input";
                title = "message";
                key = "Message";
                initialValue = "";
              }
              {
                type = "confirm";
                key = "Confirm";
                title = "Commit";
                body = "Are you sure you want to commit?";
              }
            ];
            command = "git commit --message '{{.Form.Type}}{{ if .Form.Scope }}({{ .Form.Scope }}){{ end }}{{.Form.Breaking}}: {{.Form.Message}}'";
            loadingText = "Creating conventional commit...";
          }
        ];
      };
    };
  };
}
