{ config, pkgs, ... }:
let
  domain = "matrix.${config.networking.domain}";
  domainClient = "chat.${config.networking.domain}";
  clientConfig = {
    "m.homeserver" = {
      base_url = "https://${domain}:443";
    };
  };
in
{

  age.secrets = {
    "matrix/shared" = {
      file = ../../../../secrets/nuc/matrix/shared.age;
      owner = config.systemd.services.matrix-synapse.serviceConfig.User;
    };
    "matrix/sync" = {
      file = ../../../../secrets/nuc/matrix/sync.age;
    };
  };
  nixpkgs.config.permittedInsecurePackages = [
    "jitsi-meet-1.0.8043"
    "olm-3.2.16"
  ];

  services = {
    postgresql = {
      enable = true;
      ensureUsers = [{
        name = "matrix-synapse";
      }];
    };


    matrix-synapse = {
      enable = true;
      configureRedisLocally = true;
      enableRegistrationScript = false;
      extraConfigFiles = [ config.age.secrets."matrix/shared".path ];
      log = {
        root.level = "WARNING";
      };

      settings = {
        server_name = config.networking.domain;
        enable_metrics = true;

        listeners = [{
          bind_addresses = [ "0.0.0.0" "::1" ];
          port = 8008;
          tls = false;
          type = "http";
          x_forwarded = true;
          resources = [{
            names = [ "client" "federation" "metrics" ];
            compress = false;
          }];
        }];
      };
    };
    matrix-sliding-sync = {
      enable = true;
      settings = {
        SYNCV3_SERVER = "https://${domain}";
        SYNCV3_BINDADDR = "/run/matrix-sliding-sync/server.sock";
      };
      environmentFile = config.age.secrets."matrix/sync".path;
    };


    caddy = {
      virtualHosts = {
        # synapse
        "${domain}".extraConfig = ''
          reverse_proxy /client/* unix//run/matrix-sliding-sync/server.sock
          reverse_proxy /_matrix/client/unstable/org.matrix.msc3575/sync* unix//run/matrix-sliding-sync/server.sock
          reverse_proxy 127.0.0.1:8008
          handle /_synapse/metrics* {
            respond 404
          }
        '';

        # element
        "${domainClient}".extraConfig = ''
          file_server browse
          root * ${pkgs.element-web.override {
            conf = {
              default_server_config = {
                inherit (clientConfig) "m.homeserver";
                "m.identity_server".base_url = "";
              };
              disable_3pid_login = true;
            };
          }}
        '';
      };
    };
  };

  systemd.services.matrix-synapse = {
    after = [ "matrix-synapse-pgsetup.service" ];
    serviceConfig = {
      RuntimeDirectory = "matrix-synapse";
    };
  };
  systemd.services.matrix-sliding-sync = {
    serviceConfig = {
      RuntimeDirectory = "matrix-sliding-sync";
    };
  };

  systemd.services.matrix-synapse-pgsetup = {
    description = "Prepare Synapse postgres database";
    wantedBy = [ "multi-user.target" ];
    after = [ "networking.target" "postgresql.service" ];
    serviceConfig.Type = "oneshot";

    path = [ pkgs.sudo config.services.postgresql.package ];

    # create database for synapse. will silently fail if it already exists
    script = ''
      sudo -u ${config.services.postgresql.superUser} psql <<SQL
        CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
          ENCODING 'UTF8'
          TEMPLATE template0
          LC_COLLATE = "C"
          LC_CTYPE = "C";
      SQL
    '';
  };
}