{ config, pkgs, lib, ... }:
let
  passcmd = id: "${pkgs.pass}/bin/pass ${id}";
  ticks = "''";

in
{

  # Maildir <-> Server communication
  # --------------------------------
  # mbsync: MailDir <-> IMAP
  # msmtp: sendmail interface sending mails through your provider.

  # client backend
  # --------------
  # notmuch: Tagdatabase for Emails
  # muchsync: notmuch database synctool

  # clients
  # -------
  # neomutt

  home-manager.users.mainUser.accounts.email.accounts = {
    #palo_van_dalo-gmx = {
    #  address = "palo_van_dalo@gmx.de";
    #  aliases = [ ];
    #  realName = "Ingolf Wagner";
    #  userName = "palo_van_dalo@gmx.de";
    #  passwordCommand = passcmd "mail/gmx/palo_van_dalo@gmx.de";
    #  smtp = {
    #    host = "smtp.gmx.net";
    #    port = 465;
    #  };
    #  notmuch.enable = true;
    #  msmtp = { enable = true; };
    #};
    #ingolf-wagner-gmx = {
    #  address = "ingolf.wagner@gmx.de";
    #  aliases = [ ];
    #  realName = "Ingolf Wagner";
    #  userName = "ingolf.wagner@gmx.de";
    #  passwordCommand = passcmd "mail/gmx/ingolf.wagner@gmx.de";
    #  smtp = {
    #    host = "smtp.gmx.net";
    #    port = 465;
    #  };
    #  notmuch.enable = true;
    #  msmtp = { enable = true; };
    #};
    #pali_palo = {
    #  address = "pali_palo@web.de";
    #  aliases = [ ];
    #  realName = "Ingolf Wagner";
    #  userName = "pali_palo@web.de";
    #  passwordCommand = passcmd "mail/web.de/pali_palo@web.de";
    #  smtp = {
    #    host = "smtp.web.de";
    #    port = 465;
    #  };
    #  notmuch.enable = true;
    #  msmtp = { enable = true; };
    #};
    gmail = {
      # for google accounts you have to allow 'less secure apps' in accounts.google.com
      primary = true;
      address = "palipalo9@googlemail.com";
      aliases = [ ];
      realName = "Ingolf Wagner";
      userName = "palipalo9@googlemail.com";
      passwordCommand = passcmd "mail/gmail/palipalo9@googlemail.com";
      smtp = {
        host = "smtp.gmail.com";
        port = 465;
      };
      notmuch.enable = true;
      msmtp = {
        enable = true;
      };
      gpg = {
        encryptByDefault = true;
        signByDefault = true;
        key = "42AC51C9482D0834CF488AF1389EC2D64AC71EAC";
      };
    };
    terranix_org = {
      address = "palo@terranix.org";
      aliases = [ ];
      realName = "Ingolf Wagner";
      userName = "palo@terranix.org";
      passwordCommand = passcmd "mail/namecheap/palo@terranix.org";
      smtp = {
        host = "mail.privateemail.com";
        port = 465;
      };
      notmuch.enable = true;
      msmtp = {
        enable = true;
      };
    };
    ingolf-wagner = {
      address = "contact@ingolf-wagner.de";
      aliases = [ ];
      realName = "Ingolf Wagner";
      userName = "contact@ingolf-wagner.de";
      passwordCommand = passcmd "mail/namecheap/contact@ingolf-wagner.de";
      notmuch.enable = true;
      gpg = {
        encryptByDefault = true;
        signByDefault = true;
        key = "42AC51C9482D0834CF488AF1389EC2D64AC71EAC";
      };
      smtp = {
        host = "mail.privateemail.com";
        port = 465;
      };
      msmtp = {
        enable = true;
        # msmtp --serverinfo --tls --tls-certcheck=off -a ingolf-wagner
      };
    };
  };

  # install mail programs
  home-manager.users.mainUser.programs.msmtp.enable = true;
  home-manager.users.mainUser.programs.notmuch.enable = true;

  # enable html emails
  home-manager.users.mainUser.home.file.".mailcap".text = ''
    text/html; ${pkgs.elinks}/bin/elinks -dump ; copiousoutput;
  '';

  home-manager.users.mainUser.home.file.".muttrc".text =
    let

      index_format = pkgs.writers.writeDash "index_format" ''
        # http://www.mutt.org/doc/manual/#formatstrings
        recipent="$(echo $1 | sed 's/[^,]*<\([^>]*\)[^,]*/ \1/g')"
        echo "%4C %Z %?GI?%GI& ? %[%y-%m-%d %H:%M] %-20.20a %?M?(%3M)& ? %s %> $recipent %?g?%g?%"
      '';
    in
    ''
      # gpg
      set crypt_use_gpgme=yes
      set crypt_autosign=yes
      set crypt_verify_sig=yes
      set crypt_replysign=yes
      set crypt_replyencrypt=yes
      set crypt_replysignencrypted=yes

      # mutt is not smart enough to see if I have a key or not
      #set crypt_autoencrypt = yes

      set pgp_check_gpg_decrypt_status_fd
      set pgp_use_gpg_agent = yes
      set pgp_self_encrypt = yes # needs default key
      set pgp_default_key = 42AC51C9482D0834CF488AF1389EC2D64AC71EAC

      # read html mails
      auto_view text/html
      set mailcap_path = ~/.mailcap

      # notmuch
      set nm_default_uri="notmuch://$HOME/Maildir" # path to the maildir
      set nm_record = yes
      set nm_record_tags = "-inbox me archive"
      set nm_query_type = "threads"                # we are not only interessted in messages
      set virtual_spoolfile=yes                    # enable virtual folders

      set sendmail=${
        pkgs.writers.writeBash "msmtp" ''
          ${pkgs.coreutils}/bin/tee >(${pkgs.notmuch}/bin/notmuch insert --create-folder +sent) | \
          ${pkgs.msmtp}/bin/msmtpq "$@"
        ''
      }

      set from="contact@ingolf-wagner.de"
      #alternates ^.*@ingolf-wagner\.de$ ^.*@.*\.r$
      set use_from=yes
      set envelope_from=yes
      set reverse_name

      set sort=threads

      set index_format="${index_format} %r |"
      folder-hook 'Discourse.*'            'set sort=reverse-date'

      virtual-mailboxes "INBOX" "notmuch://?query=(tag:inbox or (tag:sent and not tag:archive)) AND NOT tag:muted AND NOT tag:list AND NOT tag:fraud AND NOT tag:junk"
      virtual-mailboxes "Unread" "notmuch://?query=(tag:unread AND NOT tag:muted)"
      virtual-mailboxes "Space left" "notmuch://?query=((tag:spaceleft OR tag:space-lef) AND NOT tag:muted)"
      virtual-mailboxes "Sononym" "notmuch://?query=(tag:sononym AND NOT tag:muted)"
      virtual-mailboxes "c-base" "notmuch://?query=(tag:cbase AND NOT tag:muted)"
      virtual-mailboxes "shopping" "notmuch://?query=((tag:billing OR tag:shopping) AND NOT tag:muted)"
      virtual-mailboxes "Immobilien" "notmuch://?query=(tag:immobilien AND NOT tag:muted)"
      virtual-mailboxes "NixOS Github" "notmuch://?query=(tag:github AND tag:nixos AND NOT tag:muted)"
      virtual-mailboxes "Discourse.all" "notmuch://?query=(tag:discourse AND NOT tag:muted)"
      virtual-mailboxes "Discourse.development" "notmuch://?query=(tag:discourse AND tag:development AND NOT tag:muted)"
      virtual-mailboxes "Discourse.announcements" "notmuch://?query=(tag:discourse AND tag:announcements AND NOT tag:muted)"
      virtual-mailboxes "Discourse.links" "notmuch://?query=(tag:discourse AND tag:links AND NOT tag:muted)"
      virtual-mailboxes "Discourse.games" "notmuch://?query=(tag:discourse AND tag:games AND NOT tag:muted)"
      virtual-mailboxes "Discourse.meta" "notmuch://?query=(tag:discourse AND tag:meta AND NOT tag:muted)"
      virtual-mailboxes "Discourse.events" "notmuch://?query=(tag:discourse AND tag:events AND NOT tag:muted)"
      virtual-mailboxes "Flagged" "notmuch://?query=tag:flagged"
      virtual-mailboxes "Archive" "notmuch://?query=tag:archive"
      virtual-mailboxes "Sent" "notmuch://?query=tag:sent"
      virtual-mailboxes "Fraud" "notmuch://?query=(tag:fraud)"
      virtual-mailboxes "Junk" "notmuch://?query=(tag:junk)"
      virtual-mailboxes "All" "notmuch://?query=*"

      tag-transforms "junk"     "k" \
                     "unread"   "u" \
                     "replied"  "↻" \

      # notmuch bindings
      bind index \\\\ noop
      bind pager \\ noop
      bind pager \\\\ noop
      macro index \\\\ "<vfolder-from-query>"                   # looks up a hand made query
      macro pager \\\\ "<vfolder-from-query>"                   # looks up a hand made query

      macro index + "<modify-labels>+flagged\n<sync-mailbox>"         # tag as starred
      macro pager + "<modify-labels>+flagged\n<sync-mailbox>"         # tag as starred
      macro index ! "<modify-labels>+flagged\n<sync-mailbox>"         # tag as starred
      macro pager ! "<modify-labels>+flagged\n<sync-mailbox>"         # tag as starred
      macro index - "<modify-labels>-flagged\n<sync-mailbox>"         # tag as unstarred
      macro pager - "<modify-labels>-flagged\n<sync-mailbox>"         # tag as unstarred

      # Address Book
      # ------------
      set query_command="${pkgs.notmuch-addrlookup}/bin/notmuch-addrlookup --mutt '%s'"

      # keys bindings
      # -------------
      bind index d noop
      bind index D noop
      bind pager d noop
      bind pager D noop
      macro index D "<modify-labels-then-hide>-inbox -unread +deleted\n" # tag as deleted mail
      macro index d "<modify-labels>-deleted\n"                          # tag as deleted mail
      macro pager D "<modify-labels-then-hide>-inbox -unread +deleted\n" # tag as deleted mail
      macro pager d "<modify-labels>-deleted\n"                          # tag as deleted mail

      bind index S noop
      bind index s noop
      bind pager S noop
      bind pager s noop
      macro index S "<modify-labels-then-hide>-inbox -unread +junk\n" # tag as junk mail
      macro index s "<modify-labels>-junk\n"                          # tag as junk mail
      macro pager S "<modify-labels-then-hide>-inbox -unread +junk\n" # tag as junk mail
      macro pager s "<modify-labels>-junk\n"                          # tag as junk mail

      bind index r noop
      bind index R noop
      bind pager r noop
      bind pager R noop
      macro index r "<group-reply>"  # reply to all
      macro index R "<reply>"        # reply
      macro pager r "<group-reply>"  # reply to all
      macro pager R "<reply>"        # reply


      bind index A noop
      bind index a noop
      bind pager A noop
      bind pager a noop
      macro index A "<modify-labels>+archive -unread -inbox\n"  # tag as Archived
      macro index a "<modify-labels>-archive\n"                 # tag as Archived
      macro pager A "<modify-labels>+archive -unread -inbox\n"  # tag as Archived
      macro pager a "<modify-labels>-archive\n"                 # tag as Archived

      bind index U noop
      bind index u noop
      bind pager U noop
      bind pager u noop
      macro index u "<modify-labels>+unread\n"
      macro index U "<modify-labels>-unread\n"
      macro pager u "<modify-labels>+unread\n"
      macro pager U "<modify-labels>-unread\n"

      bind index l noop
      bind pager l noop
      macro index l "<modify-labels>" # set tags manual
      macro pager l "<modify-labels>" # set tags manual

      # taskwarrior
      # -----------
      # from https://www.nixternal.com/mark-e-mails-in-mutt-as-tasks-in-taskwarrior/
      bind index t noop
      bind pager t noop
      bind index T noop
      bind pager T noop
      macro index T "<pipe-message>${
        pkgs.writers.writeDash "mutt2task" ''
          ${pkgs.taskwarrior}/bin/task add +email scheduled:today E-mail: $( ${pkgs.gnugrep}/bin/grep 'Subject' $* | awk -F: '{print $2}' )
        ''
      }<enter>"

      bind index i noop
      bind pager i noop
      bind index I noop
      bind pager I noop
      # notmuch config set query.chat <query>
      # notmuch search query:chat
      # parse From and To, collect all mail addresses and remove my own mail lists, and create a query from it
      #From:
      #To:
      macro index,pager I "<pipe-message>${
        pkgs.writers.writeDash "show_query" ''
          cat
        ''
      }<enter>"



      # top index bar in email view
      set pager_index_lines=7
      # top_index_bar toggle
      macro pager ,@1 "<enter-command> set pager_index_lines=0; macro pager ] ,@2 'Toggle indexbar<Enter>"
      macro pager ,@2 "<enter-command> set pager_index_lines=3; macro pager ] ,@3 'Toggle indexbar<Enter>"
      macro pager ,@3 "<enter-command> set pager_index_lines=7; macro pager ] ,@1 'Toggle indexbar<Enter>"
      macro pager ] ,@1 'Toggle indexbar

      # sidebar
      # -------
      set sidebar_width   = 20
      set sidebar_visible = yes               # set to "no" to disable sidebar view at startup
      color sidebar_new yellow default
      # sidebar bindings
      bind index <left> sidebar-prev          # got to previous folder in sidebar
      bind index <right> sidebar-next         # got to next folder in sidebar
      bind index <space> sidebar-open         # open selected folder from sidebar

      # sidebar toggle
      #macro index,pager ,@) "<enter-command> set sidebar_visible=no; macro index,pager [ ,@( 'Toggle sidebar'<Enter>"
      #macro index,pager ,@( "<enter-command> set sidebar_visible=yes; macro index,pager [ ,@) 'Toggle sidebar'<Enter>"
      #macro index,pager [ ,@( 'Toggle sidebar'      # toggle the sidebar
    '';

  environment.systemPackages =
    let

      mailSync = pkgs.writers.writeDashBin "mail-sync" ''
        ${pkgs.muchsync}/bin/muchsync mailfetcher@pepe.private \
          --config /home/mailfetcher/.config/notmuch/notmuchrc \
          --nonew
      '';
      mailSend = pkgs.writers.writeDashBin "mail-send" ''
        ${pkgs.msmtp}/bin/msmtp-queue -r
      '';
      mailView = pkgs.writers.writeDashBin "mail-view" ''
        ${pkgs.neomutt}/bin/neomutt"$@"
      '';
      mutt = pkgs.writers.writeDashBin "mutt" ''
        ${pkgs.neomutt}/bin/neomutt"$@"
      '';
      mail = pkgs.writers.writeDashBin "mail" ''
        ${mailSync}/bin/mail-sync
        ${mailView}/bin/mail-view
        ${mailSend}/bin/mail-send
        ${mailSync}/bin/mail-sync
      '';
      mailDelete =
        let notmuch = "${pkgs.notmuch}/bin/notmuch";
        in pkgs.writers.writeBashBin "mail-delete" ''
          set -efu
          set -o pipefail

          if ! ${notmuch} search --exclude=false tag:deleted | tac ; then
            echo 'No killed mail.'
            exit 1
          fi

          printf 'want do rm this mail? \[y/N\] '
          read REPLY

          case "$REPLY" in
            y|Y) :;; # continue
            *)
            echo 'abort.'
            exit 2
          ;;
          esac

          ${notmuch} search --output=files --exclude=false tag:deleted | while read line; do rm -v "$line" ; done
          ${notmuch} new
        '';
      plot_maildir =
        let
          years = [ 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 ];
          file = "~/Maildir/usage.csv";
          append_year = year: ''
            echo -n "${toString year}," >> ${file}
            ${pkgs.notmuch}/bin/notmuch count -- date:${toString year} >> ${file}
          '';
        in
        pkgs.writers.writeBashBin "mail-create-statistics" ''
          rm ${file}
          ${lib.concatStringsSep "\n" (map append_year years)}
        '';

    in
    [
      pkgs.notmuch
      pkgs.muchsync
      mail
      mailSync
      mailView
      mailSend
      pkgs.neomutt
      mutt
      mailDelete
      plot_maildir
    ];

}