{ config, containerCfg, pkgs, lib, builder, name,... }:
let 
  version = "31";
  serverCfg = config.syscfg.server;
  mediaCfg = config.syscfg.media;
  backgroundImage = if mediaCfg.banner.png != null then mediaCfg.banner.png else mediaCfg.bg;
  backgroundFileName = builtins.baseNameOf (toString backgroundImage);
  logoPngFileName = builtins.baseNameOf (toString mediaCfg.logo.png);
  logoSvgFileName = builtins.baseNameOf (toString mediaCfg.logo.svg);
  logoIcoFileName = builtins.baseNameOf (toString mediaCfg.logo.ico);
  logoPngMount = "/var/www/html/themes/hcl/${logoPngFileName}";
  logoSvgMount = "/var/www/html/themes/hcl/${logoSvgFileName}";
  logoIcoMount = "/var/www/html/themes/hcl/${logoIcoFileName}";
  backgroundMount = "/var/www/html/themes/hcl/${backgroundFileName}";
in {
  requires = {
    secrets = [ name ];
    databases = [ name ];
  };

  runtime = {
    paths = [{
      path="${serverCfg.path.config.path}/nextcloud";
      owner = "33:33";
      mode = "0755";
    }];

    containers = {
      server = builder.mkContainer {
        tmpfs = true;
        subdomain = containerCfg.subdomain;
        image = "nextcloud:${version}";
        port = 80;
        secret = name;
        extraEnv = {
          REDIS_HOST = builder.host;
          POSTGRES_HOST = builder.host;
          POSTGRES_USER = "nextcloud_user";
          POSTGRES_DB = "nextcloud_db";
          AUTHENTIK_POSTGRESQL__SSLMODE = "disable";
          NEXTCLOUD_TRUSTED_DOMAINS = "${containerCfg.subdomain}.${serverCfg.domain} nextcloud-server";
          OVERWRITEPROTOCOL = "https";
          NEXTCLOUD_CLI_URL = "https://${containerCfg.subdomain}.${serverCfg.domain}";
          # SMTP_HOST = serverCfg.mail.server;
          # SMTP_NAME = "mail_user";
          # SMTP_PASSWORD = "mail_password";
          # MAIL_FROM_ADDRESS = "${containerCfg.subdomain}@${serverCfg.domain}";
          # MAIL_DOMAIN = serverCfg.mail.domain;
          TRUSTED_PROXIES = "10.10.0.0/16 192.168.0.0/16";
          NEXTCLOUD_DATA_DIR = "/var/www/html/data";
        };
        extraLabels = {
          "traefik.http.routers.${containerCfg.subdomain}.middlewares" = "hsts-headers@docker,${containerCfg.subdomain}-caldav";
          "traefik.http.middlewares.${containerCfg.subdomain}-caldav.redirectregex.permanent" = "true";
          "traefik.http.middlewares.${containerCfg.subdomain}-caldav.redirectregex.regex" = "https://(.*)/.well-known/(?:card|cal)dav";
          "traefik.http.middlewares.${containerCfg.subdomain}-caldav.redirectregex.replacement" = "https://$1/remote.php/dav";
        };
        overrides = {
          ports = if containerCfg.port!=null then [ "${toString containerCfg.port}:80" ] else [];
          volumes = [
            "${serverCfg.path.config.path}/nextcloud:/var/www/html"
            "${serverCfg.path.cloud.path}:/var/www/html/data"
            "${mediaCfg.logo.png}:${logoPngMount}:ro"
            "${mediaCfg.logo.svg}:${logoSvgMount}:ro"
            "${mediaCfg.logo.ico}:${logoIcoMount}:ro"
            "${backgroundImage}:${backgroundMount}:ro"
          ];
        };
      };
    };

    setup = {
      trigger = "server";
      envFile = [config.sops.secrets."CUSTOM".path config.sops.secrets."NEXTCLOUD".path ];
      script = pkgs.writeShellScript "setup" ''
      # Define the command wrapper
      OCC="${pkgs.podman}/bin/podman --events-backend=none exec --env-file ${config.sops.secrets."CUSTOM".path} -e POSTGRES_PASSWORD=$POSTGRES_PASSWORD -e DOMAIN=${serverCfg.domain} -u www-data nextcloud-server php occ"

      echo "Waiting for Nextcloud container to start..."
      until $OCC status > /dev/null 2>&1; do
        sleep 2
      done

      INSTALLED=$($OCC status --output=json | grep -o '"installed":true')
      if [ -z "$INSTALLED" ]; then
        echo "Running first-time setup..."
        
        $OCC maintenance:install \
          --admin-user "$DEFAULT_ADMIN_USERNAME" \
          --admin-pass "$DEFAULT_ADMIN_PASSWORD" \
          --database "pgsql" \
          --database-host "${builder.host}" \
          --database-name "nextcloud_db" \
          --database-user "nextcloud_user" \
          --database-pass "$POSTGRES_PASSWORD" \
          --data-dir "/var/www/html/data"



      fi

      echo "Applying Settings..."

        $OCC config:system:set dbhost --value="${builder.host}"
        $OCC config:system:set dbuser --value="nextcloud_user"
        $OCC config:system:set dbpassword --value="$POSTGRES_PASSWORD"
        $OCC config:system:set dbname --value="nextcloud_db"
        $OCC config:system:set memcache.local --value="\OC\Memcache\Redis"
        $OCC config:system:set memcache.locking --value="\OC\Memcache\Redis"
        $OCC config:system:set redis --value='{"host":"${builder.host}", "port":6379, "timeout":0.0}' --type=json
        $OCC config:system:set trusted_domains 1 --value=${containerCfg.subdomain}.${serverCfg.domain}
        $OCC config:system:set default_phone_region --value="CH"
        $OCC config:system:set overwriteprotocol --value="https"
        $OCC config:app:set core backgroundjobs_mode --value="cron"
        $OCC config:system:set maintenance_window_start --type=integer --value=1
        $OCC config:system:set default_language --value="en"
        $OCC config:system:set default_locale --value="en_CH"
        $OCC config:system:set overwriteprotocol --value="https"
        $OCC config:system:set overwrite.cli.url --value="https://${containerCfg.subdomain}.${serverCfg.domain}"

        echo "Applying Apps..."
        $OCC app:disable activity || true
        $OCC app:disable app_api || true
        $OCC app:disable comments || true
        $OCC app:disable firstrunwizard || true
        $OCC config:system:set show_first_run_wizard --type=bool --value=false
        $OCC app:disable nextcloud_announcements || true
        $OCC app:disable oauth2 || true
        $OCC app:disable recommendations || true
        $OCC app:disable sharebymail || true
        $OCC app:disable support || true
        $OCC app:disable survey_client || true
        $OCC app:disable updatenotification || true
        $OCC app:disable user_status || true

        $OCC app:install calendar || true
        $OCC app:install contacts || true
        $OCC app:install camerarawpreviews || true
        $OCC app:install cospend || true
        $OCC app:install deck || true
        $OCC app:install files_markdown || true
        $OCC app:install forms || true
        $OCC app:install groupfolders || true
        $OCC app:install ownpad || true
        $OCC app:install previewgenerator || true
        $OCC app:install richdocuments || true
        ${lib.optionalString (serverCfg.containers ? collabora == false) ''$OCC app:install richdocumentscode || true''}
        # $OCC app:install side_menu || true 
        $OCC app:install spreed || true
        $OCC app:install teamfolders || true
        ${lib.optionalString (serverCfg.containers ? authentik) ''$OCC app:install user_saml || true''}

        echo "Applying Apps Settings..."
        $OCC config:system:set enabledPreviewProviders --value='["OC\\Preview\\Movie", "OC\\Preview\\PNG", "OC\\Preview\\JPEG", "OC\\Preview\\GIF", "OC\\Preview\\HEIC", "OC\\Preview\\RAW"]' --type=json
        $OCC config:app:set cospend allow_federation --value="yes"
        
        ${lib.optionalString (serverCfg.containers ? ethercalc) ''
        $OCC config:app:set ownpad ownpad_ethercalc_enable --value="yes"
        $OCC config:app:set ownpad ownpad_ethercalc_host --value="https://${serverCfg.containers.ethercalc.subdomain}.${serverCfg.domain}"
        ''}
        ${lib.optionalString (serverCfg.containers ? etherpad) ''
        $OCC config:app:set ownpad ownpad_etherpad_enable --value="yes"
        $OCC config:app:set ownpad ownpad_etherpad_host --value="https://${serverCfg.containers.etherpad.subdomain}.${serverCfg.domain}"
        ''}
        ${lib.optionalString (serverCfg.containers ? collabora) ''
        $OCC config:app:set richdocuments wopi_url --value="https://${serverCfg.containers.collabora.subdomain}.${serverCfg.domain}/"
        $OCC config:app:set richdocuments public_wopi_url --value="https://${serverCfg.containers.collabora.subdomain}.${serverCfg.domain}"
        $OCC config:app:set richdocuments wopi_allowlist --value="10.0.0.0/8"
        ''}
        ${lib.optionalString (serverCfg.containers ? authentik) ''
        $OCC saml:config:set 1 --general-idp0_display_name="authentik"
        $OCC saml:config:set 1 --general-uid_mapping="http://schemas.goauthentik.io/2021/02/saml/username"
        $OCC saml:config:set 1 --idp-entityId="https://${serverCfg.containers.authentik.subdomain}.${serverCfg.domain}"
        $OCC saml:config:set 1 --idp-singleSignOnService.url="https://${serverCfg.containers.authentik.subdomain}.${serverCfg.domain}/application/saml/nextcloud/sso/binding/redirect/"
        $OCC saml:config:set 1 --idp-singleLogoutService.url="https://${serverCfg.containers.authentik.subdomain}.${serverCfg.domain}/application/saml/nextcloud/slo/binding/redirect/"
        AUTHENTIK_CERT=$(${pkgs.postgresql}/bin/psql -h localhost -U authentik_user -d authentik_db -At -c "SELECT certificate_data FROM authentik_crypto_certificatekeypair WHERE name = 'authentik Self-signed Certificate';")
        $OCC saml:config:set 1 --idp-x509cert="$AUTHENTIK_CERT" 

        $OCC saml:config:set 1 --saml-attribute-mapping-displayName_mapping="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
        $OCC saml:config:set 1 --saml-attribute-mapping-email_mapping="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
        $OCC saml:config:set 1 --saml-attribute-mapping-group_mapping="http://schemas.xmlsoap.org/claims/Group"

        $OCC config:app:set user_saml general-allowed_groups --value="admin,cloud"
        $OCC group:add cloud || true
        $OCC group:adduser admin $DEFAULT_ADMIN_USERNAME
        $OCC config:app:set user_saml general-group_provisioning --value="0"
        $OCC config:app:set user_saml general-require_provisioning_groups --value="1"
        ''}
        # configure side_menu ...
        FOLDERS=$($OCC teamfolders:list --format=json)
        ${builtins.concatStringsSep "\n" (map (name: ''
          if ! echo "$FOLDERS" | grep -q '"name":"${name}"'; then
              $OCC teamfolders:create "${name}"
          fi
        '') containerCfg.extra.teamFolders or [])}
        SERVERS=$($OCC federation:list-servers --format=json)
        ${builtins.concatStringsSep "\n" (map (domain: ''
          if ! echo "$SERVERS" | grep -q "${domain}"; then
            $OCC federation:add-server "https://${domain}"
          fi
        '') containerCfg.extra.federatedServers or [])}
        $OCC config:app:set systemtags allow_user_creating --value="no"
        
      #else
      #    echo "Nextcloud is already installed. Skipping setup."
      #fi

      echo "Applying Theme..."
      $OCC config:app:set theming url --value="https://${containerCfg.subdomain}.${serverCfg.domain}"
      ${lib.optionalString (containerCfg.extra ? name) ''$OCC config:app:set theming name --value="${containerCfg.extra.name}"''}
      ${lib.optionalString (containerCfg.extra ? slogan) ''$OCC config:app:set theming slogan --value="${containerCfg.extra.slogan}"''}
      $OCC config:app:set theming background_color --value="${serverCfg.colorScheme.palette.base02}"
      $OCC config:app:set theming primary_color --value="${serverCfg.colorScheme.palette.base0C}"
      $OCC theming:config logo "${logoPngMount}"
      $OCC theming:config logoheader "${logoSvgMount}"
      $OCC theming:config favicon "${logoIcoMount}"
      $OCC theming:config background "${backgroundMount}"

      $OCC config:app:set serverinfo token --value="$HOMEPAGE_VAR_NEXTCLOUD_API"

      echo "Maintenance..."
      $OCC app:update --all
      $OCC maintenance:repair --include-expensive --no-interaction
      $OCC db:add-missing-indices --no-interaction

      echo "Completed Setup"
      '';
    };

    cron = [ "*/5 * * * *  root  ${pkgs.podman}/bin/podman --events-backend=none exec -u www-data nextcloud-server php -f /var/www/html/cron.php" ];
  };
}
