{ pkgs, config, ... }:
let
  enableDisplayManager = false;
in
{
  imports = [ ./nix-serve.nix ];

  # Services configs
  services = {

    code-server = {
      enable = true;
      disableTelemetry = true;
      disableUpdateCheck = true;
      user = "admin";
      group = "jallen-nas";
      host = "0.0.0.0";
      port = 4444;
      auth = "none";
      hashedPassword = "$y$j9T$EkPXmsmIMFFZ.WRrBYCxS1$P0kwo6e4.WM5DsqUcEqWC3MrZp5KfCjxffraMFZWu06";
      extraEnvironment = {
        PROXY_DOMAIN = "code.mjallen.dev";
      };
    };

    minecraft-server = {
      enable = false;
      eula = true;
      declarative = true;
      openFirewall = true;
      dataDir = "/media/nas/ssd/ssd_app_data/minecraft";
      serverProperties = {
        enforce-whitelist = true;
        white-list = true;
        "enable-rcon" = true;
        "rcon.password" = config.sops.secrets."jallen-nas/admin_password".path;
      };
      whitelist = {
        mjallen18 = "03d9fba9-4453-4ad1-afa6-c67738685189";
        AlpineScent = "76ff084d-2e66-4877-aec2-d6b278431bda";
        Fortltude = "61a01913-8b10-4d64-b7ce-7958088cd6d3";
        SpicyNick = "8bb5976f-6fd9-4fa5-8697-6ecb4ee38427";
      };
      jvmOpts = "-Xms4092M -Xmx4092M -XX:+UseG1GC -XX:ParallelGCThreads=2 -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10";
    };

    udisks2.enable = true;

    # Enable the Desktop Environment.
    desktopManager.plasma6.enable = enableDisplayManager;
    displayManager = {
      sddm.enable = enableDisplayManager;
      defaultSession = "plasma";
    };

    gnome.gnome-keyring.enable = true;

    # Enable RDP
    xrdp = {
      enable = true;
      openFirewall = true;
    };

    avahi = {
      enable = true;
      nssmdns4 = true;
      publish = {
        enable = true;
        addresses = true;
        domain = true;
        hinfo = true;
        userServices = true;
        workstation = true;
      };
      extraServiceFiles = {
        # TODO is this needed?
        smb = ''
          <?xml version="1.0" standalone='no'?><!--*-nxml-*-->
          <!DOCTYPE service-group SYSTEM "avahi-service.dtd">
          <service-group>
            <name replace-wildcards="yes">%h</name>
            <service>
              <type>_smb._tcp</type>
              <port>445</port>
            </service>
          </service-group>
        '';
      };
    };

    tailscale = {
      enable = true;
      openFirewall = true;
      useRoutingFeatures = "client";
      extraUpFlags = [
        "--advertise-exit-node"
        "--accept-dns=false"
        "--advertise-routes=10.0.1.0/24"
        "--hostname=jallen-nas"
      ];
      extraSetFlags = [
        "--advertise-exit-node"
        "--hostname=jallen-nas"
        "--webclient"
      ];
      # authKeyFile = "/media/nas/ssd/nix-app-data/tailscale/auth";
    };

    btrfs = {
      autoScrub.enable = false;
      autoScrub.fileSystems = [
        "/nix"
        "/root"
        "/etc"
        "/var/log"
        "/home"
        "/media/nas/ssd/nix-app-data"
        "/media/nas/ssd/ssd_app_data"
        "/media/nas/ssd/mariadb"
        "/media/nas/main/3d_printer"
        "/media/nas/main/backup"
        "/media/nas/main/documents"
        "/media/nas/main/nextcloud"
        "/media/nas/main/movies"
        "/media/nas/main/tv"
        "/media/nas/main/isos"
      ];
    };

    authentik = {
      enable = true;
      environmentFile = config.sops.secrets."jallen-nas/authentik-env".path;
    };

    # nixai = {
    #   enable = true;
    #   mcp = {
    #     enable = true;
    #     # Optional: custom socket path
    #     socketPath = "/run/nixai/mcp.sock";
    #   };
    # };

    postgresql = {
      enable = true;
      package = pkgs.postgresql_16;
      dataDir = "/media/nas/ssd/nix-app-data/postgresql";
      ensureDatabases = [ "authentik" ];
      ensureUsers = [
        {
          name = "authentik";
          ensureDBOwnership = true;
        }
      ];
    };

    redis = {
      servers = {
        authentik = {
          enable = true;
          port = 6379;
        };

        manyfold = {
          enable = true;
          port = 6380;
        };
      };
    };

    restic.server = {
      enable = true;
      dataDir = "/media/nas/main/backup/restic";
      prometheus = true;
      listenAddress = "0.0.0.0:8008";
      htpasswd-file = "/media/nas/main/backup/restic/.htpasswd";
    };
  };
  
  systemd.user.services = {
    protonmail-bridge = {
      description = "Protonmail Bridge";
      enable = true;
      environment = {
        GNUPGHOME = "%h/.gnupg";
        PASSWORD_STORE_DIR = "%h/.password-store";
      };
      script = "${pkgs.protonmail-bridge}/bin/protonmail-bridge --noninteractive";
      path = [
        pkgs.gnome-keyring
        pkgs.gnupg
        pkgs.pass
        pkgs.protonmail-bridge
      ];
      wantedBy = [ "default.target" ];
      after = [ "gpg-agent.service" ];
    };
  };

  # TODO move to normal samba settings
  services.samba.settings.global = {
    "workgroup" = "WORKGROUP";
    "server string" = "Jallen-NAS";
    "netbios name" = "Jallen-NAS";
    "security" = "user";
    #"use sendfile" = "yes";
    #"max protocol" = "smb2";
    # note: localhost is the ipv6 localhost ::1
    "hosts allow" = "10.0.1. 127.0.0.1 localhost";
    "hosts deny" = "0.0.0.0/0";
    "guest account" = "nobody";
    "map to guest" = "bad user";
  };

  systemd.services = {
    btrfs-balance = {
      description = "BTRFS Balance Service";
      # This ensures the service only runs when the filesystem is mounted
      requires = [ "local-fs.target" ];
      after = [ "local-fs.target" ];
      
      # The actual balance command
      script = ''
        # Start with lower usage to handle the most fragmented blocks first
        ${pkgs.btrfs-progs}/bin/btrfs balance start -dusage=5 -musage=5 /mount/point
        ${pkgs.btrfs-progs}/bin/btrfs balance start -dusage=10 -musage=10 /mount/point
        ${pkgs.btrfs-progs}/bin/btrfs balance start -dusage=20 -musage=20 /mount/point
      '';

      serviceConfig = {
        Type = "oneshot";
        Nice = 19;  # Lowest CPU priority
        IOSchedulingClass = "idle";  # Lowest I/O priority
        # Prevent multiple instances from running simultaneously
        ExecStartPre = "${pkgs.coreutils}/bin/rm -f /var/run/btrfs-balance.stamp";
        ExecStopPost = "${pkgs.coreutils}/bin/touch /var/run/btrfs-balance.stamp";
      };
    };
    
    system-update-check = {
      description = "Check for system configuration updates";

      # Required packages for the service
      path = with pkgs; [
        git
        nixos-rebuild
        openssh
      ];

      # Service configuration
      serviceConfig = {
        Type = "oneshot";
        User = "root";
        WorkingDirectory = "/etc/nixos"; # Adjust this path to your config location
      };

      # The script that runs to check for updates
      script = ''
        # Store the current commit hash
        OLD_HASH=$(git rev-parse HEAD)

        # Fetch updates from remote
        git fetch origin main  # Adjust branch name if needed

        # Get the new commit hash
        NEW_HASH=$(git rev-parse origin/main)

        # If there are changes, pull and rebuild
        if [ "$OLD_HASH" != "$NEW_HASH" ]; then
          echo "Updates found, pulling changes..."
          git pull origin main

          # Get commit message and timestamp for the tag
          COMMIT_MSG=$(git log -1 --pretty=%B | head -n1 | tr -dc '[:alnum:][:space:]-' | tr '[:space:]' '-')
          TIMESTAMP=$(date +%Y%m%d-%H%M)
          SHORT_HASH=$(git rev-parse --short HEAD)
          
          # Create a profile name using the timestamp, short hash, and commit message
          PROFILE_NAME="$TIMESTAMP-$SHORT_HASH-$COMMIT_MSG"
          
          # Rebuild the system
          nixos-rebuild boot --profile-name "$PROFILE_NAME"

          echo "System rebuilt with profile: $PROFILE_NAME"
        else
          echo "No updates found"
        fi
      '';
    };

    rsync-ssd = {
      path = [
        pkgs.bash
        pkgs.rsync
      ];
      script = ''
        rsync -rtpogvPlHzs --ignore-existing /media/nas/ssd /media/nas/main/backup/ssd
      '';
    };

    glances-server = {
      path = [
        pkgs.bash
        pkgs.glances
      ];
      script = ''
        glances -w
      '';
      wantedBy = [ "multi-user.target" ];
    };
  };

  security.pam.services.login.enableGnomeKeyring = true;
  # Configure gpg-agent to cache keys
  programs.gnupg.agent = {
    enable = true;
    enableSSHSupport = true;
    # Set how long to cache the passphrase (in seconds)
    # defaultCacheTtl = 34560;
    # maxCacheTtl = 34560;
  };

  # Create a timer to run the service periodically
  systemd.timers = {
    btrfs-balance = {
      description = "Timer for BTRFS Balance Service";
      wantedBy = [ "timers.target" ];
      
      timerConfig = {
        # Run weekly on Sunday at 2am
        OnCalendar = "Sun *-*-* 02:00:00";
        # Add randomized delay to prevent multiple systems from starting at exactly the same time
        RandomizedDelaySec = "1h";
        # Ensure we don't start multiple times if the system was off
        Persistent = true;
      };
    };
    system-update-check = {
      description = "Timer for system configuration updates";
      wantedBy = [ "timers.target" ];
      
      # Timer configuration
      timerConfig = {
        OnCalendar = "daily";  # Check every day
        Persistent = true;      # Run immediately if last run was missed
        Unit = "system-update-check.service";
      };
    };
  };
}
