{
  lib,
  pkgs,
  config,
  ...
}:
with lib;
let
  cfg = config.eboskma.programs.i3;
  mod = "Mod4";
  i3lockcmd = "${pkgs.i3lock-color}/bin/i3lock-color --image ${toString ../../../wallpapers/river-3840.png} --color=333333ff --tiling --ignore-empty-password --show-failed-attempts --screen=0 --clock --pass-volume-keys";
  rofiPower = pkgs.writeShellScriptBin "rofi-power" (builtins.readFile ./powermenu.sh);
  left = "n";
  down = "e";
  up = "i";
  right = "o";

  workspacePartition = builtins.partition (n: (trivial.mod n 2) != 0) (lists.range 1 10);

  menu = "${pkgs.rofi}/bin/rofi -show drun -no-lazy-grab";
in
{
  options.eboskma.programs.i3 = {
    enable = mkEnableOption "Enable i3";
    startupCommands = mkOption {
      description = "Commands to run at startup";
      type = types.listOf types.attrs;
      default = [ ];
    };
  };

  config = mkIf cfg.enable {
    xsession = {
      enable = true;
      numlock.enable = true;

      windowManager.i3 = {
        enable = true;
        config = {
          inherit menu;
          modifier = mod;

          assigns = {
            "1" = [ { class = "Firefox"; } ];
            "2" = [
              { class = "Alacritty"; }
              { class = "foot"; }
            ];
            "3" = [
              { class = "Code"; }
              { class = "Emacs"; }
            ];
            "4" = [
              { class = "telegramdesktop"; }
              { class = "Signal"; }
            ];
          };
          # Dracula theme
          colors = {
            background = "#f8f8f2";
            focused = {
              border = "#6272a4";
              background = "#6272A4";
              text = "#f8f8f2";
              indicator = "#6272a4";
              childBorder = "#6272a4";
            };
            focusedInactive = {
              border = "#44475a";
              background = "#44475a";
              text = "#f8f8f2";
              indicator = "#44475a";
              childBorder = "#44475a";
            };
            unfocused = {
              border = "#282a36";
              background = "#282a36";
              text = "#bfbfbf";
              indicator = "#282a36";
              childBorder = "#282a36";
            };
            urgent = {
              border = "#44475a";
              background = "#ff5555";
              text = "#f8f8f2";
              indicator = "#ff5555";
              childBorder = "#ff5555";
            };
            placeholder = {
              border = "#282a36";
              background = "#282a36";
              text = "#f8f8f2";
              indicator = "#282a36";
              childBorder = "#282a36";
            };
          };

          floating = {
            criteria = [
              { instance = "gnome-calculator"; }
              { class = "Pavucontrol"; }
            ];
            modifier = mod;
          };

          fonts = {
            names = [ "Iosevka Nerd Font" ];
            style = "Regular";
            size = 12.0;
          };

          gaps = {
            inner = 10;
            outer = 5;
            smartBorders = "on";
          };

          keybindings = {
            "${mod}+Return" = "exec --no-startup-id ${config.xsession.windowManager.i3.config.terminal}";
            "${mod}+Shift+q" = "kill";
            "${mod}+s" = "exec --no-startup-id ${config.xsession.windowManager.i3.config.menu}";
            "${mod}+Shift+s" = "exec --no-startup-id ${pkgs.rofi}/bin/rofi -no-lazy-grab -show run";

            "${mod}+${left}" = "focus left";
            "${mod}+${down}" = "focus down";
            "${mod}+${up}" = "focus up";
            "${mod}+${right}" = "focus right";

            "${mod}+Left" = "focus left";
            "${mod}+Down" = "focus down";
            "${mod}+Up" = "focus up";
            "${mod}+Right" = "focus right";

            "${mod}+Shift+${left}" = "move left";
            "${mod}+Shift+${down}" = "move down";
            "${mod}+Shift+${up}" = "move up";
            "${mod}+Shift+${right}" = "move right";

            "${mod}+Shift+Left" = "move left";
            "${mod}+Shift+Down" = "move down";
            "${mod}+Shift+Up" = "move up";
            "${mod}+Shift+Right" = "move right";

            "${mod}+h" = "split h";
            "${mod}+v" = "split v";
            "${mod}+t" = "fullscreen toggle";
            "${mod}+a" = "focus parent";

            "${mod}+r" = "layout stacking";
            "${mod}+w" = "layout tabbed";
            "${mod}+f" = "layout toggle split";

            "${mod}+Shift+space" = "floating toggle";
            "${mod}+space" = "focus mode_toggle";

            "${mod}+1" = "workspace number 1";
            "${mod}+2" = "workspace number 2";
            "${mod}+3" = "workspace number 3";
            "${mod}+4" = "workspace number 4";
            "${mod}+5" = "workspace number 5";
            "${mod}+6" = "workspace number 6";
            "${mod}+7" = "workspace number 7";
            "${mod}+8" = "workspace number 8";
            "${mod}+9" = "workspace number 9";
            "${mod}+0" = "workspace number 10";

            "${mod}+Shift+1" = "move container to workspace number 1";
            "${mod}+Shift+2" = "move container to workspace number 2";
            "${mod}+Shift+3" = "move container to workspace number 3";
            "${mod}+Shift+4" = "move container to workspace number 4";
            "${mod}+Shift+5" = "move container to workspace number 5";
            "${mod}+Shift+6" = "move container to workspace number 6";
            "${mod}+Shift+7" = "move container to workspace number 7";
            "${mod}+Shift+8" = "move container to workspace number 8";
            "${mod}+Shift+9" = "move container to workspace number 9";
            "${mod}+Shift+0" = "move container to workspace number 10";

            "${mod}+Shift+minus" = "move scratchpad";
            "${mod}+minus" = "scratchpad show";

            "${mod}+Shift+c" = "reload";
            "${mod}+Shift+p" = "restart";

            "${mod}+Shift+f" = "exec --no-startup-id ${rofiPower}/bin/rofi-power";
            "${mod}+l" = "exec --no-startup-id ${i3lockcmd}";
            "${mod}+p" = "mode resize";

            "${mod}+Pause" = "mode passthrough";

            "${mod}+c" = "exec --no-startup-id emacsclient -c";

            "${mod}+Print" = "exec --no-startup-id ${pkgs.maim}/bin/maim --window $(${pkgs.xdotool}/bin/xdotool getactivewindow) ~/$(${pkgs.coreutils}/bin/date '+%Y-%m-%d-%T')-screenshot.png";
            "${mod}+Shift+Print" = "exec --no-startup-id ${pkgs.maim}/bin/maim --window $(${pkgs.xdotool}/bin/xdotool getactivewindow) | ${pkgs.xclip}/bin/xclip -selection clipboard -t image/png";
            "${mod}+Shift+Ctrl+Print" = "exec --no-startup-id ${pkgs.maim}/bin/maim -s | ${pkgs.xclip}/bin/xclip -selection clipboard -t image/png";

            "XF86AudioRaiseVolume" = "exec --no-startup-id ${pkgs.pamedia}/bin/pamedia up";
            "XF86AudioLowerVolume" = "exec --no-startup-id ${pkgs.pamedia}/bin/pamedia down";
            "XF86AudioMute" = "exec --no-startup-id ${pkgs.pamedia}/bin/pamedia mute";
            "XF86Calculator" = "exec ${pkgs.gnome-calculator}/bin/gnome-calculator";
          };

          modes = {
            passthrough = {
              "${mod}+Pause" = "mode default";
            };
          };

          terminal = "${pkgs.alacritty}/bin/alacritty";

          window = {
            border = 1;
            titlebar = false;
          };

          bars = [ ];

          workspaceAutoBackAndForth = true;
          workspaceOutputAssign = builtins.concatLists (
            builtins.attrValues (
              builtins.mapAttrs (
                name: workspaces:
                let
                  output = if name == "right" then "DP-0" else "DP-4";
                in
                builtins.map (ws: {
                  inherit output;
                  workspace = toString ws;
                }) workspaces
              ) workspacePartition
            )
          );
          # [
          #   { output = "DP-0"; workspace = "1"; }
          # ];

          startup = [
            {
              command = "/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1";
              notification = false;
            }
            {
              command = "${pkgs.networkmanagerapplet}/bin/nm-applet";
              notification = false;
            }
          ] ++ cfg.startupCommands;
        };
        extraConfig = "";
      };
    };

    home = {
      packages = with pkgs; [ dunst ];
    };
  };
}