{ pkgs, lib, ... }:
let
  replace =
    from: to: current:
    if current == from then to else current;
  toSingleLine =
    with lib.strings;
    s: concatMapStrings (stringAsChars (replace "\n" "")) (splitString "\n" s);
  theme = import ../theme.nix;
in
{
  programs = {
    fish = {
      enable = true;
      plugins = [
        {
          # !! to get the previous command
          name = "fishbang";
          src = pkgs.fetchFromGitHub {
            owner = "BrewingWeasel";
            repo = "fishbang";
            rev = "50389667eb9ac79edcff9b987c83e1de8ac93921";
            hash = "sha256-IneNWyfo29C7FDA5b6pTZRX3HpP6y/dRM6GXuLq2+zc=";
          };
        }
      ];
    };

    # TODO catppuccin colours on all parts
    starship = {
      enable = true;
      settings = {
        format = toSingleLine ''
          [](#${theme.mantleAlpha})
          $os
          $username
          [](bg:#${theme.lavenderAlpha} fg:#${theme.mantleAlpha})
          $directory
          [](fg:#${theme.lavenderAlpha} bg:#${theme.blueAlpha})
          $git_branch
          $git_status
          [](fg:#${theme.blueAlpha} bg:#86BBD8)
          $c
          $elixir
          $elm
          $golang
          $gradle
          $haskell
          $java
          $julia
          $nodejs
          $nim
          $rust
          $scala
          [](fg:#86BBD8 bg:#06969A)
          $docker_context
          [](fg:#06969A bg:#33658A)
          $time
          [ ](fg:#33658A)
        '';

        # Disable the blank line at the start of the prompt
        # add_newline = false

        # You can also replace your username with a neat symbol like   or disable this
        # and use the os module below
        username = {
          show_always = false;
          style_user = "bg:#${theme.crustAlpha}";
          style_root = "bg:#${theme.mantleAlpha}";
          format = "[$user]($style) in ";
          disabled = false;
        };

        os = {
          style = "bg:#${theme.mantleAlpha}";
          disabled = false;
        };

        directory = {
          style = "bg:#${theme.lavenderAlpha} fg:#${theme.baseAlpha}";
          format = "[ $path ]($style)";
          truncation_length = 3;
          truncation_symbol = "…/";
        };

        # Here is how you can shorten some long paths by text replacement
        # similar to mapped_locations in Oh My Posh:
        directory.substitutions = {
          "Documents" = "󰈙 ";
          "Downloads" = " ";
          "Music" = "󰓃 ";
          "Pictures" = " ";
        };
        # Keep in mind that the order matters. For example:
        # "Important Documents" = " 󰈙 "
        # will not be replaced, because "Documents" was already substituted before.
        # So either put "Important Documents" before "Documents" or use the substituted version:
        # "Important 󰈙 " = " 󰈙 "

        c = {
          symbol = " ";
          style = "bg:#86BBD8";
          format = "[ $symbol ($version) ]($style)";
        };

        docker_context = {
          symbol = " ";
          style = "bg:#06969A";
          format = "[ $symbol $context ]($style)";
        };

        elixir = {
          symbol = " ";
          style = "bg:#86BBD8";
          format = "[ $symbol ($version) ]($style)";
        };

        elm = {
          symbol = " ";
          style = "bg:#86BBD8";
          format = "[ $symbol ($version) ]($style)";
        };

        git_branch = {
          symbol = " ";
          style = "bg:#${theme.blueAlpha} fg:#${theme.baseAlpha}";
          format = "[ $symbol $branch ]($style)";
        };

        git_status = {
          style = "bg:#${theme.blueAlpha} fg:#${theme.baseAlpha}";
          format = "[$all_status$ahead_behind ]($style)";
        };

        golang = {
          symbol = " ";
          style = "bg:#86BBD8";
          format = "[ $symbol ($version) ]($style)";
        };

        gradle = {
          style = "bg:#86BBD8";
          format = "[ $symbol ($version) ]($style)";
        };

        haskell = {
          symbol = " ";
          style = "bg:#86BBD8";
          format = "[ $symbol ($version) ]($style)";
        };

        java = {
          symbol = " ";
          style = "bg:#86BBD8";
          format = "[ $symbol ($version) ]($style)";
        };

        julia = {
          symbol = " ";
          style = "bg:#86BBD8";
          format = "[ $symbol ($version) ]($style)";
        };

        nodejs = {
          symbol = "";
          style = "bg:#86BBD8";
          format = "[ $symbol ($version) ]($style)";
        };

        nim = {
          symbol = "󰆥 ";
          style = "bg:#86BBD8";
          format = "[ $symbol ($version) ]($style)";
        };

        rust = {
          symbol = " ";
          style = "bg:#86BBD8";
          format = "[ $symbol ($version) ]($style)";
        };

        scala = {
          symbol = " ";
          style = "bg:#86BBD8";
          format = "[ $symbol ($version) ]($style)";
        };

        time = {
          disabled = false;
          time_format = "%R"; # Hour:Minute Format
          style = "bg:#33658A";
          format = "[ $time ]($style)";
        };
      };
    };
  };
}
