{
  common,
  ...
}:
let
  domain = common.domain;
  proxyTo = address: port: {
    enableACME = true;
    forceSSL = true;
    locations."/".proxyPass = "${address}:${builtins.toString port}";
  };
  proxyLocations = locations: {
    enableACME = true;
    forceSSL = true;
    inherit locations;
  };
  homelab = "http://${common.localIpAddr 231}";
  homelabProxy = proxyTo homelab; # TODO get homelab local ip from systems
  redirect = subdomain: {
    enableACME = true;
    forceSSL = true;
    globalRedirect = if subdomain == "" then domain else "${subdomain}.${domain}";
  };
in
{
  services.nginx = {
    enable = true;
    enableReload = true;
    recommendedProxySettings = true;
    recommendedTlsSettings = true;

    virtualHosts = {
      # Beta is currently stable
      "www.${domain}" = redirect "";
      "beta.${domain}" = redirect "";
      "dev.${domain}" = homelabProxy 4322;
      "git.${domain}" = redirect "code";
      "kitchenowl.${domain}" = redirect "grocery";
      # Gitea
      "code.${domain}" = homelabProxy 3000;
      # Nextcloud
      "nextcloud.${domain}" = proxyLocations {
        "/".proxyPass = "${homelab}:11000";
        "/.well-known/carddav".return = "301 /remote.php/dav";
        "/.well-known/caldav".return = "301 /remote.php/dav";
      };
      # Kitchenowl
      "grocery.${domain}" = homelabProxy 800;
      # Actual budget
      "budget.${domain}" = homelabProxy 5006;
      # Uptime Kuma
      "status.${domain}" = homelabProxy 3001;
      # Headscale
      "vpn.${domain}" = proxyLocations {
        "/web".proxyPass = "${homelab}:8084";
        "/" = {
          proxyPass = "${homelab}:8082";
          extraConfig = ''
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_redirect http:// https://;
            proxy_buffering off;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
          '';
        };
      };
      # Headscale SmartDNS
      "dns.${domain}" = homelabProxy 8082;
      # FreshRSS
      "rss.${domain}" = homelabProxy 8085;
      # Ente backend
      "api.ente.${domain}" = homelabProxy 8083;
      # Ente Photos frontend
      "ente.${domain}" = homelabProxy 3003;
      # Ente Auth frontend
      "mfa.${domain}" = homelabProxy 3004;
      # Homepage / portfolio
      "${domain}" = homelabProxy 4321;
      # Yamtrack
      "track.${domain}" = homelabProxy 8090;
      # Donetick
      "chore.${domain}" = homelabProxy 2021;
      "recurring-events-api.${domain}" = homelabProxy 8095;
    };
  };

  security.acme = {
    acceptTerms = true;
    defaults.email = "acme@${domain}";
  };
}
