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

let
  exec = cmd: ":${cmd}<Enter>";
  fill = cmd: ":${cmd}<space>";

  globalBinds = {
    "gt" = exec "next-tab";
    "gT" = exec "prev-tab";
  };

  commonMessageBinds = {
    "U" = exec "unsubscribe";
    "dd" = exec "delete";
    "mA" = exec "archive flat";
    "mS" = exec "move Junk";
    "mI" = exec "move INBOX";
  };
in
{
  accounts.email.maildirBasePath = "${config.xdg.dataHome}/mail";

  # See: https://git.sbruder.de/simon/nixos-config/src/branch/master/users/simon/modules/mail/aerc/default.nix
  programs.aerc = {
    enable = true;
    package = pkgs.unstable.aerc;
    # https://git.sr.ht/~rjarry/aerc/tree/master/item/doc/aerc-config.5.scd
    extraConfig = {
      general = {
        unsafe-accounts-conf = true;
      };

      ui = {
        # See https://godoc.org/time#Time.Format
        timestamp-format = "2006-01-02 15:04 MST";
        this-day-time-format = "15:04";
        this-week-time-format = "Monday 15:04";
        this-year-time-format = "02 January";
        pinned-tab-marker = "車";
        border-char-vertical = "│";
        border-char-horizontal = "─";
        fuzzy-complete = true;
        new-message-bell = true;
        index-columns = "date<20,from<30,flags>4,subject<*";
        column-from = "{{ .From | emails | join \", \" }}";
      };

      statusline = {
        display-mode = "icon";
      };

      filters = {
        ".headers" = "colorize";
        "text/html" = "html | colorize";
        "text/plain" = "colorize";
        "text/rfc822-headers" = "colorize";
        # "text/*" = "${pkgs.bat}/bin/bat -fpp --file-name='$AERC_FILENAME'";
        "message/delivery-status" = "cat | colorize";
      };

      hooks = {
        mail-received = "notify-send \"New mail from $AERC_FROM_NAME\" \"$AERC_SUBJECT\"";
      };
    };
    extraBinds = {
      messages = lib.mkMerge [
        globalBinds
        commonMessageBinds
        {
          "q" = exec "quit";

          "j" = exec "next";
          "<Down>" = exec "next";
          "<C-d>" = exec "next 50%";

          "k" = exec "prev";
          "<Up>" = exec "prev";
          "<C-b>" = exec "prev 50%";

          "gg" = exec "select 0";
          "G" = exec "select -1";

          "J" = exec "next-folder";
          "K" = exec "prev-folder";
          "c" = fill "cf";

          "<Enter>" = exec "view";
          "C" = exec "compose";

          "/" = fill "search";
          "\\" = fill "filter";
          "n" = exec "next-result";
          "N" = exec "prev-result";
          #"D" = exec "modify-labels +deleted -inbox";
          #"A" = exec "modify-labels -inbox";
          #"ms" = exec "modify-labels +spam -inbox";
          #"mS" = exec "modify-labels -spam +inbox";
        }
      ];

      view = lib.mkMerge [
        globalBinds
        commonMessageBinds
        {
          "q" = exec "close";
          "O" = exec "open";
          "S" = fill "save";

          "f" = exec "forward";

          "rr" = exec "reply -a";
          "rq" = exec "reply -aq";
          "Rr" = exec "reply";
          "Rq" = exec "reply -q";

          "<C-k>" = exec "prev-part";
          "<C-j>" = exec "next-part";
          "J" = exec "next";
          "K" = exec "prev";
        }
      ];

      compose = lib.mkMerge [
        globalBinds
        {
          "$ex" = "<C-x>";
          "<C-k>" = exec "prev-field";
          "<C-j>" = exec "next-field";
          "<tab>" = exec "next-field";
        }
      ];

      "compose::editor" = {
        "$noinherit" = "true";
        "$ex" = "<C-x>";
        "<C-k>" = exec "prev-field";
        "<C-j>" = exec "next-field";
      };

      "compose::review" = {
        "y" = exec "send";
        "n" = exec "abort";
        "p" = exec "postpone";
        "q" = exec "choose -o d discard abort -o p postpone postpone";
        "e" = exec "edit";
        "a" = fill "attach";
        "d" = fill "detach";
      };
    };

    stylesets.default = {
      "*.selected.reverse" = true;
      "title.reverse" = true;
      "header.bold" = true;
      "*error.bold" = true;
      "error.fg" = 1;
      "warning.fg" = 3;
      "success.fg" = 2;
      "msglist_unread.bold" = true;
      "msglist_deleted.fg" = 10;
      "tab.fg" = 0;
      "tab.selected.reverse" = false;
      "tab.selected.bold" = true;
      "tab.selected.bg" = 2;
      "dirlist_default.bg" = 18;
      "border.fg" = 0;
      "statusline_default.bg" = 18;
      "statusline_error.fg" = 1;
      "statusline_error.reverse" = true;
      "statusline_success.fg" = 2;
      "statusline_success.reverse" = true;
      "completion_default.bg" = 0;
    };
  };
}
