{
  config,
  pkgs,
  lib,
  ...
}:
let
  inherit (config.machine.prosody)
    enable
    domain
    ;

  sslCertDir = config.security.acme.certs."${domain}".directory;
in
with lib;
mkIf enable {
  services.prosody = {
    inherit enable;

    package = pkgs.prosody.override {
      withCommunityModules = [
        "sasl2"
        "sasl2_bind2"
        "sasl_ssdp"
        "sasl2_fast"
        "sasl_ssdp"
        "csi_battery_saver"
        "muc_notifications"
      ];
    };

    admins = [
      "admin@${domain}"
    ];
    allowRegistration = true;
    s2sSecureAuth = true;
    c2sRequireEncryption = true;
    modules = {
      http_files = true;
      limits = true;
      server_contact_info = true;
      bosh = true;
      motd = true;
      announce = true;
      welcome = true;
      admin_adhoc = true;
      websocket = true;
      watchregistrations = true;
    };
    extraModules = [
      "turn_external"
    ];
    xmppComplianceSuite = true;
    checkConfig = false;
    ssl = {
      cert = "${sslCertDir}/fullchain.pem";
      key = "${sslCertDir}/key.pem";
    };
    virtualHosts.${domain} = {
      inherit domain;
      enabled = enable;
      ssl = {
        cert = "${sslCertDir}/fullchain.pem";
        key = "${sslCertDir}/key.pem";
      };
    };
    muc = [
      {
        domain = "conference.${domain}";
        restrictRoomCreation = "local";
      }
    ];
    httpFileShare = {
      domain = "upload.${domain}";
      http_host = domain;
      expires_after = "never";
      size_limit = 32 * 1024 * 1024;
    };
    extraConfig = ''
      storage = "sql"
      sql = {
        driver = "SQLite3";
        database = "prosody.sqlite";
      }

      -- Keep messages
      archive_expires_after = "never"
      muc_log_presences = true
      muc_log_expires_after = "never"

      -- Recommended by Monal dev
      smacks_max_queue_size = 4000

      c2s_direct_tls_ports = { 5223 };
      s2s_direct_tls_ports = { 5270 };

      trusted_proxies = { "127.0.0.1", "::1" };
      http_external_url = "https://${domain}/"
      consider_bosh_secure = true;
      consider_websocket_secure = true;
      statistics = "internal";
      statistics_interval = "manual";
    '';
  };
}
