{ pkgs, config, lib, ... }:
let
  mkUserJs = with lib; prefs: extraPrefs: ''
    // Generated by Geoffrey's dotfiles.

    ${concatStrings (mapAttrsToList (name: value: ''
      user_pref("${name}", ${builtins.toJSON value});
    '') prefs)}
    ${extraPrefs}
  '';

  toThunderbirdCalendar = account:
    let
      id = builtins.hashString "sha256" account.name;
      thunderbird = config.frogeye.accounts.calendar.accounts.${account.name};
    in
    {
      "calendar.registry.${id}.cache.enabled" = thunderbird.offlineSupport; # TODO Check this actually corresponds
      "calendar.registry.${id}.color" = thunderbird.color;
      "calendar.registry.${id}.forceEmailScheduling" = thunderbird.clientSideEmailScheduling;
      "calendar.registry.${id}.imip.identity.key" = "id_${builtins.hashString "sha256" thunderbird.email}";
      "calendar.registry.${id}.name" = account.name;
      "calendar.registry.${id}.readOnly" = thunderbird.readOnly;
      "calendar.registry.${id}.refreshInterval" = builtins.toString thunderbird.refreshInterval;
      "calendar.registry.${id}.suppressAlarms" = !thunderbird.showReminders; # TODO Check this actually corresponds
      "calendar.registry.${id}.type" = account.remote.type; # TODO Check and validate supported types
      "calendar.registry.${id}.uri" = account.remote.url;
      "calendar.registry.${id}.username" = account.remote.userName;
      # Unimplemented
      "calendar.registry.${id}.notifications.times" = "";
      # Unknown
      # "calendar.registry.${id}.calendar-main-in-composite" = true;
    };
in
{
  config = {
    programs.aerc = {
      enable = true;
      extraConfig.general.unsafe-accounts-conf = true;
    };
    programs.thunderbird = {
      enable = config.frogeye.desktop.xorg;
      profiles.hm = {
        isDefault = true;
        withExternalGnupg = true;
        extraConfig = mkUserJs
          (lib.attrsets.mergeAttrsList (
            # Add calendar config
            (lib.mapAttrsToList (name: account: (toThunderbirdCalendar account)) config.accounts.calendar.accounts) ++
            # Add config for every identity (kinda)
            (lib.mapAttrsToList
              (name: account: ({
                # UPST Make signature be used in Thunderbird
                "mail.identity.id_${builtins.hashString "sha256" account.address}.htmlSigText" = account.signature.text;
                "mail.identity.id_${builtins.hashString "sha256" account.address}.compose_html" = false;
              }))
              config.accounts.email.accounts) ++
            # General settings
            [{
              "mail.pane_config.dynamic" = 0;
              "intl.date_time.pattern_override.date_short" = "yyyy-MM-dd";
            }]

          )) "";
      };
    };
  };
  # UPST Thunderbird-specific options (should be named so), to be included in HM Thunderbird module
  options = {
    frogeye.accounts.calendar.accounts = lib.mkOption {
      default = { };
      type = lib.types.attrsOf (lib.types.submodule ({ config, name, ... }: {
        # TODO Set defaults as Thunderbird sets it
        options = {
          color = lib.mkOption {
            type = lib.types.str;
            default = "#5277c3";
          };
          refreshInterval = lib.mkOption {
            type = lib.types.int;
            default = 0; # 0 = Manual
          };
          readOnly = lib.mkOption {
            type = lib.types.bool;
            default = false;
          };
          showReminders = lib.mkOption {
            type = lib.types.bool;
            default = true;
          };
          offlineSupport = lib.mkOption {
            type = lib.types.bool;
            default = true;
          };
          email = lib.mkOption {
            type = lib.types.str;
            # TODO Nullable
            # TODO Ensure it actually matches an email identity
          };
          clientSideEmailScheduling = lib.mkOption {
            type = lib.types.bool;
            default = false;
          };
        };
      }));
    };
  };
}