{
  pkgs,
  lib,
  ...
}:
let
  useFeatures = [
    "alacritty"
    #"emacs"
    "direnv"
    "git"
    "gpg"
    "gtk"
    #"keyring"
    "syncthing"
    "tmux"
    "xdg"
    "zsh"
    "helix"
  ];
  colors = {
    background = "ffffff";
    foreground = "000000";
    regular0 = "000000";
    regular1 = "000000";
    regular2 = "000000";
    regular3 = "000000";
    regular4 = "000000";
    regular5 = "000000";
    regular6 = "000000";
    regular7 = "000000";
    bright0 = "ffffff";
    bright1 = "ffffff";
    bright2 = "ffffff";
    bright3 = "ffffff";
    bright4 = "ffffff";
    bright5 = "ffffff";
    bright6 = "ffffff";
    bright7 = "ffffff";
  };
in
{
  imports = [
    ./dconf.nix
  ];

  home.stateVersion = "20.09";

  programs.gpg.settings.default-key = "99658A3EB5CD7C13";

  dadada.home =
    lib.attrsets.genAttrs useFeatures (useFeatures: {
      enable = true;
    })
    // {
      session = {
        enable = true;
        sessionVars = {
          EDITOR = "hx";
          PAGER = "less";
          MAILDIR = "\$HOME/.var/mail";
          MBLAZE = "\$HOME/.config/mblaze";
          NOTMUCH_CONFIG = "\$HOME/.config/notmuch/config";
        };
      };
    };

  # Languagetool server for web extension
  systemd.user.services."languagetool-http-server" = {
    Unit = {
      Description = "Languagetool HTTP server";
      PartOf = [ "graphical-session-pre.target" ];
      After = [ "graphical-session.target" ];
    };

    Service = {
      Type = "simple";
      ExecStart = "${pkgs.languagetool}/bin/languagetool-http-server org.languagetool.server.HTTPServer --allow-origin '*'";
      Restart = "always";
    };

    Install = {
      WantedBy = [ "graphical-session.target" ];
    };
  };

  programs.offlineimap.enable = false;
  xdg.configFile."offlineimap/config".text = ''
    [general]
    accounts = tu-bs,mailbox

    [Account tu-bs]
    localrepository = tu-bs-local
    remoterepository = tu-bs-remote

    [Repository tu-bs-local]
    type = Maildir
    localfolders = ~/lib/backup/y0067212@tu-bs.de

    [Repository tu-bs-remote]
    type = IMAP
    remotehost = mail.tu-braunschweig.de
    remoteuser = y0067212
    sslcacertfile = /etc/ssl/certs/ca-certificates.crt

    [Account mailbox]
    localrepository = mailbox-local
    remoterepository = mailbox-remote

    [Repository mailbox-local]
    type = Maildir
    localfolders = ~/lib/backup/mailbox.org

    [Repository mailbox-remote]
    type = IMAP
    remotehost = imap.mailbox.org
    remoteuser = dadada@dadada.li
    sslcacertfile = /etc/ssl/certs/ca-certificates.crt
  '';

  home.file.".jjconfig.toml".source = ./jjconfig.toml;

  systemd.user.timers."backup-keepassxc" = {
    Unit.Description = "Backup password DB";
    Timer = {
      OnBootSec = "15min";
      OnUnitActiveSec = "1d";
    };
    Install.WantedBy = [ "timers.target" ];
  };

  systemd.user.services."backup-keepassxc" = {
    Unit.Description = "Backup password DB";
    Unit.Type = "oneshot";
    Service.ExecStart = "${pkgs.openssh}/bin/scp -P 23 -i /home/dadada/.ssh/keepassxc-backup /home/dadada/lib/sync/Personal.kdbx u355513-sub4@u355513-sub4.your-storagebox.de:Personal.kdbx";
    Install.WantedBy = [ "multi-user.target" ];
  };

  systemd.user.timers."backup-keepassxc-ninurta" = {
    Unit.Description = "Backup password DB to ninurta";
    Timer = {
      OnBootSec = "15min";
      OnUnitActiveSec = "1d";
    };
    Install.WantedBy = [ "timers.target" ];
  };

  systemd.user.services."backup-keepassxc-ninurta" = {
    Unit.Description = "Backup password DB to ninurta";
    Unit.Type = "oneshot";
    Service.ExecStart = "${pkgs.openssh}/bin/scp -P 22 -i /home/dadada/.ssh/keepassxc-backup /home/dadada/lib/sync/Personal.kdbx backup-keepassxc@ninurta.bs.dadada.li:/mnt/storage/backups/backup-keepassxc/Personal.kdbx";
    Install.WantedBy = [ "multi-user.target" ];
  };

  programs.foot = {
    enable = true;
    server.enable = false;
    settings = {
      inherit colors;
      main = {
        shell = "tmux";
        font = "Jetbrains Mono:size=8";
        dpi-aware = false;
      };
      mouse.hide-when-typing = true;
      csd.preferred = "none";
      cursor.color = "fdf6e3 586e75";
      bell = {
        urgent = true;
        visual = false;
      };
    };
  };

  home.file.".config/sway/config".text = with colors; ''
    # Read `man 5 sway` for a complete reference.

    ### Variables
    #
    # Logo key. Use Mod1 for Alt.
    set $mod Mod4
    # Home row direction keys, like vim
    set $left h
    set $down j
    set $up k
    set $right l
    # Your preferred terminal emulator
    set $term foot
    # Your preferred application launcher
    # Note: pass the final command to swaymsg so that the resulting window can be opened
    # on the original workspace that the command was run on.
    set $menu fuzzel
    set $wallpaper "~/lib/pictures/wallpaper.jpg"

    ### Idle configuration
    #
    # Example configuration:
    #
    exec swayidle -w \
             timeout 300 'swaylock -f -i $wallpaper -s fill' \
             timeout 600 'swaymsg "output * power off"' resume 'swaymsg "output * power on"' \
             before-sleep 'swaylock -f -i $wallpaper -s fill'
    #
    # This will lock your screen after 300 seconds of inactivity, then turn off
    # your displays after another 300 seconds, and turn your screens back on when
    # resumed. It will also lock your screen before your computer goes to sleep.

    input * {
      xkb_layout eu
      xkb_model pc105+inet
      xkb_options caps:escape
        drag_lock enabled
        drag enabled
        dwt enabled
        tap enabled
        tap_button_map lrm
        natural_scroll enabled
    }

    ### Key bindings
    #
    # Basics:
    #
    # Start a terminal
    bindsym $mod+Return exec $term

    # Kill focused window
    bindsym $mod+Shift+q kill

    # Start your launcher
    bindsym $mod+d exec $menu

    # Drag floating windows by holding down $mod and left mouse button.
    # Resize them with right mouse button + $mod.
    # Despite the name, also works for non-floating windows.
    # Change normal to inverse to use left mouse button for resizing and right
    # mouse button for dragging.
    floating_modifier $mod normal

    # Lock the screen
    bindsym XF86Sleep exec 'swaylock -f -c ${background}'
    bindsym $mod+End exec 'swaylock -f -c ${background}'

    # Reload the configuration file
    bindsym $mod+Shift+c reload

    # Exit sway (logs you out of your Wayland session)
    bindsym $mod+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -B 'Yes, exit sway' 'swaymsg exit'

    # Brightness
    bindsym --locked XF86MonBrightnessDown exec light -U 10
    bindsym --locked XF86MonBrightnessUp exec light -A 10

    # Volume
    bindsym --locked XF86AudioRaiseVolume exec 'pactl set-sink-volume @DEFAULT_SINK@ +1%'
    bindsym --locked XF86AudioLowerVolume exec 'pactl set-sink-volume @DEFAULT_SINK@ -1%'
    bindsym --locked XF86AudioMute exec 'pactl set-sink-mute @DEFAULT_SINK@ toggle'

    #
    # Moving around:
    #
    # Move your focus around
    bindsym $mod+$left focus left
    bindsym $mod+$down focus down
    bindsym $mod+$up focus up
    bindsym $mod+$right focus right
    # Or use $mod+[up|down|left|right]
    bindsym $mod+Left focus left
    bindsym $mod+Down focus down
    bindsym $mod+Up focus up
    bindsym $mod+Right focus right

    # Move the focused window with the same, but add Shift
    bindsym $mod+Shift+$left move left
    bindsym $mod+Shift+$down move down
    bindsym $mod+Shift+$up move up
    bindsym $mod+Shift+$right move right
    # Ditto, with arrow keys
    bindsym $mod+Shift+Left move left
    bindsym $mod+Shift+Down move down
    bindsym $mod+Shift+Up move up
    bindsym $mod+Shift+Right move right

    #
    # Workspaces:
    #
    # Switch to workspace
    bindsym $mod+1 workspace number 1
    bindsym $mod+2 workspace number 2
    bindsym $mod+3 workspace number 3
    bindsym $mod+4 workspace number 4
    bindsym $mod+5 workspace number 5
    bindsym $mod+6 workspace number 6
    bindsym $mod+7 workspace number 7
    bindsym $mod+8 workspace number 8
    bindsym $mod+9 workspace number 9
    bindsym $mod+0 workspace number 10
    # Move focused container to workspace
    bindsym $mod+Shift+1 move container to workspace number 1
    bindsym $mod+Shift+2 move container to workspace number 2
    bindsym $mod+Shift+3 move container to workspace number 3
    bindsym $mod+Shift+4 move container to workspace number 4
    bindsym $mod+Shift+5 move container to workspace number 5
    bindsym $mod+Shift+6 move container to workspace number 6
    bindsym $mod+Shift+7 move container to workspace number 7
    bindsym $mod+Shift+8 move container to workspace number 8
    bindsym $mod+Shift+9 move container to workspace number 9
    bindsym $mod+Shift+0 move container to workspace number 10
    # Note: workspaces can have any name you want, not just numbers.
    # We just use 1-10 as the default.

    #
    # Layout stuff:
    #
    # You can "split" the current object of your focus with
    # $mod+b or $mod+v, for horizontal and vertical splits
    # respectively.
    bindsym $mod+b splith
    bindsym $mod+v splitv

    # Switch the current container between different layout styles
    bindsym $mod+s layout stacking
    bindsym $mod+w layout tabbed
    bindsym $mod+e layout toggle split

    # Make the current focus fullscreen
    bindsym $mod+f fullscreen

    # Toggle the current focus between tiling and floating mode
    bindsym $mod+Shift+space floating toggle

    # Swap focus between the tiling area and the floating area
    bindsym $mod+space focus mode_toggle

    # Move focus to the parent container
    bindsym $mod+a focus parent

    #
    # Font
    #
    font "pango:Jetbrains Mono 8"

    #
    # Scratchpad:
    #
    # Sway has a "scratchpad", which is a bag of holding for windows.
    # You can send windows there and get them back later.

    # Move the currently focused window to the scratchpad
    bindsym $mod+Shift+minus move scratchpad

    # Show the next scratchpad window or hide the focused scratchpad window.
    # If there are multiple scratchpad windows, this command cycles through them.
    bindsym $mod+minus scratchpad show

    #
    # Resizing containers:
    #
    mode "resize" {
        # left will shrink the containers width
        # right will grow the containers width
        # up will shrink the containers height
        # down will grow the containers height
        bindsym $left resize shrink width 10px
        bindsym $down resize grow height 10px
        bindsym $up resize shrink height 10px
        bindsym $right resize grow width 10px

        # Ditto, with arrow keys
        bindsym Left resize shrink width 10px
        bindsym Down resize grow height 10px
        bindsym Up resize shrink height 10px
        bindsym Right resize grow width 10px

        # Return to default mode
        bindsym Return mode "default"
        bindsym Escape mode "default"
    }
    bindsym $mod+r mode "resize"

    #
    # Status Bar:
    #
    # Read `man 5 sway-bar` for more information about this section.
    bar {
        position bottom

        # When the status_command prints a new line to stdout, swaybar updates.
        # The default just shows the current date and time.
        status_command ~/.config/sway/status

        colors {
            statusline ${foreground}
            background ${background}
            inactive_workspace ${background}ee ${background}ee ${foreground}ee
        }
    }

    # Gaps between multiple tiling windows
    gaps inner 10
    smart_gaps on

    bindsym $mod+grave exec busctl --user call org.keepassxc.KeePassXC.MainWindow /keepassxc org.keepassxc.KeePassXC.MainWindow lockAllDatabases && swaylock -c #fdf6e3

    # class                 border         backgr.        text           indicator      child_border
    client.focused          #${background} #${foreground} #${background} #${foreground} #${background}
    client.focused_inactive #${background} #${background} #${foreground} #${foreground} #${background}
    client.unfocused        #${background} #${background} #${foreground} #${foreground} #${background}
    client.urgent           #${background} #${background} #${foreground} #${foreground} #${background}
    client.placeholder      #${background} #${background} #${foreground} #${foreground} #${background}

    client.background       #${foreground}

    include /etc/sway/config.d/*

    exec sleep 5; systemctl --user restart kanshi.service
    exec sleep 5; swaymsg output '*' bg $wallpaper fill
  '';
  home.file.".config/sway/status".source = ./status;
  home.file.".config/kanshi/config".text = ''
    profile Laptop {
      output eDP-1 enable
    }

    profile Docked {
      output eDP-1 disable
      output "LG Electronics LG HDR 4K 0x000354D1" {
        enable
        scale 1.4
        position 0,0
      }
    }
  '';

  services.poweralertd.enable = true;

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

  home.packages = import ./pkgs.nix { pkgs = pkgs; };
}