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

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];

  # Use the systemd-boot EFI boot loader.
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;
  boot.resumeDevice = "/dev/mapper/luksroot";
  # Pin Linux kernel to 6.12
  boot.kernelPackages = pkgs.linuxPackages_6_12;

  boot.extraModprobeConfig = ''
    options mt7921_common disable_clc=1
    options atkbd reset=1 softrepeat=1
    options i8042 nomux=1 reset=1 nopnp=1 kbdreset=1 direct=1 dumbkbd=1
  '';

  # Kernel parameters for power saving
    boot.kernelParams = [
      # CRITICAL FIX: Disable ACPI for i8042 (ASUS BIOS bug workaround)
      "i8042.noacpi"                         # Disable buggy ASUS ACPI keyboard controller
      "i8042.reset=1"                        # Force reset i8042
      "i8042.nomux=1"                        # No multiplexing
      "i8042.nopnp=1"                        # Ignore PnP detection
      "atkbd.softrepeat=1"                   # Software key repeat
      "amd_pstate=active"                    # Use AMD P-State driver for better power management
      "amd_pstate.shared_mem=1"
      "pcie_aspm.policy=powersupersave"      # Aggressive PCIe power management
      "amdgpu.gpu_recovery=1"                # Enable automatic GPU recovery
      #"amdgpu.runpm=0"                      # Disable runtime PM (major hang cause)
      ###"amdgpu.dcdebugmask=0x400" 
      #"amdgpu.dcdebugmask=0x10"             # Disable PSR (panel self-refresh)
    #"amdgpu.ppfeaturemask=0xf7fff"        # Disable GFXOFF
  ]; 

  # Disable TPM
  systemd.tpm2.enable = false;
  boot.initrd.systemd.tpm2.enable = false;

  #swapDevices = [{ file = "/swap/swapfile"; }];

  # Override btrfs mount options from hardware-configuration.nix
  fileSystems."/" = {
    options = [ "subvol=@" "compress=zstd" "space_cache=v2" "noatime"
  "autodefrag" "ssd" "discard=async" ];
  };

  fileSystems."/home" = {
    options = [ "subvol=@home" "compress=zstd" "space_cache=v2" "noatime"
   "autodefrag" "ssd" "discard=async" ];
  };

  fileSystems."/var/log" = {
    options = [ "subvol=@log" "compress=zstd" "space_cache=v2" "noatime"
  "autodefrag" "ssd" "discard=async" ];
  };

  fileSystems."/swap" = {
    options = [ "subvol=@swap" "noatime" "ssd" "discard=async" ];
  };

  # Enable NetworkManager and set network host name
  networking.networkmanager.enable = true;
  networking.hostName = "lusia-laptop";

  # NetworkManager power saving for WiFi
  networking.networkmanager.wifi.powersave = true;

  # Enable Tailscale
  services.tailscale.enable = true;

  # Trust the Tailscale interface
  networking.firewall.trustedInterfaces = [ "tailscale0" ];

  # Disable reverse path filtering for Tailscale                                                                                                 ╎│
  boot.kernel.sysctl."net.ipv4.conf.tailscale0.rp_filter" = 0; 

  # Enable resolved
  services.resolved.enable = true;

  # OpenVPN services
  # VSTech VPN (with DNS for bgs.local domain)
  services.openvpn.servers.vstech = {
    config = ''
      client
      remote 51.83.143.81
      proto udp
      port 649
      dev tun
      topology subnet
      ca /home/lusia/VSTech-vpn/ca.crt
      cert /home/lusia/VSTech-vpn/Klient251.crt
      key /home/lusia/VSTech-vpn/Klient251.key
      tls-crypt /home/lusia/VSTech-vpn/ta.key

      auth sha512
      data-ciphers aes-256-cbc
      data-ciphers-fallback aes-256-cbc
      key-direction 1
      keepalive 10 120
    '';
    updateResolvConf = false;

    # Manually set DNS after connection
    up = ''
      ${pkgs.systemd}/bin/resolvectl dns $dev 10.10.10.1
      ${pkgs.systemd}/bin/resolvectl domain $dev bgs.local
    '';

    down = ''
      ${pkgs.systemd}/bin/resolvectl revert $dev
    '';
  }; 

  # CAT VPN
  services.openvpn.servers.cat = {
    config = ''
      client
      remote 79.133.193.211
      proto tcp
      port 1194
      dev tun
      topology subnet
      ca /home/lusia/vpn/ca.crt
      cert /home/lusia/vpn/client18.crt
      key /home/lusia/vpn/client18.key

      auth sha256
      data-ciphers AES-256-CBC
      key-direction 1
    '';
    updateResolvConf = true;
  };

  # Enable upower service
  services.upower.enable = true;

  # Set your time zone.
  time.timeZone = "Europe/Warsaw";

  # Select internationalisation properties.
  i18n.defaultLocale = "en_US.UTF-8";
  console = {
    keyMap = "pl";
  };

  # Enable niri
  # programs.niri.enable = true;

  # Enable fish
  programs.fish.enable = true;

  # Enable greetd with tuigreet
  services.greetd = {
    enable = true;
    settings = {
      default_session = {
        command = "${pkgs.tuigreet}/bin/tuigreet --time --cmd niri-session";
        user = "greeter";
      };
    };
  };

  # Essential for niri
  security.polkit.enable = true;
  services.gnome.gnome-keyring.enable = true;

  # XDG Portal for file pickers or screen sharing
  xdg.portal = {
    enable = true;
    extraPortals = [ pkgs.xdg-desktop-portal-gtk
                     pkgs.xdg-desktop-portal-gnome ];
    config = {
      common = {
        default = [ "gtk" ];
        "org.freedesktop.impl.portal.ScreenCast" = [ "gnome" ];
        "org.freedesktop.impl.portal.Screenshot" = [ "gnome" ];
      };
    };
  };

  # Enable dconf
  programs.dconf.enable = true;

  users.groups.plugdev = {};

  users.users.lusia = {
    isNormalUser = true;
    description = "Lukrecja";
    extraGroups = [ "wheel" "networkmanager" "docker" "plugdev" "scanner" "lp" ];
    initialPassword = "pass";
    shell = pkgs.fish;
  };

  # Import udev rules for probe-rs
  services.udev.packages = [
    (pkgs.writeTextFile {
      name = "probe-rs-udev-rules";
      destination = "/etc/udev/rules.d/69-probe-rs.rules";
      text = builtins.readFile ./udev-rules/69-probe-rs.rules;
    })
  ];

  hardware.enableAllFirmware = true;
  services.openssh.enable = true;
  security.sudo.enable = true;

  # Enable xwayland
  programs.xwayland.enable = true;

  # Set a session variable for icon theme
  environment.sessionVariables = rec {
    QT_QPA_PLATFORMTHEME = "qt5ct";
  };

  environment.systemPackages = with pkgs; [
    git
    curl
    wget
    vim
    fish
    kitty
    #asusctl
    powertop  # For monitoring power consumption
    openvpn
    nodejs
    gnumake
    gcc
    cmake
    xwayland-satellite
    busybox
    libdecor
    file
    cifs-utils
    samba
    gvfs
  ];

  # Fonts
  fonts.packages = with pkgs; [
    noto-fonts
    noto-fonts-cjk-sans
    noto-fonts-color-emoji
    pkgs.nerd-fonts.fira-code
  ];

  # For SMB shares
  services.gvfs.enable = true;

  # Printers
  services.avahi = {
    enable = true;
    nssmdns4 = true;
    openFirewall = true;
  };

  services.printing = {
    enable = true;
    drivers = with pkgs; [
      cups-filters
      cups-browsed
    ];
  };

  # Enable Flatpaks
  services.flatpak.enable = true;

  # Enable Docker
  virtualisation.docker.enable = true;
  virtualisation.docker.storageDriver = "btrfs";

  nixpkgs.config.allowUnfree = true;
  nix.settings.experimental-features = [ "nix-command" "flakes" ];

  # Enable Bluetooth (but it will be blocked by default to save power)
  hardware.bluetooth.enable = true;
  hardware.bluetooth.powerOnBoot = false;  # Don't power on bluetooth at boot

  hardware.sane.enable = true;

  # Configure epsonds for network scanning
  environment.etc."sane.d/epsonds.conf".text = ''
    net EPSOND80395.local
  '';
 
  # Enable OpenTabletDriver
  hardware.opentabletdriver.enable = true;
  hardware.uinput.enable = true;
  boot.kernelModules = [ "uinput" ];

  # Enable PPD for power options
  services.power-profiles-daemon.enable = true;

  # Enable AMD GPU graphics acceleration
  hardware.graphics = {
    enable = true;
    enable32Bit = true;  # For 32-bit applications/games
  };

  # Open ports in the firewall.
  # networking.firewall.allowedTCPPorts = [ ... ];
  # networking.firewall.allowedUDPPorts = [ ... ];
  # Or disable the firewall altogether.
  # networking.firewall.enable = false;

  # Copy the NixOS configuration file and link it from the resulting system
  # (/run/current-system/configuration.nix). This is useful in case you
  # accidentally delete configuration.nix.
  # system.copySystemConfiguration = true;

  # This option defines the first version of NixOS you have installed on this particular machine,
  # and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
  #
  # Most users should NEVER change this value after the initial install, for any reason,
  # even if you've upgraded your system to a new NixOS release.
  #
  # This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
  # so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
  # to actually do that.
  #
  # This value being lower than the current NixOS release does NOT mean your system is
  # out of date, out of support, or vulnerable.
  #
  # Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
  # and migrated your data accordingly.
  #
  # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
  system.stateVersion = "24.11"; # Did you read the comment?

}
