{
  config,
  lib,
  namespace,
  ...
}:
let
  name = "matrix";
  cfg = config.${namespace}.services.${name};

  matrixConfig = lib.${namespace}.mkModule {
    inherit config name;
    serviceName = "${name}-synapse";
    description = "config";
    options = { };
    moduleConfig = {
      sops = {
        secrets = {
          "jallen-nas/matrix/client-id" = {
            sopsFile = (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml");
            owner = "matrix-synapse";
            group = "matrix-synapse";
          };
          "jallen-nas/matrix/client-secret" = {
            sopsFile = (lib.snowfall.fs.get-file "secrets/nas-secrets.yaml");
            owner = "matrix-synapse";
            group = "matrix-synapse";
          };
        };
        templates = {
          "matrix-authentik.yaml" = {
            owner = "matrix-synapse";
            group = "matrix-synapse";
            restartUnits = [ "matrix-synapse.service" ];
            content = ''
              oidc_providers:
                - idp_id: authentik
                  idp_name: authentik
                  discover: true
                  issuer: https://authentik.mjallen.dev/application/o/matrix/
                  client_id: ${config.sops.placeholder."jallen-nas/matrix/client-id"}
                  client_secret: ${config.sops.placeholder."jallen-nas/matrix/client-secret"}
                  scopes:
                    - openid
                    - profile
                    - email
                  user_mapping_provider:
                    config:
                      localpart_template: "{{ user.preferred_username }}"
                      display_name_template: "{{ user.preferred_username|capitalize }}"
                  allow_existing_users: true
            '';
          };
        };
      };

      services.matrix-synapse = {
        enable = true;
        dataDir = "${cfg.configDir}/matrix-synapse";
        configureRedisLocally = true;
        enableRegistrationScript = true;
        extras = [
          "oidc"
          "redis"
        ];
        extraConfigFiles = [ config.sops.templates."matrix-authentik.yaml".path ];
        settings = {
          server_name = "mjallen.dev";
          public_baseurl = "https://matrix.mjallen.dev";
          serve_server_wellknown = true;

          listeners = [
            {
              port = cfg.port;
              tls = false;
              x_forwarded = true;
              bind_addresses = [
                "::1"
                cfg.listenAddress
              ];
              resources = [
                {
                  names = [
                    "client"
                    "federation"
                  ];
                  compress = false;
                }
              ];
            }
          ];

          # Database configuration
          database = {
            name = "psycopg2";
            allow_unsafe_locale = true;
            args = {
              user = "synapse";
              database = "synapse";
              host = "localhost";
              cp_min = 5;
              cp_max = 10;
            };
          };

          # Registration settings
          enable_registration = false; # Set to true initially to create admin user
          enable_registration_without_verification = false;

          # Media settings
          max_upload_size = "50M";
          media_store_path = "${cfg.configDir}/matrix-synapse/media";

          # Logging
          # log_config = "/var/lib/matrix-synapse/log_config.yaml";
          trusted_key_servers = [
            {
              server_name = "matrix.org";
            }
          ];
        };
      };

      users.users.matrix-synapse = {
        isSystemUser = true;
        group = "matrix-synapse";
      };
      users.groups.matrix-synapse = { };

      services.postgresql = {
        ensureDatabases = [ "synapse" ];
        ensureUsers = [
          {
            name = "synapse";
            ensureDBOwnership = true;
          }
        ];
      };
    };
  };
in
{
  imports = [ matrixConfig ];
}
