{ config, pkgs, ... }:
{

  systemd.network.networks."30-wan".addresses = [
    {
      Address = "2a01:4f8:c013:7fc0::/64";
    }
  ];

  networking.firewall = {
    enable = true;
    allowedTCPPorts = [
      80
      443
    ];
    allowedUDPPorts = [
      51820
    ];
  };

  services.fail2ban.jails = {
    # max 6 failures in 600 seconds
    "nginx-spam" = ''
      enabled  = true
      filter   = nginx-bruteforce
      logpath = /var/log/nginx/access.log
      backend = auto
      maxretry = 6
      findtime = 600
    '';
  };

  services.namespaced-vpn = {
    enable = true;
    ips = [
      "10.64.244.95/32"
      "fc00:bbbb:bbbb:bb01::1:f45e/128"
    ];
    publicKey = "KkShcqgwbkX2A9n1hhST6qu+m3ldxdJ2Lx8Eiw6mdXw=";
    endpoint = "146.70.117.226:51820";
    privateKeyFile = config.sops.secrets.wireguardKey.path;
    dns = "10.64.0.1";
  };

  services.storagebox = {
    enable = true;
    hostname = "u491729.your-storagebox.de";
    hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICf9svRenC/PLKIL9nk6K/pxQgoiFC41wTNvoIncOxs";
    user = "u491729";
    sshKeyFile = config.sops.secrets.storageboxKey.path;
    passFile = config.sops.secrets.storageboxCryptKey.path;
  };

  services.slskd = {
    enable = true;
    domain = "slsk.escapeangle.com";
    environmentFile = config.sops.secrets.slskdEnvFile.path;
    settings = {
      shares.directories = [ "/data/music" ];
      global.upload = {
        slots = 3;
        speed_limit = 10000;
      };
      directories = {
        downloads = "/data/slsk/downloads";
        incomplete = "/data/slsk/incomplete";
      };
    };
  };

  systemd.services.slskd.serviceConfig = {
    UMask = "0002";
    NetworkNamespacePath = "/run/netns/vpn";
  };

  services.nginx.virtualHosts."sls.escapeangle.com" = {
    forceSSL = true;
    enableACME = true;
    locations."/" = {
      proxyPass = "http://10.10.10.2:${toString config.services.slskd.settings.web.port}";
      proxyWebsockets = true;
    };
  };

  users.groups.storage = {
    name = "storage";
    gid = 491729;
    members = [
      config.services.navidrome.user
      "slskd"
      "bandcamp-collection-downloader"
    ];
  };

  services.navidrome = {
    enable = true;
    settings = {
      BaseUrl = "https://music.escapeangle.com";
      MusicFolder = "/data/music";
      DataFolder = "/data/navidrome";
      EnableInsightsCollector = false;
      AutoTranscodeDownload = true;
      EnableGravatar = true;
      EnableTranscodingConfig = true;
      FFmpegPath = "${pkgs.ffmpeg}/bin/ffmpeg";
      IgnoredArticles = "The El La Los Las Le Les Os As O A De";
    };
    environmentFile = config.sops.secrets.navidromeSecrets.path;
  };

  services.nginx.virtualHosts."music.escapeangle.com" = {
    forceSSL = true;
    enableACME = true;
    locations."/" = {
      proxyPass = "http://localhost:${toString config.services.navidrome.settings.Port}";
      proxyWebsockets = true;
    };
  };

  environment.systemPackages = with pkgs; [
    beets
  ];

  services.nginx.virtualHosts."tag.escapeangle.com" = {
    forceSSL = true;
    enableACME = true;
    locations."/" = {
      proxyPass = "http://localhost:7373";
      proxyWebsockets = true;
    };
  };

  services.bandcamp-collection-downloader = {
    enable = true;
    bandcampUser = "lander";
    cookiesFile = config.sops.secrets.bandcampcdCookieFile.path;
  };

  services.declarative-jellyfin = {
    enable = true;
    serverId = "71c25c254161412ebf8e7e7fc599d7f8";

    libraries = {
      Movies = {
        enabled = true;
        contentType = "movies";
        pathInfos = [ "/data/movies" ];

        typeOptions.Movies = {
          metadataFetchers = [
            "The Open Movie Database"
            "TheMovieDb"
          ];
          imageFetchers = [
            "The Open Movie Database"
            "TheMovieDb"
          ];
        };
      };

      Shows = {
        enabled = true;
        contentType = "tvshows";
        pathInfos = [ "/data/shows" ];
      };
    };

    users = {
      Lander = {
        mutable = false;
        permissions.isAdministrator = true;
        hashedPasswordFile = config.sops.secrets.jellyfin-lander-password.path;
      };
    };
  };

  services.nginx.virtualHosts."media.escapeangle.com" = {
    forceSSL = true;
    enableACME = true;
    locations = {
      "/" = {
        proxyPass = "http://localhost:8096";
      };
      "/socket" = {
        proxyPass = "http://localhost:8096";
        proxyWebsockets = true;
      };
    };
  };

  services.sabnzbd = {
    enable = true;
    group = "storage";
  };

  systemd.services.sabnzbd.serviceConfig = {
    NetworkNamespacePath = "/run/netns/vpn";
  };

  services.nginx.virtualHosts."nzb.escapeangle.com" = {
    forceSSL = true;
    enableACME = true;
    locations."/" = {
      proxyPass = "http://10.10.10.2:8080";
      proxyWebsockets = true;
    };
  };

  services.jellyseerr = {
    enable = true;
  };

  services.nginx.virtualHosts."jellyseerr.escapeangle.com" = {
    forceSSL = true;
    enableACME = true;
    locations."/" = {
      proxyPass = "http://localhost:${toString config.services.jellyseerr.port}";
      proxyWebsockets = true;
    };
  };

  services.prowlarr = {
    enable = true;
  };

  services.radarr = {
    enable = true;
    group = "storage";
  };

  services.sonarr = {
    enable = true;
    group = "storage";
  };

  sops = {
    defaultSopsFile = ./hosting-02.yaml;
    secrets = {
      wireguardKey = {
        owner = "root";
      };
      storageboxKey = {
        owner = "root";
      };
      storageboxCryptKey = {
        owner = "root";
      };
      slskdEnvFile = {
        owner = config.services.slskd.user;
      };
      navidromeSecrets = {
        owner = config.services.navidrome.user;
      };
      bandcampcdCookieFile = {
        owner = "bandcampcd";
      };
      jellyfin-lander-password = {
        owner = config.services.jellyfin.user;
        group = config.services.jellyfin.group;
      };
    };
  };

  system.stateVersion = "25.05";
}
