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

let
  inherit (lib)
    mkEnableOption
    mkOption
    types
    mkIf
    ;

  cfg = config.programs.meli;

  tomlFormat = pkgs.formats.toml { };

  enabledAccounts = lib.attrsets.filterAttrs (
    name: value: value.enable && (value.meli.enable or false)
  ) config.accounts.email.accounts;

  meliAccounts = (lib.attrsets.mapAttrs (name: value: (mkMeliAccounts name value)) enabledAccounts);

  mkMeliAccounts = (
    name: account: {
      root_mailbox = "${config.accounts.email.maildirBasePath}/${account.maildir.path}";
      format = "Maildir";
      identity = account.address;
      display_name = account.realName;
      subscribed_mailboxes = account.meli.mailboxes;
      send_mail = mkSmtp account;
      mailboxes = account.meli.mailboxAliases;
    }
  );

  mkSmtp = account: {
    hostname = account.smtp.host;
    port = account.smtp.port;
    auth = {
      type = "auto";
      username = account.userName;
      password = {
        type = "command_eval";
        value = lib.strings.concatStringsSep " " account.passwordCommand;
      };
    };
    security = {
      type =
        if account.smtp.tls.enable or false then
          if account.smtp.tls.useStartTls or false then "starttls" else "tls"
        else
          "none";
      danger_accept_invalid_certs = false;
    };
    extensions = {
      PIPELINING = true;
      CHUNKING = true;
      PRDR = true;
      DSN_NOTIFY = "FAILURE";
    };
  };

in
{
  meta.maintainers = with lib.hm.maintainers; [ munsman ];

  options = {
    programs.meli = {
      enable = mkEnableOption "meli email client";

      package = lib.mkPackageOption pkgs "meli" { };

      includes = mkOption {
        type = with types; listOf (str);
        description = "Paths of the various meli configuration files to include.";
        default = [ ];
      };

      settings = mkOption {
        type = types.submodule {
          freeformType = tomlFormat.type;
        };
        example = lib.literalExpression ''
          {
          shortcuts = {
          contact-list = {
                      create_contact = "c";
                      edit_contact = "m";
                    };
          general = {
            edit = "m";
            scroll_up = "e";
            scroll_down = "n";
          };
          composing = {
            edit = "m";
            scroll_up = "e";
            scroll_down = "n";
          };
          listing = {
            new_mail = "t";
            set_seen = "s";
          };
          pager = {
                      scroll_up = "e";
                      scroll_down = "n";
          };

          }
          }'';
        default = { };
        description = "Meli Configuration";
      };
    };
    accounts.email.accounts = mkOption {
      type = types.attrsOf (
        types.submodule (
          { config, ... }:
          {
            options.meli = {
              enable = mkEnableOption "the meli mail client for this account.\nRequires SMTP settings.";
              mailboxes = mkOption {
                type = with types; listOf str;
                default = (
                  with config.folders;
                  [
                    inbox
                    sent
                    trash
                    drafts
                  ]
                );
                example = [
                  "INBOX"
                  "Sent"
                  "Trash"
                  "Drafts"
                ];
                description = "Mailboxes to show in meli";
              };
              mailboxAliases = mkOption {
                type = with types; attrsOf attrs;
                default = { };
                example = {
                  "INBOX" = {
                    alias = "📥 Inbox";
                  };
                  "Sent" = {
                    alias = "📤 Sent";
                  };
                };
                description = "Folder display name";
              };
            };
          }
        )
      );
    };
  };
  config = mkIf config.programs.meli.enable {
    home.packages = [ config.programs.meli.package ];

    # Generate meli configuration from email accounts
    xdg.configFile."meli/config.toml" =
      let

        generatedToml = tomlFormat.generate "meli-config" (
          {
            accounts = meliAccounts;
          }
          // config.programs.meli.settings
        );

      in
      if cfg.includes == [ ] then
        {
          source = generatedToml;
        }
      else
        {
          text = lib.concatStringsSep "\n" (
            map (inc: "include(\"${inc}\")") (cfg.includes ++ [ generatedToml ])
          );
        };
  };
}
