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

let
  aercPackage = pkgs.unstable.aerc.override {
    # support .filename filter
    buildGoModule = args: pkgs.unstable.buildGoModule (args // rec {
      version = "6ffc0ed5991bef69a50cbc22647af0a6a0e0a895";
      src = pkgs.fetchFromSourcehut {
        owner = "~rjarry";
        repo = "aerc";
        rev = version;
        hash = "sha256-IyAcTCDSjOmZ6KPr9nYKdxWA0qryeU4jTwxRWzt2NOY=";
      };
      vendorHash = "sha256-s7lt5amq6Zsn+1AM2SlNeXSZIRbJ+vYKZmdWEDC4Sp4=";
    });
  };

  abaPackage = pkgs.unstable.aba;
  abaExe = "${abaPackage}/bin/aba -a ${config.xdg.dataHome}/aerc/aba.toml";

  pipeAba = param: exec "pipe -m ${abaExe} parse ${param}";
  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";
    "af" = pipeAba "--from";
    "at" = pipeAba "--to";
    "ac" = pipeAba "--cc";
    "aa" = pipeAba "--all";
  };
in
{
  options.local.programs.aerc.enable = lib.mkEnableOption "aerc";

  config = lib.mkIf config.local.programs.aerc.enable {
    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 = aercPackage;
      # https://git.sr.ht/~rjarry/aerc/tree/master/item/doc/aerc-config.5.scd
      extraConfig = {
        general = {
          unsafe-accounts-conf = true;
          pgp-provider = "gpg";
        };

        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 \", \" }}";
        };

        compose = {
          address-book-cmd = "${abaExe} list '%s'";
        };

        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/*" = "cat | colorize";
          "application/pgp-keys" = "gpg";
          ".filename,~\\.gpg" = "gpg --decrypt";
          ".filename,~\\.xml\\.gz" = "${pkgs.gzip}/bin/gunzip |"
            + "${pkgs.xmlformat}/bin/xmlformat |"
            + "${pkgs.bat}/bin/bat -fpp --file-name='$AERC_FILENAME' --language xml";
        };

        openers = { };

        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";
          }
        ];

        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 = {
          "$ex" = "<C-x>";
          "<C-k>" = exec "prev-field";
          "<C-j>" = exec "next-field";
          "<tab>" = exec "next-field";
          "<C-l>" = exec "next-tab";
          "<C-h>" = exec "prev-tab";
        };

        "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.bg" = 6;
        "*.selected.fg" = 18;
        "*.selected.bold" = true;
        "statusline_*.dim" = true;
        "statusline_*.bg" = 0;
        "statusline_*.fg" = 15;
        "*warning.fg" = 3;
        "*success.fg" = 2;
        "*error.fg" = 1;
        "*error.bold" = true;
        "border.fg" = 15;
        "title.bg" = 12;
        "title.fg" = 15;
        "title.bold" = true;
        "header.fg" = 4;
        "header.bold" = true;
        "msglist_read.selected.fg" = 0;
        "msglist_unread.bold" = true;
        "msglist_deleted.dim" = true;
        "msglist_marked.bg" = 6;
        "msglist_marked.fg" = 15;
        "msglist_pill.bg" = 12;
        "msglist_pill.fg" = 15;
        "part_mimetype.fg" = 12;
        "selector_chooser.bold" = true;
        "selector_focused.bold" = true;
        "selector_focused.bg" = 12;
        "selector_focused.fg" = 15;
        "completion_pill.bg" = 12;
        "completion_default.bg" = 8;
        "completion_default.fg" = 15;
      };
    };
  };
}