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

with lib;
let
  cfg = config.my.programs.fish;
  shellConfig = config.my.shell;
  exportVariables =
    lib.mapAttrsToList (n: v: ''set -x ${n} "${v}"'') shellConfig.variables;
  exportedVariables = lib.concatStringsSep "\n" exportVariables;
in
{
  options.my.programs.fish.enable = mkEnableOption "fish";

  config = lib.mkIf cfg.enable {
    # set as default shell
    users.users.moritz.shell = pkgs.fish;
    environment.systemPackages = with pkgs.fishPlugins; [ fzf-fish pisces ];
    # needed for nix completions
    programs.fish.enable = true;

    home-manager.users.moritz = {
      programs = {
        fish = {
          enable = true;
          shellAbbrs = shellConfig.abbreviations;
          shellAliases = shellConfig.aliases;
          shellInit = ''
            # Vi Mode
            fish_vi_key_bindings

            # Emulates vim's cursor shape behavior
            # Set the normal and visual mode cursors to a block
            set fish_cursor_default block
            # Set the insert mode cursor to a line
            set fish_cursor_insert line
            # Set the replace mode cursor to an underscore
            set fish_cursor_replace_one underscore
            # The following variable can be used to configure cursor shape in
            # visual mode, but due to fish_cursor_default, is redundant here
            set fish_cursor_visual block

            # Variables
            ${exportedVariables}
          '';
          functions = {
            gi = with pkgs; ''
              set url https://www.gitignore.io/api

              if test (count $argv) -eq 0
                set choice ( curl -sL $url/list \
                           | string split "," \
                           | ${fzf}/bin/fzf -m \
                           | string join "," )
              else
                set choice (string join "," $argv[1..])
              end

              if ${gum}/bin/gum confirm "Overwrite current .gitignore?"
                ${curl}/bin/curl -sL $url/$choice > .gitignore
              else
                ${curl}/bin/curl -sL $url/$choice >> .gitignore
              end
            '';
            fish_greeting = "";
            cheat = "cht.sh $argv | bat -p";
          };
        };
      };
    };
  };
}
