{ config, pkgs, mail, ... }:

{
  imports = [ ./nixvim ];

  config = {
    home.username = "rothe";
    home.homeDirectory = "/home/rothe";

    # Add extra variables like $EDITOR
    home.sessionVariables = {
    };

    home.packages = with pkgs; [
      black
      devenv
      fzf
      gitleaks
      go
      gopls
      gotools
      goreleaser
      htop
      jq
      pylint
      python311
      python311Packages.flake8
      python311Packages.ipython
      pyright
      ripgrep
      ruff
      rusti-cal
      roboto-mono
      silver-searcher
      shellcheck
      sops
      (nerdfonts.override { fonts = [
        "JetBrainsMono"
        "RobotoMono"
      ]; })
    ];
    fonts.fontconfig.enable = true;

    programs.fish = {
      enable = true;
      # disable greeting
      shellInit = ''
      set fish_greeting
      fish_add_path ~/bin/
      fish_add_path ~/go/bin/
      export DEBFULLNAME="Johannes Rothe"
      export DEBEMAIL="${mail}"
      export GIT_EDITOR="nvim"
      export GIT_AUTHOR_NAME="Johannes Rothe"
      export GIT_AUTHOR_EMAIL="${mail}"
      export GIT_COMMITTER_NAME="Johannes Rothe"
      export GIT_COMMITTER_EMAIL="${mail}"
      export VAULT_ADDR="https://passwords.magazino.eu:8201"
      export NIX_PATH=$HOME/.nix-defexpr/channels
      fzf --fish | source
      '';
      shellAliases = {
        "..." = "cd ../..";
        "t" = "terraform";
        "n" = "nvim";
        "cds" = "cd ~/src/";
        "cdc" = "cd ~/catkin_ws/src/";
        "ll" = "ls -lh";
        "cal" = "rusti-cal --color -w";
        "ip" = "ip -c";
        "preview" = "mpv av://v4l2:/dev/video0 --profile=low-latency";
        "cam" = "gphoto2 --stdout --capture-movie | ffmpeg -i - -vcodec rawvideo -pix_fmt yuv420p -threads 0 -f v4l2 /dev/video0";
        "upd" = "sudo apt update";
        "upg" = "sudo apt upgrade";
        "gch" = "git checkout “$(git branch --all | fzf | tr -d ‘[:space:]’)”";
      };
    };

    programs.git = {
      enable = true;
      userEmail = "${mail}";
      userName = "Johannes Rothe";
      aliases = {
        a = "add";
        ci = "commit";
        ca = "commit --amend --no-edit";
        ds = "diff --staged";
        df = "diff";
        st = "status";
        co = "checkout";
        br = "branch";
        p = "pull -r";
      };
      lfs = {
        enable = true;
      };
      difftastic = {
        enable = true;
        background = "dark";
      };
      extraConfig = {
        core = {
          editor = "nvim";
        };
      };
    };

    programs.tmux = {
      enable = true;
      prefix = "C-a";
      historyLimit = 150000;
      keyMode = "vi";
      customPaneNavigationAndResize = true;
      plugins = with pkgs.tmuxPlugins; [
        yank
        vim-tmux-navigator
      ];
      extraConfig = ''
      bind-key Space next-window

      set -g status-right '#[fg=colour242]#S'
      set -g status-left ' '
      set -g window-status-format '#I:#W'
      set -g window-status-current-format '#I:#W'
      set -g allow-rename off

      # Start windows and panes at 1, not 0
      set -g base-index 1
      setw -g pane-base-index 1

      # default statusbar colors
      set-option -g status-style bg=colour232,fg=colour239,default

      # border
      set -g pane-border-style fg=colour234,bg=default
      set -g pane-active-border-style fg=colour236,bg=default

      # active window title colors
      set-window-option -g window-status-current-style fg=colour231,bg=default
      set-window-option -g window-status-style fg=colour239,bg=default

      # bell
      set-window-option -g window-status-bell-style fg=colour232,bg=colour253

      # Correct colors
      set -g default-terminal "tmux-256color"
      set -ga terminal-overrides ",*256col*:Tc"

      # Keybindings for yank
      bind-key -T copy-mode-vi v send-keys -X begin-selection
      bind-key -T copy-mode-vi C-v send-keys -X rectangle-toggle
      bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel

      # Open split with current working directory
      bind '"' split-window -v -c "#{pane_current_path}"
      bind % split-window -h -c "#{pane_current_path}"
      '';
    };

    programs.vim = {
      enable = true;
      defaultEditor = true;
      # List of supported plugins: nix-env -f '<nixpkgs>' -qaP -A vimPlugins
      # TODO Black plugin missing
      plugins = [
        pkgs.vimPlugins.ale
        pkgs.vimPlugins.committia
        pkgs.vimPlugins.gitgutter
        pkgs.vimPlugins.indentLine
        pkgs.vimPlugins.polyglot
        pkgs.vimPlugins.nerdtree
        pkgs.vimPlugins.rainbow
        pkgs.vimPlugins.sonokai
        pkgs.vimPlugins.vim-airline
        pkgs.vimPlugins.vim-devicons
        pkgs.vimPlugins.vim-go
        pkgs.vimPlugins.vim-hcl
        pkgs.vimPlugins.vim-isort
        pkgs.vimPlugins.vim-terraform
        pkgs.vimPlugins.YouCompleteMe
      ];
      extraConfig = ''
      set number
      set nocompatible
      set colorcolumn=88
      set background=dark
      set cursorline
      set encoding=utf-8

      " Theme
      if has('termguicolors')
        set termguicolors
      endif
      let g:sonokai_style = "atlantis"
      let g:sonokai_disable_italic_comment = 1
      colorscheme sonokai
      let g:airline_theme = "sonokai"

      " Filetypes
      au BufNewFile,BufRead *.launch set filetype=xml

      augroup indent
        autocmd FileType python,go,dockerfile,js,toml :set tabstop=4 softtabstop=4 shiftwidth=4 expandtab autoindent fileformat=unix
        autocmd FileType terraform,sh,json,yaml,html,css :set tabstop=2 softtabstop=2 shiftwidth=2 expandtab autoindent fileformat=unix
      augroup end

      augroup spell
        autocmd FileType gitcommit :set spell
        autocmd FileType git :set nospell
        autocmd FileType markdown :set spell
      augroup end

      augroup shortcuts
        autocmd FileType terraform nnoremap <F9> :! terraform fmt<CR>
        autocmd FileType python nnoremap <F9> :Black<CR> :Isort <CR>
        autocmd FileType go nnoremap <F9> <Plug>(go-fmt)<Plug>(go-lint)
        autocmd FileType go nnoremap <F7> <Plug>(go-build)
        autocmd FileType go nnoremap <F8> <Plug>(go-run)
        autocmd FileType go nnoremap gd <Plug>(go-def)
      augroup end

      " Ale
    let g:ale_linters = {'python': ['flake8', 'mypy'],'javascript': ['eslint']}
    let g:ale_fixers = {'python': ['black', 'isort']}
    let g:ale_python_pylint_options = '--disable=C0111,C0114'

      " YouCompleteMe
      let g:ycm_gopls_binary_path = "${pkgs.gopls}/bin/gopls"

      " Black
      let g:black_linelength = 88

      " NERDTREE
      " open nerdtree when no file is specified on startup
      autocmd StdinReadPre * let s:std_in=1
      autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
      " toggle nerdtree keyboard shortcut
      map <C-t> :NERDTreeToggle<CR>

      " Devicons
      let g:webdevicons_conceal_nerdtree_brackets = 1
      syntax enable
      if exists("g:loaded_webdevicons")
        call webdevicons#refresh()
      endif

      " terraform
      let g:terraform_fmt_on_save = 1
      let g:terraform_align = 1

      hi clear SpellBad
      hi SpellBad cterm=underline ctermfg=red
      '';
    };

    programs.ssh = {
      enable = true;
      extraConfig = ''
      AddKeysToAgent yes
      SendEnv GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
      '';
    };

    programs.newsboat = {
      enable = true;
      extraConfig = "
      urls-source \"miniflux\"\n
      miniflux-url \"https://feeds.johannes-rothe.de/\"\n
      miniflux-login \"johannes\"\n
      miniflux-passwordfile ~/.minifluxpw\n
      ";
    };

    programs.direnv = {
      enable = true;
    };

    home.file = {
      "${config.xdg.configHome}/ghostty/config".source = ./ghostty/config;
    };

    # This value determines the Home Manager release that your configuration is
    # compatible with. This helps avoid breakage when a new Home Manager release
    # introduces backwards incompatible changes.
    #
    # You should not change this value, even if you update Home Manager. If you do
    # want to update the value, then make sure to first check the Home Manager
    # release notes.
    home.stateVersion = "23.05"; # Please read the comment before changing.

    # Let Home Manager install and manage itself.
    programs.home-manager.enable = true;
  };
}