{
  lib,
  config,
  ...
}: let
  mediaLocation = "/var/lib/immich";
in {
  options.host.immich = {
    enable = lib.mkEnableOption "should immich be enabled on this computer";
    subdomain = lib.mkOption {
      type = lib.types.str;
      description = "subdomain of base domain that immich will be hosted at";
      default = "immich";
    };
  };

  config = lib.mkIf config.host.immich.enable (lib.mkMerge [
    {
      host = {
        reverse_proxy.subdomains.${config.host.immich.subdomain} = {
          target = "http://localhost:${toString config.services.immich.port}";

          websockets.enable = true;
          forwardHeaders.enable = true;

          extraConfig = ''
            # allow large file uploads
            client_max_body_size 50000M;

            # set timeout
            proxy_read_timeout 600s;
            proxy_send_timeout 600s;
            send_timeout       600s;
            proxy_redirect     off;
          '';
        };
        postgres = {
          enable = true;
          extraUsers = {
            ${config.services.immich.database.user} = {
              isClient = true;
            };
          };
        };
      };

      services.immich = {
        enable = true;
        port = 2283;
        # redis.enable = false;
      };

      networking.firewall.interfaces.${config.services.tailscale.interfaceName} = {
        allowedUDPPorts = [
          config.services.immich.port
        ];
        allowedTCPPorts = [
          config.services.immich.port
        ];
      };
    }
    (lib.mkIf config.host.impermanence.enable {
      assertions = [
        {
          assertion = config.services.immich.mediaLocation == mediaLocation;
          message = "immich media location does not match persistence";
        }
      ];
      environment.persistence."/persist/system/root" = {
        enable = true;
        hideMounts = true;
        directories = [
          {
            directory = mediaLocation;
            user = "immich";
            group = "immich";
          }
        ];
      };
    })
  ]);
}