{ config, pkgs, lib, ... }:

{
  imports = [ ];

  deployment = {
    targetUser = "sefidel";
    targetHost = "alpha.bee-polaris.ts.net";
    allowLocalDeployment = true;
  };

  security = {
    rtkit.enable = true;
    doas.enable = true;
    doas.wheelNeedsPassword = false;
    sudo.wheelNeedsPassword = false;
  };

  # Use latest LTS kernel (https://github.com/NixOS/nixpkgs/pull/341596)
  boot.kernelPackages = pkgs.linuxPackages;
  boot.kernelParams = [
    # "nohibernate"
    "console=tty1"

    # Resolve ACPI conflicts for Gigabyte motherboard
    "acpi_enforce_resources=lax"
  ];
  boot.kernelModules = [ "i2c-dev" "i2c-piix4" ];

  boot.initrd.supportedFilesystems = [ "zfs" ];
  boot.supportedFilesystems = [ "zfs" ];
  boot.zfs.package = pkgs.zfs_unstable;
  boot.zfs.forceImportRoot = false;
  boot.zfs.forceImportAll = false;
  boot.zfs.allowHibernation = true; # NOTE: disable if using swap on ZFS

  boot.loader.systemd-boot = {
    # Managed by lanzaboote
    enable = false;
    editor = false;
    configurationLimit = 16;
    # TODO: https://github.com/NixOS/nixpkgs/pull/334526
    # bootCounting.enable = true;
    # bootCounting.tries = 3;
    # bootCounting.enable = true;
    # bootCounting.tries = 3;
  };

  boot.initrd.postDeviceCommands = lib.mkAfter ''
    zfs rollback -r rpool/local/root@blank
  '';

  hardware.enableRedistributableFirmware = true;

  networking.hostName = "alpha";
  networking.hostId = "8425e349";

  networking.networkmanager.enable = true;
  networking.useDHCP = false;
  networking.firewall.enable = true;

  # TODO: https://github.com/NixOS/nixpkgs/issues/180175
  systemd.services.NetworkManager-wait-online.serviceConfig.ExecStart = lib.mkForce [ "" "${pkgs.networkmanager}/bin/nm-online -q" ];

  programs.nm-applet.enable = true;
  systemd.user.services.nm-applet = {
    after = [ "graphical-session.target" ];
    serviceConfig = {
      Restart = "on-failure";
      RestartSec = "5s";
    };
  };

  i18n.defaultLocale = "en_US.UTF-8";

  console.keyMap = "us";
  console.colors = [
    "151515"
    "cf6a4c"
    "99ad6a"
    "dfa358"
    "8197bf"
    "b3a3ff"
    "8fbfdc"
    "cbc0ab"
    "333333"
    "d98870"
    "adbd88"
    "e5b579"
    "9aaccc"
    "c2b5ff"
    "a5cce3"
    "d5cdbc"
  ];

  time.timeZone = "Asia/Seoul";

  environment.systemPackages = with pkgs; [ gcc git gnumake solaar ];

  services.zfs.trim.enable = true;
  services.zfs.autoScrub.enable = true;
  services.zfs.autoScrub.pools = [ "rpool" ];

  # NOTE: `com.sun:auto-snapshot` property must be set to true on datasets you
  # wish to snapshot
  services.zfs.autoSnapshot.enable = true;
  services.zfs.autoSnapshot.flags = "-k -p --utc";

  services.openssh.enable = true;
  services.openssh.settings.PasswordAuthentication = false;

  modules = {
    secure-boot.enable = true;

    persistence = {
      enable = true;
      storagePath = "/persist";
      setupSshHostKeys = true;

      directories = [
        "/etc/NetworkManager/system-connections"
        "/var/lib/nixos"
        "/var/lib/bluetooth"
        "/var/lib/tailscale"
        "/var/lib/libvirt"
        "/etc/cups"
      ];
    };
  };

  sops.secrets.borg-alpha-rolling-pass = { };
  services.borgbackup.jobs.alpha-rolling = {
    paths = [
      "/persist"
      "/home"
    ];

    exclude = [
      # Ephemeral user files
      "**/.cache"
      "**/.nix-profile"
      "**/.config"
      # Rust build files
      "**/target"
      # Large, non-essential files
      "/home/**/sandbox"
    ];

    prune.keep = {
      within = "1d"; # Keep all archives from the last day
      daily = 7;
      weekly = 4;
      monthly = 3;
    };

    repo = "20963@hk-s020.rsync.net:rolling/alpha";
    encryption.mode = "repokey-blake2";
    encryption.passCommand = "cat ${config.sops.secrets.borg-alpha-rolling-pass.path}";

    environment.BORG_RSH = "ssh -i /persist/ssh/ssh_host_ed25519_key";
    # use borg 1.0+ on rsync.net
    environment.BORG_REMOTE_PATH = "/usr/local/bin/borg1/borg1";
    extraCreateArgs = "--verbose --stats --checkpoint-interval 600";
    compression = "auto,zstd";
    startAt = "hourly";
    persistentTimer = true;
  };

  systemd.services."borgbackup-job-alpha-rolling" = {
    preStart = lib.mkBefore ''
      # Wait until internet is reachable after resuming
      echo "Waiting until the remote is reachable..."
      until /run/current-system/sw/bin/ping rsync.net -c1 -q >/dev/null 2>&1; do :; done
      echo "Remote is reachable, exiting preStart"
    '';
  };

  services.openssh.knownHosts."hk-s020.rsync.net".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILcPl9x9JfRFwsn09NnDw/xBZbAN80ZQck+h6AqlVqPH";

  services.pipewire = {
    enable = true;

    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
  };

  hardware.bluetooth.enable = true;
  hardware.logitech.wireless.enable = true;
  hardware.opentabletdriver.enable = true;

  hardware.devkit.enable = true;

  services.hardware.openrgb.enable = true;

  services.keyd-qol.enable = true;

  services.udev.extraRules = ''
    # Logitech receiver for superlight, causes premature wakeup from suspend
    ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c547", ATTR{power/wakeup}="disabled"
  '';

  services.printing.enable = true;
  services.printing.drivers = with pkgs; [
    brgenml1lpr
    brgenml1cupswrapper
  ];
  services.avahi.enable = true;
  services.avahi.nssmdns4 = true;

  services.pcscd.enable = true;

  programs.dconf.enable = true;
  services.gnome.gnome-keyring.enable = true;

  virtualisation.libvirtd.enable = true;
  virtualisation.spiceUSBRedirection.enable = false;
  programs.virt-manager.enable = true;

  virtualisation.docker.enable = true;

  services.tailscale.enable = true;
  services.tailscale.useRoutingFeatures = "both";
  programs.trayscale.enable = true;
  systemd.user.services.trayscale = {
    after = [ "graphical-session.target" ];
    serviceConfig = {
      Restart = "on-failure";
      RestartSec = "5s";
    };
  };

  # User = networkId;
  # nameToId = netName: "nebula-${netName}";
  # sops.secrets.nebula-sefidel-internal-ca = { owner = "nebula-sefidel-internal"; };
  # sops.secrets.nebula-sefidel-internal-cert = { owner = "nebula-sefidel-internal"; };
  # sops.secrets.nebula-sefidel-internal-key = { owner = "nebula-sefidel-internal"; };

  services.nebula.networks = {
    sefidel-internal = {
      enable = false;

      ca = config.sops.secrets.nebula-sefidel-internal-ca.path;
      cert = config.sops.secrets.nebula-sefidel-internal-cert.path;
      key = config.sops.secrets.nebula-sefidel-internal-key.path;

      staticHostMap = {
        "100.64.0.1" = [ "v-coord1.sefidel.net:4242" ];
      };

      lighthouses = [ "100.64.0.1" ];
      relays = [ "100.64.0.1" ];

      firewall.inbound = [
        {
          host = "any";
          port = "any";
          proto = "any";
        }
      ];
    };
  };

  services.greetd = {
    enable = true;
    vt = 2;

    settings.default_session.command = "${pkgs.greetd.tuigreet}/bin/tuigreet -t -c sway";
  };

  services.journald.extraConfig = lib.mkForce "";

  systemd.extraConfig = "RebootWatchdogSec=5";

  fonts = {
    fontDir.enable = true;

    packages = with pkgs; [
      nerd-fonts.iosevka
      nerd-fonts.jetbrains-mono
      cozette
      dina-font
      emacs-all-the-icons-fonts
      envypn-font
      jetbrains-mono
      nanum
      sarasa-gothic
      siji
      tamzen
      twemoji-color-font
    ];

    fontconfig = {
      enable = true;

      defaultFonts = {
        serif = [
          "Sarasa Gothic C"
          "Sarasa Gothic J"
          "Sarasa Gothic K"
        ];

        sansSerif = [
          "Sarasa Gothic C"
          "Sarasa Gothic J"
          "Sarasa Gothic K"
        ];

        monospace = [
          "Dina"
          "Terminus"
          "Iosevka Nerd Font"
          "JetBrainsMono Nerd Font"
        ];

        emoji = [
          "Siji"
          "Twitter Color Emoji"
        ];
      };
    };
  };

  programs = {
    sway.enable = true;
    sway.package = null; # Managed by home-manager
    sway.extraPackages = lib.mkForce [ ];

    zsh.enable = true;
    zsh.enableCompletion = false;
  };

  programs.steam = {
    enable = true;
    remotePlay.openFirewall = true;
    dedicatedServer.openFirewall = true;
  };
  nixpkgs.allowedUnfree = [ "steam" "steam-unwrapped" "brgenml1lpr" ];

  madness.enable = true;

  environment.sessionVariables = {
    WLR_NO_HARDWARE_CURSORS = "1"; # Prevent cursors disappearing on nouveau
  };

  hardware.graphics.enable = true;
  hardware.graphics.extraPackages = with pkgs; [ vaapiVdpau libvdpau-va-gl ];

  xdg.portal = {
    enable = true;
    extraPortals = with pkgs; [
      xdg-desktop-portal-gtk
      xdg-desktop-portal-wlr
    ];
  };

  sops.defaultSopsFile = ./secrets/secrets.yaml;
  sops.secrets.root-password.neededForUsers = true;
  sops.secrets.sefidel-password.neededForUsers = true;

  users.mutableUsers = false;

  users.users = {
    root.hashedPasswordFile = config.sops.secrets.root-password.path;
    sefidel = {
      isNormalUser = true;
      shell = pkgs.zsh;
      hashedPasswordFile = config.sops.secrets.sefidel-password.path;

      extraGroups = [
        "wheel"
        "audio"
        "networkmanager"
        "plugdev"
        "libvirtd"
        "docker"
      ];
    };
  };

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It's perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "23.11"; # Did you read the comment?
}