{
  config,
  lib,
  namespace,
  ...
}:
with lib;
let
  cfg = config.${namespace}.services.nextcloud;

  adminpass = config.sops.secrets."jallen-nas/nextcloud/adminpassword".path;
  secretsFile = config.sops.secrets."jallen-nas/nextcloud/smtp_settings".path;
  jwtSecretFile = config.sops.secrets."jallen-nas/onlyoffice-key".path;
  nextcloudUserId = config.users.users.nix-apps.uid;
  nextcloudGroupId = config.users.groups.jallen-nas.gid;
  hostAddress = "10.0.1.3";
  localAddress = "10.0.2.18";
  nextcloudPortExtHttp = 9988;
  nextcloudPortExtHttps = 9943;
  onlyofficePortExt = 9943;
in
{
  imports = [ ./options.nix ];

  config = mkIf cfg.enable {
    containers.nextcloud = {
      autoStart = true;
      privateNetwork = true;
      hostAddress = hostAddress;
      localAddress = localAddress;
      specialArgs = {
        inherit namespace;
      };

      bindMounts = {
        secrets = {
          hostPath = "/run/secrets/jallen-nas/nextcloud";
          isReadOnly = true;
          mountPoint = "/run/secrets/jallen-nas/nextcloud";
        };

        secrets2 = {
          hostPath = "/run/secrets/jallen-nas/onlyoffice-key";
          isReadOnly = true;
          mountPoint = "/run/secrets/jallen-nas/onlyoffice-key";
        };

        data = {
          hostPath = "/media/nas/main/nextcloud";
          isReadOnly = false;
          mountPoint = "/data";
        };

        "/var/lib/nextcloud" = {
          hostPath = "/media/nas/main/nix-app-data/nextcloud";
          isReadOnly = false;
          mountPoint = "/var/lib/nextcloud";
        };

        "/var/lib/onlyoffice" = {
          hostPath = "/media/nas/main/nix-app-data/onlyoffice";
          isReadOnly = false;
          mountPoint = "/var/lib/onlyoffice";
        };
      };

      config =
        {
          pkgs,
          lib,
          ...
        }:
        {
          nixpkgs.config.allowUnfree = true;
          networking.extraHosts = ''
            ${hostAddress} host.containers protonmail-bridge
          '';

          services = {
            nextcloud = {
              enable = true;
              package = pkgs.nextcloud31;
              # datadir = "/data";
              database.createLocally = true;
              hostName = "cloud.mjallen.dev";
              appstoreEnable = true;
              caching.redis = true;
              configureRedis = true;
              enableImagemagick = true;
              https = true;
              secretFile = secretsFile;

              config = {
                adminuser = "mjallen";
                adminpassFile = adminpass;
                dbhost = "localhost";
                dbtype = "sqlite";
                dbname = "nextcloud";
                dbuser = "nextcloud";
              };
              settings = {
                loglevel = 3;
                allow_local_remote_servers = true;
                upgrade.disable-web = false;
                datadirectory = "/data";
                trusted_domains = [
                  "${hostAddress}:${toString nextcloudPortExtHttp}"
                  "${hostAddress}:${toString nextcloudPortExtHttps}"
                  "${localAddress}:80"
                  "${localAddress}:443"
                  "cloud.mjallen.dev"
                ];
                opcache.interned_strings_buffer = 16;
                trusted_proxies = [ hostAddress ];
                maintenance_window_start = 6;
                default_phone_region = "US";
                enable_previews = true;
                enabledPreviewProviders = [
                  "OC\\Preview\\PNG"
                  "OC\\Preview\\JPEG"
                  "OC\\Preview\\GIF"
                  "OC\\Preview\\BMP"
                  "OC\\Preview\\XBitmap"
                  "OC\\Preview\\MP3"
                  "OC\\Preview\\TXT"
                  "OC\\Preview\\MarkDown"
                  "OC\\Preview\\OpenDocument"
                  "OC\\Preview\\Krita"
                  "OC\\Preview\\HEIC"
                  "OC\\Preview\\Movie"
                  "OC\\Preview\\MSOffice2003"
                  "OC\\Preview\\MSOffice2007"
                  "OC\\Preview\\MSOfficeDoc"
                ];
                installed = true;
                user_oidc = {
                  auto_provision = false;
                  soft_auto_provision = false;
                  allow_multiple_user_backends = false; # auto redirect to authentik for login
                };
              };
            };
          };

          services.onlyoffice = {
            enable = true;
            port = onlyofficePortExt;
            hostname = "office.mjallen.dev";
            jwtSecretFile = jwtSecretFile;
          };

          # System packages
          environment.systemPackages = with pkgs; [
            cudaPackages.cudnn
            cudatoolkit
            ffmpeg
            # libtensorflow-bin
            nextcloud31
            nodejs
            onlyoffice-documentserver
            sqlite
          ];

          # Create required users and groups
          users.users.nextcloud = {
            isSystemUser = true;
            uid = lib.mkForce nextcloudUserId;
            group = "nextcloud";
          };

          users.users.onlyoffice = {
            group = lib.mkForce "nextcloud";
          };

          users.groups = {
            nextcloud = {
              gid = lib.mkForce nextcloudGroupId;
            };
            downloads = { };
          };

          # Create and set permissions for required directories
          system.activationScripts.nextcloud-dirs = ''
            mkdir -p /data

            chown -R nextcloud:nextcloud /data

            chown  -R nextcloud:nextcloud /run/secrets/jallen-nas/nextcloud

            chmod -R 775 /data

            chmod  -R 750 /run/secrets/jallen-nas/nextcloud

          '';

          hardware = {
            graphics = {
              enable = true;
              # setLdLibraryPath = true;
            };
          };

          programs = {
            nix-ld.enable = true;
          };

          system.stateVersion = "23.11";
          networking = {
            firewall = {
              enable = true;
              allowedTCPPorts = [
                80
                443
                onlyofficePortExt
              ];
            };
            # Use systemd-resolved inside the container
            # Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
            useHostResolvConf = lib.mkForce false;
          };
          services.resolved.enable = true;

        };
    };

    networking = {
      nat = {
        forwardPorts = [
          {
            destination = "${localAddress}:443";
            sourcePort = nextcloudPortExtHttps;
          }
          {
            destination = "${localAddress}:80";
            sourcePort = nextcloudPortExtHttp;
          }
          {
            destination = "${localAddress}:8000";
            sourcePort = 8000;
          }
          {
            destination = "${localAddress}:${toString onlyofficePortExt}";
            sourcePort = onlyofficePortExt;
          }
        ];
      };
    };
  };
}
